import { attemptSummary, overlayCollapsedLines, policyLabel, relativeAge } from './presentation.js';
import type { ContinuityWorkerView, UiAction } from './ui-model.js';

export interface ManagedOverlay {
  update(worker: ContinuityWorkerView | null, visible: boolean): void;
  destroy(): void;
}

const HOST_ID = 'chatgpt-orchestrator-overlay-host';

export function overlayShouldRender(worker: ContinuityWorkerView | null, visible: boolean): boolean {
  return visible && worker !== null;
}

export function createManagedOverlay(
  document: Document,
  onAction: (action: UiAction, worker: ContinuityWorkerView, enabled?: boolean) => void,
): ManagedOverlay {
  document.getElementById(HOST_ID)?.remove();
  const host = document.createElement('div');
  host.id = HOST_ID;
  host.setAttribute('data-chatgpt-orchestrator-owned', 'true');
  host.style.position = 'fixed';
  host.style.inset = '0 auto auto 0';
  host.style.inlineSize = '0';
  host.style.blockSize = '0';
  host.style.pointerEvents = 'none';
  const shadow = host.attachShadow({ mode: 'closed' });
  shadow.innerHTML = `
    <style>
      :host { all: initial; }
      .root { position: fixed; right: 16px; bottom: 96px; z-index: 2147483646; width: min(330px, calc(100vw - 32px)); color: #111827; font: 13px/1.4 system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; pointer-events: auto; }
      .collapsed, .drawer { box-sizing: border-box; background: rgba(255,255,255,.98); border: 1px solid #d1d5db; box-shadow: 0 8px 24px rgba(0,0,0,.16); }
      .collapsed { display: flex; width: 100%; min-height: 44px; align-items: center; justify-content: space-between; gap: 10px; border-radius: 999px; padding: 7px 12px; color: inherit; font: inherit; cursor: pointer; text-align: left; }
      .collapsed-copy { display: grid; gap: 1px; min-width: 0; }
      .collapsed-title { font-weight: 750; }
      .collapsed-detail { color: #4b5563; font-size: 11px; font-weight: 650; overflow-wrap: anywhere; }
      .collapsed:hover { background: #f9fafb; }
      .collapsed:focus-visible, button:focus-visible { outline: 3px solid #2563eb; outline-offset: 2px; }
      .drawer { margin-top: 8px; max-height: min(520px, calc(100vh - 190px)); overflow: auto; border-radius: 14px; padding: 14px; }
      .drawer[hidden] { display: none; }
      .eyebrow { margin: 0 0 4px; color: #4b5563; font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; }
      h2 { margin: 0; font: 700 15px/1.3 system-ui, sans-serif; overflow-wrap: anywhere; }
      .hierarchy { margin: 3px 0 0; color: #4b5563; font-size: 11px; overflow-wrap: anywhere; }
      .status { margin: 8px 0 0; font-weight: 700; }
      .meta { margin: 3px 0 0; color: #4b5563; }
      dl { display: grid; grid-template-columns: auto 1fr; gap: 4px 10px; margin: 12px 0; }
      dt { color: #4b5563; } dd { margin: 0; text-align: right; overflow-wrap: anywhere; }
      .actions { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
      button.action { min-height: 36px; border: 1px solid #c7cdd6; border-radius: 8px; background: #fff; color: #111827; font: 600 12px/1.2 system-ui, sans-serif; cursor: pointer; }
      button.action:hover:not(:disabled) { background: #f3f4f6; }
      button.action:disabled { opacity: .55; cursor: not-allowed; }
      button.stop { border-color: #b91c1c; color: #991b1b; }
      .events-title { margin: 13px 0 5px; font-size: 11px; font-weight: 750; text-transform: uppercase; letter-spacing: .04em; }
      .events { display: grid; gap: 5px; margin: 0; padding: 0; list-style: none; }
      .events li { padding: 6px 7px; border-radius: 7px; background: #f3f4f6; font-size: 11px; overflow-wrap: anywhere; }
      .hint { margin: 10px 0 0; color: #4b5563; font-size: 11px; }
      @media (max-width: 520px) { .root { right: 10px; bottom: 88px; width: min(310px, calc(100vw - 20px)); } }
      @media (prefers-color-scheme: dark) { .root { color: #f9fafb; } .collapsed, .drawer { background: rgba(31,41,55,.98); border-color: #4b5563; } .collapsed:hover, button.action:hover:not(:disabled) { background: #374151; } .collapsed-detail, .eyebrow, .hierarchy, .meta, dt, .hint { color: #d1d5db; } button.action { background: #1f2937; color: #f9fafb; border-color: #6b7280; } button.stop { color: #fecaca; border-color: #f87171; } .events li { background: #374151; } }
    </style>
    <section class="root" hidden aria-label="ChatGPT Orchestrator execution continuity">
      <button class="collapsed" type="button" aria-expanded="false" aria-controls="orchestrator-drawer">
        <span class="collapsed-copy"><span class="collapsed-title">Orchestrated</span><span class="collapsed-detail">Loading</span></span>
        <span aria-hidden="true">⌃</span>
      </button>
      <div class="drawer" id="orchestrator-drawer" hidden>
        <p class="eyebrow">Execution Continuity</p>
        <h2 class="worker-name"></h2>
        <p class="hierarchy" hidden></p>
        <p class="status" role="status" aria-live="polite"></p>
        <p class="meta"></p>
        <dl>
          <dt>Policy</dt><dd class="policy">Unknown</dd>
          <dt>Attempt</dt><dd class="attempt">Unavailable</dd>
          <dt>Auto resumes</dt><dd class="resume-count">Unavailable</dd>
          <dt>Last progress</dt><dd class="progress">Unavailable</dd>
        </dl>
        <div class="actions">
          <button class="action pause" type="button">Pause</button>
          <button class="action continue" type="button">Continue now</button>
          <button class="action stop" type="button">Stop worker</button>
          <button class="action toggle-auto" type="button">Toggle Auto Resume</button>
        </div>
        <p class="events-title">Recent continuity events</p>
        <ul class="events"></ul>
        <p class="hint"></p>
      </div>
    </section>
  `;
  document.documentElement.append(host);

  const root = shadow.querySelector<HTMLElement>('.root')!;
  const collapsed = shadow.querySelector<HTMLButtonElement>('.collapsed')!;
  const collapsedTitle = shadow.querySelector<HTMLElement>('.collapsed-title')!;
  const collapsedDetail = shadow.querySelector<HTMLElement>('.collapsed-detail')!;
  const drawer = shadow.querySelector<HTMLElement>('.drawer')!;
  const workerName = shadow.querySelector<HTMLElement>('.worker-name')!;
  const hierarchy = shadow.querySelector<HTMLElement>('.hierarchy')!;
  const status = shadow.querySelector<HTMLElement>('.status')!;
  const meta = shadow.querySelector<HTMLElement>('.meta')!;
  const policy = shadow.querySelector<HTMLElement>('.policy')!;
  const attempt = shadow.querySelector<HTMLElement>('.attempt')!;
  const resumeCount = shadow.querySelector<HTMLElement>('.resume-count')!;
  const progress = shadow.querySelector<HTMLElement>('.progress')!;
  const events = shadow.querySelector<HTMLUListElement>('.events')!;
  const hint = shadow.querySelector<HTMLElement>('.hint')!;
  const pause = shadow.querySelector<HTMLButtonElement>('.pause')!;
  const continueNow = shadow.querySelector<HTMLButtonElement>('.continue')!;
  const stop = shadow.querySelector<HTMLButtonElement>('.stop')!;
  const toggleAuto = shadow.querySelector<HTMLButtonElement>('.toggle-auto')!;
  let current: ContinuityWorkerView | null = null;

  const setExpanded = (expanded: boolean): void => {
    collapsed.setAttribute('aria-expanded', String(expanded));
    drawer.hidden = !expanded;
  };
  collapsed.addEventListener('click', () => setExpanded(collapsed.getAttribute('aria-expanded') !== 'true'));
  collapsed.addEventListener('keydown', (event) => {
    if (event.key === 'Escape') setExpanded(false);
  });
  drawer.addEventListener('keydown', (event) => {
    if (event.key === 'Escape') {
      setExpanded(false);
      collapsed.focus();
    }
  });

  pause.addEventListener('click', () => { if (current) onAction('pause', current); });
  continueNow.addEventListener('click', () => { if (current) onAction('continue-now', current); });
  stop.addEventListener('click', () => {
    const confirm = document.defaultView?.confirm.bind(document.defaultView);
    if (current && confirm?.(`Stop ${current.label}? This interrupts the logical worker rather than merely pausing continuation.`)) onAction('stop', current);
  });
  toggleAuto.addEventListener('click', () => {
    if (!current || current.policyMode === null) return;
    onAction('set-auto-resume', current, current.policyMode !== 'auto');
  });

  const renderEvents = (worker: ContinuityWorkerView): void => {
    events.replaceChildren();
    if (worker.recentEvents === null) {
      const item = document.createElement('li');
      item.textContent = 'Recent continuity events are not exposed by the current backend UI contract.';
      events.append(item);
      return;
    }
    if (worker.recentEvents.length === 0) {
      const item = document.createElement('li');
      item.textContent = 'No recent continuity events.';
      events.append(item);
      return;
    }
    for (const event of worker.recentEvents.slice(-4).reverse()) {
      const item = document.createElement('li');
      item.textContent = `${event.type} · ${relativeAge(event.timestamp)}${event.detail ? ` · ${event.detail}` : ''}`;
      events.append(item);
    }
  };

  const update = (worker: ContinuityWorkerView | null, visible: boolean): void => {
    current = worker;
    root.hidden = !overlayShouldRender(worker, visible);
    if (!worker || !visible) {
      setExpanded(false);
      return;
    }
    const collapsedLines = overlayCollapsedLines(worker);
    collapsedTitle.textContent = collapsedLines.primary;
    collapsedDetail.textContent = collapsedLines.detail;
    workerName.textContent = worker.label;
    hierarchy.textContent = worker.hierarchicalName && worker.hierarchicalName !== worker.label ? worker.hierarchicalName : '';
    hierarchy.hidden = hierarchy.textContent === '';
    status.textContent = worker.statusLabel;
    meta.textContent = attemptSummary(worker);
    policy.textContent = policyLabel(worker);
    attempt.textContent = worker.attemptNumber === null ? 'Unavailable' : String(worker.attemptNumber);
    resumeCount.textContent = worker.autoResumeCount === null ? 'Unavailable' : String(worker.autoResumeCount);
    progress.textContent = relativeAge(worker.lastProgressAt);
    for (const button of [pause, continueNow, stop]) button.disabled = !worker.controlAvailable;
    toggleAuto.disabled = !worker.controlAvailable || worker.policyMode === null;
    toggleAuto.textContent = worker.policyMode === 'auto' ? 'Disable Auto Resume' : 'Enable Auto Resume';
    hint.textContent = worker.controlAvailable ? '' : 'Backend continuity controls are not available for this worker.';
    renderEvents(worker);
  };

  return { update, destroy: () => host.remove() };
}
