import {
  customElement,
  DeesElement,
  type TemplateResult,
  html,
  property,
  css,
  cssManager,
  state,
} from '@design.estate/dees-element';
import { DeesAppuiSecondarymenu, DeesIcon } from '@design.estate/dees-catalog';
import type { ISecondaryMenuGroup } from '../../elements/interfaces/secondarymenu.js';
import { demo } from './eco-view-scan.demo.js';

// Ensure components are registered
DeesAppuiSecondarymenu;
DeesIcon;

declare global {
  interface HTMLElementTagNameMap {
    'eco-view-scan': EcoViewScan;
  }
}

// Types
export type TScanFormat = 'pdf' | 'jpeg' | 'png' | 'tiff';
export type TScanColorMode = 'color' | 'grayscale' | 'blackwhite';
export type TScanSource = 'flatbed' | 'adf' | 'adf-duplex';
export type TScanPanel = 'scan' | 'history' | 'settings';

export interface IScanSettings {
  format: TScanFormat;
  resolution: number;
  colorMode: TScanColorMode;
  source: TScanSource;
}

export interface IScannedDocument {
  id: string;
  timestamp: Date;
  format: TScanFormat;
  data: string; // base64
  thumbnail?: string;
  size: number;
  name?: string;
}

export interface IScannerInfo {
  id: string;
  name: string;
  address: string;
  status: 'online' | 'offline' | 'busy' | 'error';
  capabilities?: {
    resolutions: number[];
    formats: TScanFormat[];
    colorModes: TScanColorMode[];
    sources: TScanSource[];
  };
}

export interface IDataProviderInfo {
  id: string;
  name: string;
  icon?: string;
}

@customElement('eco-view-scan')
export class EcoViewScan extends DeesElement {
  public static demo = demo;
  public static demoGroup = 'Views';

  public static styles = [
    cssManager.defaultStyles,
    css`
      :host {
        display: block;
        width: 100%;
        height: 100%;
        background: ${cssManager.bdTheme('#f5f5f7', 'hsl(240 6% 10%)')};
        color: ${cssManager.bdTheme('hsl(0 0% 10%)', 'hsl(0 0% 98%)')};
        font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
      }

      .scan-container {
        display: flex;
        height: 100%;
      }

      dees-appui-secondarymenu {
        flex-shrink: 0;
        background: ${cssManager.bdTheme('#ffffff', 'hsl(240 6% 8%)')};
        border-right: 1px solid ${cssManager.bdTheme('hsl(0 0% 90%)', 'hsl(240 5% 15%)')};
      }

      .content {
        flex: 1;
        overflow-y: auto;
        padding: 32px 48px;
        display: flex;
        flex-direction: column;
      }

      .panel-header {
        margin-bottom: 24px;
        display: flex;
        align-items: center;
        justify-content: space-between;
      }

      .panel-header-left {
        display: flex;
        flex-direction: column;
        gap: 4px;
      }

      .panel-title {
        font-size: 28px;
        font-weight: 600;
        color: ${cssManager.bdTheme('hsl(0 0% 10%)', 'hsl(0 0% 98%)')};
      }

      .panel-description {
        font-size: 14px;
        color: ${cssManager.bdTheme('hsl(0 0% 50%)', 'hsl(0 0% 60%)')};
      }

      .scanner-selector {
        display: flex;
        align-items: center;
        gap: 12px;
        margin-bottom: 24px;
      }

      .scanner-selector label {
        font-size: 14px;
        font-weight: 500;
        color: ${cssManager.bdTheme('hsl(0 0% 40%)', 'hsl(0 0% 70%)')};
      }

      .scanner-selector select {
        flex: 1;
        max-width: 300px;
        padding: 10px 14px;
        font-size: 14px;
        border: 1px solid ${cssManager.bdTheme('hsl(0 0% 85%)', 'hsl(240 5% 25%)')};
        border-radius: 8px;
        background: ${cssManager.bdTheme('#ffffff', 'hsl(240 6% 15%)')};
        color: ${cssManager.bdTheme('hsl(0 0% 10%)', 'hsl(0 0% 95%)')};
        cursor: pointer;
      }

      .scanner-selector select:focus {
        outline: none;
        border-color: hsl(217 91% 60%);
      }

      .preview-area {
        flex: 1;
        min-height: 300px;
        background: ${cssManager.bdTheme('#ffffff', 'hsl(240 6% 12%)')};
        border: 2px dashed ${cssManager.bdTheme('hsl(0 0% 85%)', 'hsl(240 5% 25%)')};
        border-radius: 12px;
        display: flex;
        align-items: center;
        justify-content: center;
        overflow: hidden;
        margin-bottom: 24px;
      }

      .preview-area.has-image {
        border-style: solid;
      }

      .preview-placeholder {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 12px;
        color: ${cssManager.bdTheme('hsl(0 0% 60%)', 'hsl(0 0% 50%)')};
      }

      .preview-placeholder dees-icon {
        opacity: 0.5;
      }

      .preview-image {
        max-width: 100%;
        max-height: 100%;
        object-fit: contain;
      }

      .action-bar {
        display: flex;
        gap: 12px;
        margin-bottom: 32px;
      }

      .action-button {
        display: flex;
        align-items: center;
        gap: 8px;
        padding: 12px 24px;
        font-size: 14px;
        font-weight: 500;
        border: none;
        border-radius: 8px;
        cursor: pointer;
        transition: all 0.15s ease;
      }

      .action-button.primary {
        background: hsl(217 91% 60%);
        color: white;
      }

      .action-button.primary:hover:not(:disabled) {
        background: hsl(217 91% 55%);
      }

      .action-button.secondary {
        background: ${cssManager.bdTheme('hsl(0 0% 95%)', 'hsl(240 5% 20%)')};
        color: ${cssManager.bdTheme('hsl(0 0% 30%)', 'hsl(0 0% 90%)')};
      }

      .action-button.secondary:hover:not(:disabled) {
        background: ${cssManager.bdTheme('hsl(0 0% 90%)', 'hsl(240 5% 25%)')};
      }

      .action-button:disabled {
        opacity: 0.5;
        cursor: not-allowed;
      }

      .action-button.scanning dees-icon {
        animation: spin 1s linear infinite;
      }

      @keyframes spin {
        from { transform: rotate(0deg); }
        to { transform: rotate(360deg); }
      }

      .dropdown-container {
        position: relative;
      }

      .dropdown-menu {
        position: absolute;
        bottom: 100%;
        left: 0;
        margin-bottom: 4px;
        background: ${cssManager.bdTheme('#ffffff', 'hsl(240 6% 15%)')};
        border: 1px solid ${cssManager.bdTheme('hsl(0 0% 90%)', 'hsl(240 5% 25%)')};
        border-radius: 8px;
        box-shadow: 0 4px 16px ${cssManager.bdTheme('rgba(0,0,0,0.1)', 'rgba(0,0,0,0.3)')};
        min-width: 200px;
        z-index: 100;
        overflow: hidden;
      }

      .dropdown-item {
        display: flex;
        align-items: center;
        gap: 10px;
        padding: 10px 14px;
        font-size: 14px;
        color: ${cssManager.bdTheme('hsl(0 0% 20%)', 'hsl(0 0% 90%)')};
        cursor: pointer;
        transition: background 0.1s ease;
      }

      .dropdown-item:hover {
        background: ${cssManager.bdTheme('hsl(0 0% 95%)', 'hsl(240 5% 20%)')};
      }

      .dropdown-item dees-icon {
        opacity: 0.7;
      }

      .settings-section {
        background: ${cssManager.bdTheme('#ffffff', 'hsl(240 6% 12%)')};
        border: 1px solid ${cssManager.bdTheme('hsl(0 0% 90%)', 'hsl(240 5% 18%)')};
        border-radius: 12px;
        padding: 20px;
        margin-bottom: 20px;
      }

      .settings-section-title {
        font-size: 16px;
        font-weight: 600;
        margin-bottom: 16px;
        color: ${cssManager.bdTheme('hsl(0 0% 20%)', 'hsl(0 0% 90%)')};
      }

      .setting-row {
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 12px 0;
        border-bottom: 1px solid ${cssManager.bdTheme('hsl(0 0% 92%)', 'hsl(240 5% 18%)')};
      }

      .setting-row:last-child {
        border-bottom: none;
      }

      .setting-label {
        font-size: 14px;
        color: ${cssManager.bdTheme('hsl(0 0% 30%)', 'hsl(0 0% 80%)')};
      }

      .setting-control select {
        padding: 8px 12px;
        font-size: 14px;
        border: 1px solid ${cssManager.bdTheme('hsl(0 0% 85%)', 'hsl(240 5% 25%)')};
        border-radius: 6px;
        background: ${cssManager.bdTheme('#ffffff', 'hsl(240 6% 15%)')};
        color: ${cssManager.bdTheme('hsl(0 0% 10%)', 'hsl(0 0% 95%)')};
        cursor: pointer;
      }

      .history-grid {
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
        gap: 16px;
      }

      .history-item {
        background: ${cssManager.bdTheme('#ffffff', 'hsl(240 6% 12%)')};
        border: 1px solid ${cssManager.bdTheme('hsl(0 0% 90%)', 'hsl(240 5% 18%)')};
        border-radius: 8px;
        overflow: hidden;
        cursor: pointer;
        transition: all 0.15s ease;
      }

      .history-item:hover {
        border-color: hsl(217 91% 60%);
        transform: translateY(-2px);
        box-shadow: 0 4px 12px ${cssManager.bdTheme('rgba(0,0,0,0.1)', 'rgba(0,0,0,0.3)')};
      }

      .history-thumbnail {
        width: 100%;
        aspect-ratio: 1;
        background: ${cssManager.bdTheme('hsl(0 0% 95%)', 'hsl(240 5% 18%)')};
        display: flex;
        align-items: center;
        justify-content: center;
      }

      .history-thumbnail img {
        width: 100%;
        height: 100%;
        object-fit: cover;
      }

      .history-info {
        padding: 10px;
      }

      .history-name {
        font-size: 13px;
        font-weight: 500;
        color: ${cssManager.bdTheme('hsl(0 0% 20%)', 'hsl(0 0% 90%)')};
        margin-bottom: 4px;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
      }

      .history-date {
        font-size: 12px;
        color: ${cssManager.bdTheme('hsl(0 0% 50%)', 'hsl(0 0% 60%)')};
      }

      .empty-state {
        text-align: center;
        padding: 60px 20px;
        color: ${cssManager.bdTheme('hsl(0 0% 50%)', 'hsl(0 0% 60%)')};
      }

      .empty-state dees-icon {
        margin-bottom: 16px;
        opacity: 0.4;
      }

      .empty-state p {
        font-size: 14px;
        margin: 0;
      }
    `,
  ];

  @property({ type: Array })
  accessor scanners: IScannerInfo[] = [];

  @property({ type: Array })
  accessor providers: IDataProviderInfo[] = [];

  @state()
  accessor activePanel: TScanPanel = 'scan';

  @state()
  accessor selectedScannerId: string | null = null;

  @state()
  accessor isScanning = false;

  @state()
  accessor currentPreview: string | null = null;

  @state()
  accessor currentDocument: IScannedDocument | null = null;

  @state()
  accessor scanHistory: IScannedDocument[] = [];

  @state()
  accessor settings: IScanSettings = {
    format: 'pdf',
    resolution: 300,
    colorMode: 'color',
    source: 'flatbed',
  };

  @state()
  accessor showSendToMenu = false;

  private get selectedScanner(): IScannerInfo | null {
    return this.scanners.find(s => s.id === this.selectedScannerId) || null;
  }

  private get availableResolutions(): number[] {
    return this.selectedScanner?.capabilities?.resolutions || [150, 300, 600];
  }

  private get availableFormats(): TScanFormat[] {
    return this.selectedScanner?.capabilities?.formats || ['pdf', 'jpeg', 'png'];
  }

  private get availableColorModes(): TScanColorMode[] {
    return this.selectedScanner?.capabilities?.colorModes || ['color', 'grayscale'];
  }

  private get availableSources(): TScanSource[] {
    return this.selectedScanner?.capabilities?.sources || ['flatbed'];
  }

  public render(): TemplateResult {
    return html`
      <div class="scan-container">
        <dees-appui-secondarymenu
          .menuGroups=${this.getMenuGroups()}
          .selectedKey=${this.activePanel}
        ></dees-appui-secondarymenu>
        <div class="content">
          ${this.renderContent()}
        </div>
      </div>
    `;
  }

  private getMenuGroups(): ISecondaryMenuGroup[] {
    return [
      {
        name: 'SCAN',
        iconName: 'lucide:scan',
        items: [
          {
            key: 'scan',
            label: 'New Scan',
            iconName: 'lucide:plus',
            action: () => this.activePanel = 'scan',
          },
        ],
      },
      {
        name: 'HISTORY',
        iconName: 'lucide:history',
        items: [
          {
            key: 'history',
            label: 'Recent Scans',
            iconName: 'lucide:clock',
            action: () => this.activePanel = 'history',
            badge: this.scanHistory.length > 0 ? this.scanHistory.length : undefined,
          },
        ],
      },
      {
        name: 'OPTIONS',
        iconName: 'lucide:settings',
        items: [
          {
            key: 'settings',
            label: 'Scan Settings',
            iconName: 'lucide:sliders',
            action: () => this.activePanel = 'settings',
          },
        ],
      },
    ];
  }

  private renderContent(): TemplateResult {
    switch (this.activePanel) {
      case 'scan':
        return this.renderScanPanel();
      case 'history':
        return this.renderHistoryPanel();
      case 'settings':
        return this.renderSettingsPanel();
      default:
        return this.renderScanPanel();
    }
  }

  private renderScanPanel(): TemplateResult {
    return html`
      <div class="panel-header">
        <div class="panel-header-left">
          <h2 class="panel-title">Scan Document</h2>
          <p class="panel-description">Select a scanner and start scanning</p>
        </div>
      </div>

      <div class="scanner-selector">
        <label>Scanner:</label>
        <select
          .value=${this.selectedScannerId || ''}
          @change=${(e: Event) => this.handleScannerChange(e)}
        >
          <option value="">Select a scanner...</option>
          ${this.scanners.map(scanner => html`
            <option value=${scanner.id} ?selected=${scanner.id === this.selectedScannerId}>
              ${scanner.name} ${scanner.status !== 'online' ? `(${scanner.status})` : ''}
            </option>
          `)}
        </select>
      </div>

      <div class="preview-area ${this.currentPreview ? 'has-image' : ''}">
        ${this.currentPreview
          ? html`<img class="preview-image" src=${this.currentPreview} alt="Scan preview" />`
          : html`
            <div class="preview-placeholder">
              <dees-icon .icon=${'lucide:scan'} .iconSize=${48}></dees-icon>
              <span>Scan preview will appear here</span>
            </div>
          `
        }
      </div>

      <div class="action-bar">
        <button
          class="action-button primary ${this.isScanning ? 'scanning' : ''}"
          ?disabled=${!this.selectedScannerId || this.isScanning}
          @click=${this.handleScan}
        >
          <dees-icon .icon=${this.isScanning ? 'lucide:loader' : 'lucide:scan'} .iconSize=${18}></dees-icon>
          ${this.isScanning ? 'Scanning...' : 'Scan'}
        </button>

        <div class="dropdown-container">
          <button
            class="action-button secondary"
            ?disabled=${!this.currentDocument}
            @click=${() => this.showSendToMenu = !this.showSendToMenu}
          >
            <dees-icon .icon=${'lucide:send'} .iconSize=${18}></dees-icon>
            Send To
            <dees-icon .icon=${'lucide:chevronUp'} .iconSize=${14}></dees-icon>
          </button>
          ${this.showSendToMenu ? this.renderSendToMenu() : ''}
        </div>

        <button
          class="action-button secondary"
          ?disabled=${!this.currentDocument}
          @click=${this.handleSaveLocal}
        >
          <dees-icon .icon=${'lucide:download'} .iconSize=${18}></dees-icon>
          Save
        </button>
      </div>
    `;
  }

  private renderSendToMenu(): TemplateResult {
    return html`
      <div class="dropdown-menu" @mouseleave=${() => this.showSendToMenu = false}>
        ${this.providers.length > 0
          ? this.providers.map(provider => html`
              <div class="dropdown-item" @click=${() => this.handleSendToProvider(provider.id)}>
                <dees-icon .icon=${provider.icon || 'lucide:cloud'} .iconSize=${18}></dees-icon>
                ${provider.name}
              </div>
            `)
          : html`
              <div class="dropdown-item" style="opacity: 0.5; cursor: default;">
                <dees-icon .icon=${'lucide:info'} .iconSize=${18}></dees-icon>
                No providers configured
              </div>
            `
        }
      </div>
    `;
  }

  private renderHistoryPanel(): TemplateResult {
    return html`
      <div class="panel-header">
        <div class="panel-header-left">
          <h2 class="panel-title">Recent Scans</h2>
          <p class="panel-description">View and manage your scanned documents</p>
        </div>
      </div>

      ${this.scanHistory.length > 0
        ? html`
          <div class="history-grid">
            ${this.scanHistory.map(doc => html`
              <div class="history-item" @click=${() => this.handleHistoryItemClick(doc)}>
                <div class="history-thumbnail">
                  ${doc.thumbnail
                    ? html`<img src=${doc.thumbnail} alt=${doc.name || 'Scan'} />`
                    : html`<dees-icon .icon=${'lucide:file'} .iconSize=${32}></dees-icon>`
                  }
                </div>
                <div class="history-info">
                  <div class="history-name">${doc.name || `Scan ${doc.id.slice(0, 8)}`}</div>
                  <div class="history-date">${this.formatDate(doc.timestamp)}</div>
                </div>
              </div>
            `)}
          </div>
        `
        : html`
          <div class="empty-state">
            <dees-icon .icon=${'lucide:inbox'} .iconSize=${48}></dees-icon>
            <p>No scans yet. Start scanning to see your documents here.</p>
          </div>
        `
      }
    `;
  }

  private renderSettingsPanel(): TemplateResult {
    return html`
      <div class="panel-header">
        <div class="panel-header-left">
          <h2 class="panel-title">Scan Settings</h2>
          <p class="panel-description">Configure default scan options</p>
        </div>
      </div>

      <div class="settings-section">
        <div class="settings-section-title">Output Settings</div>

        <div class="setting-row">
          <span class="setting-label">Format</span>
          <div class="setting-control">
            <select
              .value=${this.settings.format}
              @change=${(e: Event) => this.updateSetting('format', (e.target as HTMLSelectElement).value as TScanFormat)}
            >
              ${this.availableFormats.map(fmt => html`
                <option value=${fmt} ?selected=${fmt === this.settings.format}>
                  ${fmt.toUpperCase()}
                </option>
              `)}
            </select>
          </div>
        </div>

        <div class="setting-row">
          <span class="setting-label">Resolution (DPI)</span>
          <div class="setting-control">
            <select
              .value=${String(this.settings.resolution)}
              @change=${(e: Event) => this.updateSetting('resolution', parseInt((e.target as HTMLSelectElement).value))}
            >
              ${this.availableResolutions.map(res => html`
                <option value=${res} ?selected=${res === this.settings.resolution}>
                  ${res} DPI
                </option>
              `)}
            </select>
          </div>
        </div>

        <div class="setting-row">
          <span class="setting-label">Color Mode</span>
          <div class="setting-control">
            <select
              .value=${this.settings.colorMode}
              @change=${(e: Event) => this.updateSetting('colorMode', (e.target as HTMLSelectElement).value as TScanColorMode)}
            >
              ${this.availableColorModes.map(mode => html`
                <option value=${mode} ?selected=${mode === this.settings.colorMode}>
                  ${this.getColorModeLabel(mode)}
                </option>
              `)}
            </select>
          </div>
        </div>

        <div class="setting-row">
          <span class="setting-label">Source</span>
          <div class="setting-control">
            <select
              .value=${this.settings.source}
              @change=${(e: Event) => this.updateSetting('source', (e.target as HTMLSelectElement).value as TScanSource)}
            >
              ${this.availableSources.map(src => html`
                <option value=${src} ?selected=${src === this.settings.source}>
                  ${this.getSourceLabel(src)}
                </option>
              `)}
            </select>
          </div>
        </div>
      </div>
    `;
  }

  private handleScannerChange(e: Event): void {
    const select = e.target as HTMLSelectElement;
    this.selectedScannerId = select.value || null;
    this.dispatchEvent(new CustomEvent('scanner-select', {
      detail: { scannerId: this.selectedScannerId },
      bubbles: true,
      composed: true,
    }));
  }

  private async handleScan(): Promise<void> {
    if (!this.selectedScannerId || this.isScanning) return;

    this.isScanning = true;
    this.dispatchEvent(new CustomEvent('scan-request', {
      detail: {
        scannerId: this.selectedScannerId,
        settings: this.settings,
      },
      bubbles: true,
      composed: true,
    }));
  }

  public setScanResult(result: { data: string; format: TScanFormat; thumbnail?: string }): void {
    const doc: IScannedDocument = {
      id: crypto.randomUUID(),
      timestamp: new Date(),
      format: result.format,
      data: result.data,
      thumbnail: result.thumbnail,
      size: result.data.length,
    };

    this.currentDocument = doc;
    this.currentPreview = result.thumbnail || `data:image/${result.format};base64,${result.data}`;
    this.scanHistory = [doc, ...this.scanHistory.slice(0, 19)]; // Keep last 20
    this.isScanning = false;
  }

  public setScanError(error: string): void {
    this.isScanning = false;
    console.error('Scan error:', error);
    // Could dispatch error event or show toast
  }

  private handleSaveLocal(): void {
    if (!this.currentDocument) return;

    this.dispatchEvent(new CustomEvent('save-local', {
      detail: { document: this.currentDocument },
      bubbles: true,
      composed: true,
    }));
  }

  private handleSendToProvider(providerId: string): void {
    if (!this.currentDocument) return;

    this.showSendToMenu = false;
    this.dispatchEvent(new CustomEvent('send-to-provider', {
      detail: {
        providerId,
        document: this.currentDocument,
      },
      bubbles: true,
      composed: true,
    }));
  }

  private handleHistoryItemClick(doc: IScannedDocument): void {
    this.currentDocument = doc;
    this.currentPreview = doc.thumbnail || `data:image/${doc.format};base64,${doc.data}`;
    this.activePanel = 'scan';
  }

  private updateSetting<K extends keyof IScanSettings>(key: K, value: IScanSettings[K]): void {
    this.settings = { ...this.settings, [key]: value };
    this.dispatchEvent(new CustomEvent('settings-change', {
      detail: { settings: this.settings },
      bubbles: true,
      composed: true,
    }));
  }

  private getColorModeLabel(mode: TScanColorMode): string {
    const labels: Record<TScanColorMode, string> = {
      color: 'Color',
      grayscale: 'Grayscale',
      blackwhite: 'Black & White',
    };
    return labels[mode];
  }

  private getSourceLabel(source: TScanSource): string {
    const labels: Record<TScanSource, string> = {
      flatbed: 'Flatbed',
      adf: 'Document Feeder',
      'adf-duplex': 'Document Feeder (Duplex)',
    };
    return labels[source];
  }

  private formatDate(date: Date): string {
    return new Intl.DateTimeFormat('en-US', {
      month: 'short',
      day: 'numeric',
      hour: '2-digit',
      minute: '2-digit',
    }).format(date);
  }
}
