import {
  DeesElement,
  property,
  html,
  customElement,
  type TemplateResult,
  css,
  cssManager,
  domtools,
  state,
} from '@design.estate/dees-element';
import { themeDefaultStyles } from '../../00theme.js';
import { DeesWorkspaceMonaco } from '../dees-workspace-monaco/dees-workspace-monaco.js';

const deferred = domtools.plugins.smartpromise.defer();

declare global {
  interface HTMLElementTagNameMap {
    'dees-workspace-markdown': DeesWorkspaceMarkdown;
  }
}

@customElement('dees-workspace-markdown')
export class DeesWorkspaceMarkdown extends DeesElement {
  public static demo = () => html`<dees-workspace-markdown></dees-workspace-markdown>`;
  public static demoGroup = 'Workspace';

  public static styles = [
    themeDefaultStyles,
    cssManager.defaultStyles,
    css`
      :host {
        display: block;
        position: relative;
        width: 100%;
        height: 100%;
      }

      .splitContainer {
        position: absolute;
        height: 100%;
        width: 100%;
        display: flex;
        flex-direction: row;
      }

      .editorContainer {
        position: relative;
        height: 100%;
        min-width: 100px;
        overflow: hidden;
      }

      .resizeHandle {
        width: 6px;
        height: 100%;
        background: ${cssManager.bdTheme('#e5e7eb', '#30363d')};
        cursor: col-resize;
        flex-shrink: 0;
        transition: background 0.15s ease;
        position: relative;
      }

      .resizeHandle:hover,
      .resizeHandle.dragging {
        background: ${cssManager.bdTheme('#3b82f6', '#58a6ff')};
      }

      .resizeHandle::after {
        content: '';
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        width: 2px;
        height: 32px;
        background: ${cssManager.bdTheme('#9ca3af', '#6e7681')};
        border-radius: 1px;
        opacity: 0.6;
      }

      .resizeHandle:hover::after,
      .resizeHandle.dragging::after {
        background: ${cssManager.bdTheme('#ffffff', '#ffffff')};
        opacity: 1;
      }

      .outletContainer {
        position: relative;
        height: 100%;
        min-width: 100px;
        background: ${cssManager.bdTheme('#ffffff', '#0d1117')};
        color: ${cssManager.bdTheme('#24292f', '#e6edf3')};
        font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica, Arial, sans-serif;
        padding: 20px;
        overflow-y: auto;
        box-sizing: border-box;
      }

      /* Prevent text selection while dragging */
      .splitContainer.dragging {
        user-select: none;
      }

      .splitContainer.dragging .editorContainer,
      .splitContainer.dragging .outletContainer {
        pointer-events: none;
      }
    `,
  ];

  /**
   * Initial split ratio for the editor (left) panel.
   * Value from 0 to 100 representing percentage width.
   * Default is 50 (50/50 split).
   */
  @property({ type: Number })
  accessor splitRatio: number = 50;

  /**
   * Minimum width percentage for either panel.
   */
  @property({ type: Number })
  accessor minPanelSize: number = 10;

  @state()
  accessor currentSplitRatio: number = 50;

  @state()
  accessor isDragging: boolean = false;

  private resizeHandleElement: HTMLElement;
  private containerElement: HTMLElement;

  public render() {
    return html`
      <div class="splitContainer ${this.isDragging ? 'dragging' : ''}">
        <div class="editorContainer" style="width: ${this.currentSplitRatio}%">
          <dees-workspace-monaco
            .language=${'markdown'}
            .content=${`# a test content

This is test content that is of longer form an hopefully starts to wrap when I need it. And yes, it does perfectly. nice.

Test | Hello
--- | ---
Yeah | So good

This is real asset I think. Why would we want to leave that on the table? Can you tell my that?

Why are we here?

Do you know?

> note:
There is something going on.

\`\`\`typescript
const hello = 'yes'
\`\`\`
`}
            wordWrap="bounded"
          ></dees-workspace-monaco>
        </div>
        <div
          class="resizeHandle ${this.isDragging ? 'dragging' : ''}"
          @mousedown=${this.handleMouseDown}
        ></div>
        <div class="outletContainer" style="width: ${100 - this.currentSplitRatio}%">
          <dees-workspace-markdownoutlet></dees-workspace-markdownoutlet>
        </div>
      </div>
    `;
  }

  public async firstUpdated(_changedPropertiesArg) {
    await super.firstUpdated(_changedPropertiesArg);

    // Initialize current ratio from property
    this.currentSplitRatio = this.splitRatio;

    // Cache elements
    this.containerElement = this.shadowRoot.querySelector('.splitContainer');
    this.resizeHandleElement = this.shadowRoot.querySelector('.resizeHandle');

    const editor = this.shadowRoot.querySelector('dees-workspace-monaco') as DeesWorkspaceMonaco;

    // Wire up markdown rendering
    const markdownOutlet = this.shadowRoot.querySelector('dees-workspace-markdownoutlet');
    const smartmarkdownInstance = new domtools.plugins.smartmarkdown.SmartMarkdown();
    const mdParsedResult = await smartmarkdownInstance.getMdParsedResultFromMarkdown('loading...')
    editor.contentSubject.subscribe(async contentArg => {
      await mdParsedResult.updateFromMarkdownString(contentArg)
      const html = mdParsedResult.html;
      markdownOutlet.updateHtmlText(html);
    });
  }

  private handleMouseDown = (e: MouseEvent) => {
    e.preventDefault();
    this.isDragging = true;

    document.addEventListener('mousemove', this.handleMouseMove);
    document.addEventListener('mouseup', this.handleMouseUp);
  };

  private handleMouseMove = (e: MouseEvent) => {
    if (!this.isDragging || !this.containerElement) return;

    const containerRect = this.containerElement.getBoundingClientRect();
    const containerWidth = containerRect.width;
    const mouseX = e.clientX - containerRect.left;

    // Calculate percentage, accounting for the resize handle width (6px)
    let newRatio = (mouseX / containerWidth) * 100;

    // Clamp to min/max
    newRatio = Math.max(this.minPanelSize, Math.min(100 - this.minPanelSize, newRatio));

    this.currentSplitRatio = newRatio;
  };

  private handleMouseUp = () => {
    this.isDragging = false;
    document.removeEventListener('mousemove', this.handleMouseMove);
    document.removeEventListener('mouseup', this.handleMouseUp);

    // Trigger resize on monaco editor
    const editor = this.shadowRoot.querySelector('dees-workspace-monaco') as DeesWorkspaceMonaco;
    if (editor) {
      // Monaco needs to be notified of size changes
      window.dispatchEvent(new Event('resize'));
    }
  };

  async disconnectedCallback() {
    await super.disconnectedCallback();
    // Clean up event listeners
    document.removeEventListener('mousemove', this.handleMouseMove);
    document.removeEventListener('mouseup', this.handleMouseUp);
  }

  /**
   * Programmatically set the split ratio
   */
  public setSplitRatio(ratio: number) {
    this.currentSplitRatio = Math.max(this.minPanelSize, Math.min(100 - this.minPanelSize, ratio));
  }

  /**
   * Reset to initial split ratio
   */
  public resetSplitRatio() {
    this.currentSplitRatio = this.splitRatio;
  }
}
