import { DeesInputBase } from '../dees-input-base/dees-input-base.js';
import {
  customElement,
  type TemplateResult,
  property,
  html,
  cssManager,
  css,
  state,
} from '@design.estate/dees-element';
import { themeDefaultStyles } from '../../00theme.js';
import { DeesModal } from '../../dees-modal/dees-modal.js';
import '../../dees-icon/dees-icon.js';
import '../../dees-label/dees-label.js';
import '../../00group-workspace/dees-workspace-monaco/dees-workspace-monaco.js';
import { DeesWorkspaceMonaco } from '../../00group-workspace/dees-workspace-monaco/dees-workspace-monaco.js';

declare global {
  interface HTMLElementTagNameMap {
    'dees-input-code': DeesInputCode;
  }
}

// Common programming languages for the language selector
const LANGUAGES = [
  { key: 'typescript', label: 'TypeScript' },
  { key: 'javascript', label: 'JavaScript' },
  { key: 'json', label: 'JSON' },
  { key: 'html', label: 'HTML' },
  { key: 'css', label: 'CSS' },
  { key: 'scss', label: 'SCSS' },
  { key: 'markdown', label: 'Markdown' },
  { key: 'yaml', label: 'YAML' },
  { key: 'xml', label: 'XML' },
  { key: 'sql', label: 'SQL' },
  { key: 'python', label: 'Python' },
  { key: 'java', label: 'Java' },
  { key: 'csharp', label: 'C#' },
  { key: 'cpp', label: 'C++' },
  { key: 'go', label: 'Go' },
  { key: 'rust', label: 'Rust' },
  { key: 'shell', label: 'Shell' },
  { key: 'plaintext', label: 'Plain Text' },
];

@customElement('dees-input-code')
export class DeesInputCode extends DeesInputBase<string> {
  public static demo = () => html`
    <dees-input-code
      label="TypeScript Code"
      key="code"
      language="typescript"
      height="300px"
      .value=${'const greeting: string = "Hello World";\nconsole.log(greeting);'}
    ></dees-input-code>
  `;
  public static demoGroup = 'Input';

  // INSTANCE
  @property({ type: String })
  accessor value: string = '';

  @property({ type: String })
  accessor language: string = 'typescript';

  @property({ type: String })
  accessor height: string = '200px';

  @property({ type: String })
  accessor wordWrap: 'on' | 'off' = 'off';

  @property({ type: Boolean })
  accessor showLineNumbers: boolean = true;

  @state()
  accessor isLanguageDropdownOpen: boolean = false;

  @state()
  accessor copySuccess: boolean = false;

  private editorElement: DeesWorkspaceMonaco | null = null;

  public static styles = [
    themeDefaultStyles,
    ...DeesInputBase.baseStyles,
    cssManager.defaultStyles,
    css`
      * {
        box-sizing: border-box;
      }

      :host {
        display: block;
      }

      .code-container {
        border: 1px solid ${cssManager.bdTheme('hsl(0 0% 89.8%)', 'hsl(0 0% 14.9%)')};
        border-radius: 6px;
        overflow: hidden;
        background: ${cssManager.bdTheme('hsl(0 0% 100%)', 'hsl(0 0% 9%)')};
      }

      .toolbar {
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 8px 12px;
        background: ${cssManager.bdTheme('hsl(0 0% 97%)', 'hsl(0 0% 7%)')};
        border-bottom: 1px solid ${cssManager.bdTheme('hsl(0 0% 89.8%)', 'hsl(0 0% 14.9%)')};
        gap: 8px;
      }

      .toolbar-left {
        display: flex;
        align-items: center;
        gap: 8px;
      }

      .toolbar-right {
        display: flex;
        align-items: center;
        gap: 4px;
      }

      .language-selector {
        position: relative;
      }

      .language-button {
        display: flex;
        align-items: center;
        gap: 6px;
        padding: 4px 10px;
        font-size: 12px;
        font-weight: 500;
        background: ${cssManager.bdTheme('hsl(0 0% 100%)', 'hsl(0 0% 12%)')};
        border: 1px solid ${cssManager.bdTheme('hsl(0 0% 89.8%)', 'hsl(0 0% 20%)')};
        border-radius: 4px;
        cursor: pointer;
        color: ${cssManager.bdTheme('hsl(0 0% 20%)', 'hsl(0 0% 90%)')};
        transition: all 0.15s ease;
      }

      .language-button:hover {
        background: ${cssManager.bdTheme('hsl(0 0% 95%)', 'hsl(0 0% 15%)')};
      }

      .language-dropdown {
        position: absolute;
        top: 100%;
        left: 0;
        margin-top: 4px;
        background: ${cssManager.bdTheme('hsl(0 0% 100%)', 'hsl(0 0% 9%)')};
        border: 1px solid ${cssManager.bdTheme('hsl(0 0% 89.8%)', 'hsl(0 0% 20%)')};
        border-radius: 6px;
        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
        z-index: 100;
        max-height: 250px;
        overflow-y: auto;
        min-width: 140px;
      }

      .language-option {
        padding: 8px 12px;
        font-size: 12px;
        cursor: pointer;
        color: ${cssManager.bdTheme('hsl(0 0% 20%)', 'hsl(0 0% 90%)')};
        transition: background 0.15s ease;
      }

      .language-option:hover {
        background: ${cssManager.bdTheme('hsl(0 0% 95%)', 'hsl(0 0% 15%)')};
      }

      .language-option.selected {
        background: ${cssManager.bdTheme('hsl(0 0% 90%)', 'hsl(0 0% 20%)')};
      }

      .toolbar-button {
        display: flex;
        align-items: center;
        justify-content: center;
        width: 32px;
        height: 32px;
        background: transparent;
        border: none;
        border-radius: 4px;
        cursor: pointer;
        color: ${cssManager.bdTheme('hsl(0 0% 45%)', 'hsl(0 0% 60%)')};
        transition: all 0.15s ease;
      }

      .toolbar-button:hover {
        background: ${cssManager.bdTheme('hsl(0 0% 90%)', 'hsl(0 0% 15%)')};
        color: ${cssManager.bdTheme('hsl(0 0% 20%)', 'hsl(0 0% 90%)')};
      }

      .toolbar-button.active {
        background: ${cssManager.bdTheme('hsl(0 0% 85%)', 'hsl(0 0% 20%)')};
        color: ${cssManager.bdTheme('hsl(0 0% 20%)', 'hsl(0 0% 90%)')};
      }

      .toolbar-button.success {
        color: hsl(142.1 76.2% 36.3%);
      }

      .editor-wrapper {
        position: relative;
      }

      dees-workspace-monaco {
        display: block;
      }

      .toolbar-divider {
        width: 1px;
        height: 20px;
        background: ${cssManager.bdTheme('hsl(0 0% 85%)', 'hsl(0 0% 20%)')};
        margin: 0 4px;
      }

      :host([disabled]) .code-container {
        opacity: 0.5;
        pointer-events: none;
      }
    `,
  ];

  public render(): TemplateResult {
    const currentLanguage = LANGUAGES.find(l => l.key === this.language) || LANGUAGES[0];

    return html`
      <style>
        .editor-wrapper {
          height: ${this.height};
        }
      </style>
      <div class="input-wrapper">
        <dees-label .label=${this.label} .description=${this.description} .required=${this.required}></dees-label>
        <div class="code-container">
          <div class="toolbar">
            <div class="toolbar-left">
              <div class="language-selector">
                <button
                  class="language-button"
                  @click=${this.toggleLanguageDropdown}
                  @blur=${this.handleLanguageBlur}
                >
                  ${currentLanguage.label}
                  <dees-icon .icon=${'lucide:ChevronDown'} iconSize="14"></dees-icon>
                </button>
                ${this.isLanguageDropdownOpen ? html`
                  <div class="language-dropdown">
                    ${LANGUAGES.map(lang => html`
                      <div
                        class="language-option ${lang.key === this.language ? 'selected' : ''}"
                        @mousedown=${(e: Event) => this.selectLanguage(e, lang.key)}
                      >
                        ${lang.label}
                      </div>
                    `)}
                  </div>
                ` : ''}
              </div>
            </div>
            <div class="toolbar-right">
              <button
                class="toolbar-button ${this.wordWrap === 'on' ? 'active' : ''}"
                title="Word Wrap"
                @click=${this.toggleWordWrap}
              >
                <dees-icon .icon=${'lucide:WrapText'} iconSize="16"></dees-icon>
              </button>
              <button
                class="toolbar-button ${this.showLineNumbers ? 'active' : ''}"
                title="Line Numbers"
                @click=${this.toggleLineNumbers}
              >
                <dees-icon .icon=${'lucide:Hash'} iconSize="16"></dees-icon>
              </button>
              <div class="toolbar-divider"></div>
              <button
                class="toolbar-button ${this.copySuccess ? 'success' : ''}"
                title="Copy Code"
                @click=${this.copyCode}
              >
                <dees-icon .icon=${this.copySuccess ? 'lucide:Check' : 'lucide:Copy'} iconSize="16"></dees-icon>
              </button>
              <button
                class="toolbar-button"
                title="Expand"
                @click=${this.openFullscreen}
              >
                <dees-icon .icon=${'lucide:Maximize2'} iconSize="16"></dees-icon>
              </button>
            </div>
          </div>
          <div class="editor-wrapper">
            <dees-workspace-monaco
              .content=${this.value}
              .language=${this.language}
              .wordWrap=${this.wordWrap}
              @content-change=${this.handleContentChange}
            ></dees-workspace-monaco>
          </div>
        </div>
      </div>
    `;
  }

  async firstUpdated() {
    this.editorElement = this.shadowRoot?.querySelector('dees-workspace-monaco') as DeesWorkspaceMonaco;
    if (this.editorElement) {
      // Subscribe to content changes from the editor
      this.editorElement.contentSubject.subscribe((newContent: string) => {
        if (this.value !== newContent) {
          this.value = newContent;
          this.changeSubject.next(this as any);
        }
      });
    }
  }

  private toggleLanguageDropdown() {
    this.isLanguageDropdownOpen = !this.isLanguageDropdownOpen;
  }

  private handleLanguageBlur() {
    // Small delay to allow click events on dropdown items
    setTimeout(() => {
      this.isLanguageDropdownOpen = false;
    }, 150);
  }

  private async selectLanguage(e: Event, languageKey: string) {
    e.preventDefault();
    this.language = languageKey;
    this.isLanguageDropdownOpen = false;

    // Update the editor language
    if (this.editorElement) {
      this.editorElement.language = languageKey;
      const editor = await this.editorElement.editorDeferred.promise;
      const model = editor.getModel();
      if (model) {
        (window as any).monaco.editor.setModelLanguage(model, languageKey);
      }
    }
  }

  private toggleWordWrap() {
    this.wordWrap = this.wordWrap === 'on' ? 'off' : 'on';
    this.updateEditorOption('wordWrap', this.wordWrap);
  }

  private toggleLineNumbers() {
    this.showLineNumbers = !this.showLineNumbers;
    this.updateEditorOption('lineNumbers', this.showLineNumbers ? 'on' : 'off');
  }

  private async updateEditorOption(option: string, value: any) {
    if (this.editorElement) {
      const editor = await this.editorElement.editorDeferred.promise;
      editor.updateOptions({ [option]: value });
    }
  }

  private async copyCode() {
    try {
      await navigator.clipboard.writeText(this.value);
      this.copySuccess = true;
      setTimeout(() => {
        this.copySuccess = false;
      }, 2000);
    } catch (err) {
      console.error('Failed to copy code:', err);
    }
  }

  private handleContentChange(e: CustomEvent) {
    const newContent = e.detail;
    if (this.value !== newContent) {
      this.value = newContent;
      this.changeSubject.next(this as any);
    }
  }

  public async openFullscreen() {
    const currentValue = this.value;
    let modalEditorElement: DeesWorkspaceMonaco | null = null;

    // Modal-specific state
    let modalLanguage = this.language;
    let modalWordWrap = this.wordWrap;
    let modalShowLineNumbers = this.showLineNumbers;
    let modalLanguageDropdownOpen = false;
    let modalCopySuccess = false;

    // Helper to get current language label
    const getLanguageLabel = () => {
      const lang = LANGUAGES.find(l => l.key === modalLanguage);
      return lang ? lang.label : 'TypeScript';
    };

    // Helper to update toolbar UI
    const updateToolbarUI = (modal: DeesModal) => {
      const toolbar = modal.shadowRoot?.querySelector('.modal-toolbar');
      if (!toolbar) return;

      // Update language button text
      const langBtn = toolbar.querySelector('.language-button span');
      if (langBtn) langBtn.textContent = getLanguageLabel();

      // Update word wrap button
      const wrapBtn = toolbar.querySelector('.wrap-btn') as HTMLElement;
      if (wrapBtn) {
        wrapBtn.classList.toggle('active', modalWordWrap === 'on');
      }

      // Update line numbers button
      const linesBtn = toolbar.querySelector('.lines-btn') as HTMLElement;
      if (linesBtn) {
        linesBtn.classList.toggle('active', modalShowLineNumbers);
      }

      // Update copy button
      const copyBtn = toolbar.querySelector('.copy-btn') as HTMLElement;
      const copyIcon = copyBtn?.querySelector('dees-icon') as any;
      if (copyBtn && copyIcon) {
        copyBtn.classList.toggle('success', modalCopySuccess);
        copyIcon.icon = modalCopySuccess ? 'lucide:Check' : 'lucide:Copy';
      }

      // Update dropdown visibility
      const dropdown = toolbar.querySelector('.language-dropdown') as HTMLElement;
      if (dropdown) {
        dropdown.style.display = modalLanguageDropdownOpen ? 'block' : 'none';
      }
    };

    const modal = await DeesModal.createAndShow({
      heading: this.label || 'Code Editor',
      width: 'fullscreen',
      contentPadding: 0,
      content: html`
        <style>
          .modal-toolbar {
            display: flex;
            align-items: center;
            justify-content: space-between;
            padding: 8px 12px;
            background: ${cssManager.bdTheme('hsl(0 0% 97%)', 'hsl(0 0% 7%)')};
            border-bottom: 1px solid ${cssManager.bdTheme('hsl(0 0% 89.8%)', 'hsl(0 0% 14.9%)')};
            gap: 8px;
          }
          .modal-toolbar .toolbar-left {
            display: flex;
            align-items: center;
            gap: 8px;
          }
          .modal-toolbar .toolbar-right {
            display: flex;
            align-items: center;
            gap: 4px;
          }
          .modal-toolbar .language-selector {
            position: relative;
          }
          .modal-toolbar .language-button {
            display: flex;
            align-items: center;
            gap: 6px;
            padding: 4px 10px;
            font-size: 12px;
            font-weight: 500;
            background: ${cssManager.bdTheme('hsl(0 0% 100%)', 'hsl(0 0% 12%)')};
            border: 1px solid ${cssManager.bdTheme('hsl(0 0% 89.8%)', 'hsl(0 0% 20%)')};
            border-radius: 4px;
            cursor: pointer;
            color: ${cssManager.bdTheme('hsl(0 0% 20%)', 'hsl(0 0% 90%)')};
            transition: all 0.15s ease;
          }
          .modal-toolbar .language-button:hover {
            background: ${cssManager.bdTheme('hsl(0 0% 95%)', 'hsl(0 0% 15%)')};
          }
          .modal-toolbar .language-dropdown {
            position: absolute;
            top: 100%;
            left: 0;
            margin-top: 4px;
            background: ${cssManager.bdTheme('hsl(0 0% 100%)', 'hsl(0 0% 9%)')};
            border: 1px solid ${cssManager.bdTheme('hsl(0 0% 89.8%)', 'hsl(0 0% 20%)')};
            border-radius: 6px;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
            z-index: 100;
            max-height: 250px;
            overflow-y: auto;
            min-width: 140px;
            display: none;
          }
          .modal-toolbar .language-option {
            padding: 8px 12px;
            font-size: 12px;
            cursor: pointer;
            color: ${cssManager.bdTheme('hsl(0 0% 20%)', 'hsl(0 0% 90%)')};
            transition: background 0.15s ease;
          }
          .modal-toolbar .language-option:hover {
            background: ${cssManager.bdTheme('hsl(0 0% 95%)', 'hsl(0 0% 15%)')};
          }
          .modal-toolbar .language-option.selected {
            background: ${cssManager.bdTheme('hsl(0 0% 90%)', 'hsl(0 0% 20%)')};
          }
          .modal-toolbar .toolbar-button {
            display: flex;
            align-items: center;
            justify-content: center;
            width: 32px;
            height: 32px;
            background: transparent;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            color: ${cssManager.bdTheme('hsl(0 0% 45%)', 'hsl(0 0% 60%)')};
            transition: all 0.15s ease;
          }
          .modal-toolbar .toolbar-button:hover {
            background: ${cssManager.bdTheme('hsl(0 0% 90%)', 'hsl(0 0% 15%)')};
            color: ${cssManager.bdTheme('hsl(0 0% 20%)', 'hsl(0 0% 90%)')};
          }
          .modal-toolbar .toolbar-button.active {
            background: ${cssManager.bdTheme('hsl(0 0% 85%)', 'hsl(0 0% 20%)')};
            color: ${cssManager.bdTheme('hsl(0 0% 20%)', 'hsl(0 0% 90%)')};
          }
          .modal-toolbar .toolbar-button.success {
            color: hsl(142.1 76.2% 36.3%);
          }
          .modal-toolbar .toolbar-divider {
            width: 1px;
            height: 20px;
            background: ${cssManager.bdTheme('hsl(0 0% 85%)', 'hsl(0 0% 20%)')};
            margin: 0 4px;
          }
          .modal-editor-wrapper {
            position: relative;
            height: calc(100vh - 175px);
            width: 100%;
          }
        </style>
        <div class="modal-toolbar">
          <div class="toolbar-left">
            <div class="language-selector">
              <button class="language-button">
                <span>${getLanguageLabel()}</span>
                <dees-icon .icon=${'lucide:ChevronDown'} iconSize="14"></dees-icon>
              </button>
              <div class="language-dropdown">
                ${LANGUAGES.map(lang => html`
                  <div
                    class="language-option ${lang.key === modalLanguage ? 'selected' : ''}"
                    data-lang="${lang.key}"
                  >
                    ${lang.label}
                  </div>
                `)}
              </div>
            </div>
          </div>
          <div class="toolbar-right">
            <button class="toolbar-button wrap-btn ${modalWordWrap === 'on' ? 'active' : ''}" title="Word Wrap">
              <dees-icon .icon=${'lucide:WrapText'} iconSize="16"></dees-icon>
            </button>
            <button class="toolbar-button lines-btn ${modalShowLineNumbers ? 'active' : ''}" title="Line Numbers">
              <dees-icon .icon=${'lucide:Hash'} iconSize="16"></dees-icon>
            </button>
            <div class="toolbar-divider"></div>
            <button class="toolbar-button copy-btn" title="Copy Code">
              <dees-icon .icon=${'lucide:Copy'} iconSize="16"></dees-icon>
            </button>
          </div>
        </div>
        <div class="modal-editor-wrapper">
          <dees-workspace-monaco
            .content=${currentValue}
            .language=${modalLanguage}
            .wordWrap=${modalWordWrap}
          ></dees-workspace-monaco>
        </div>
      `,
      menuOptions: [
        {
          name: 'Cancel',
          action: async (modalRef) => {
            await modalRef.destroy();
          },
        },
        {
          name: 'Save & Close',
          action: async (modalRef) => {
            // Get the editor content from the modal
            modalEditorElement = modalRef.shadowRoot?.querySelector('dees-workspace-monaco') as DeesWorkspaceMonaco;
            if (modalEditorElement) {
              const editor = await modalEditorElement.editorDeferred.promise;
              const newValue = editor.getValue();
              this.setValue(newValue);
            }
            await modalRef.destroy();
          },
        },
      ],
    });

    // Wait for modal to render
    await new Promise(resolve => setTimeout(resolve, 100));
    modalEditorElement = modal.shadowRoot?.querySelector('dees-workspace-monaco') as DeesWorkspaceMonaco;

    // Wire up toolbar event handlers
    const toolbar = modal.shadowRoot?.querySelector('.modal-toolbar');
    if (toolbar) {
      // Language button click
      const langBtn = toolbar.querySelector('.language-button');
      langBtn?.addEventListener('click', () => {
        modalLanguageDropdownOpen = !modalLanguageDropdownOpen;
        updateToolbarUI(modal);
      });

      // Language option clicks
      const langOptions = toolbar.querySelectorAll('.language-option');
      langOptions.forEach((option) => {
        option.addEventListener('click', async () => {
          const newLang = (option as HTMLElement).dataset.lang;
          if (newLang && modalEditorElement) {
            modalLanguage = newLang;
            modalLanguageDropdownOpen = false;

            // Update editor language
            const editor = await modalEditorElement.editorDeferred.promise;
            const model = editor.getModel();
            if (model) {
              (window as any).monaco.editor.setModelLanguage(model, newLang);
            }

            // Update selected state
            langOptions.forEach(opt => opt.classList.remove('selected'));
            option.classList.add('selected');

            updateToolbarUI(modal);
          }
        });
      });

      // Word wrap button
      const wrapBtn = toolbar.querySelector('.wrap-btn');
      wrapBtn?.addEventListener('click', async () => {
        modalWordWrap = modalWordWrap === 'on' ? 'off' : 'on';
        if (modalEditorElement) {
          const editor = await modalEditorElement.editorDeferred.promise;
          editor.updateOptions({ wordWrap: modalWordWrap });
        }
        updateToolbarUI(modal);
      });

      // Line numbers button
      const linesBtn = toolbar.querySelector('.lines-btn');
      linesBtn?.addEventListener('click', async () => {
        modalShowLineNumbers = !modalShowLineNumbers;
        if (modalEditorElement) {
          const editor = await modalEditorElement.editorDeferred.promise;
          editor.updateOptions({ lineNumbers: modalShowLineNumbers ? 'on' : 'off' });
        }
        updateToolbarUI(modal);
      });

      // Copy button
      const copyBtn = toolbar.querySelector('.copy-btn');
      copyBtn?.addEventListener('click', async () => {
        if (modalEditorElement) {
          const editor = await modalEditorElement.editorDeferred.promise;
          const content = editor.getValue();
          try {
            await navigator.clipboard.writeText(content);
            modalCopySuccess = true;
            updateToolbarUI(modal);
            setTimeout(() => {
              modalCopySuccess = false;
              updateToolbarUI(modal);
            }, 2000);
          } catch (err) {
            console.error('Failed to copy code:', err);
          }
        }
      });

      // Close dropdown when clicking outside
      document.addEventListener('click', (e) => {
        if (modalLanguageDropdownOpen && !langBtn?.contains(e.target as Node)) {
          modalLanguageDropdownOpen = false;
          updateToolbarUI(modal);
        }
      }, { once: true });
    }
  }

  public getValue(): string {
    return this.value;
  }

  public setValue(value: string): void {
    this.value = value;
    if (this.editorElement) {
      this.editorElement.content = value;
      // Also update the Monaco editor directly if it's already loaded
      this.editorElement.editorDeferred.promise.then(editor => {
        if (editor.getValue() !== value) {
          editor.setValue(value);
        }
      });
    }
    this.changeSubject.next(this as any);
  }
}
