import browser from 'webextension-polyfill';
import {
  ChatGptProductStateError,
  ChatGptWebAdapter,
  HostUiChangedError,
  type ChatGptInspection,
  type ChatGptWaitCondition,
} from '@platform-modules/chatgpt-web-adapter';
import { createManagedOverlay } from './overlay.js';
import { OVERLAY_MESSAGE_KIND, UI_MESSAGE_KIND, type OverlayUpdate } from './ui-model.js';

const CONTENT_KIND = 'chatgpt-orchestrator.content' as const;
const STATE_KIND = 'chatgpt-orchestrator.content-state' as const;

void browser.runtime.sendMessage({ kind: 'chatgpt-orchestrator.wake' }).catch(() => undefined);

interface ContentRequest {
  kind: typeof CONTENT_KIND;
  action: 'inspect' | 'submit' | 'steer' | 'wait';
  prompt?: string;
  condition?: ChatGptWaitCondition;
  timeoutMs?: number;
}

const adapter = new ChatGptWebAdapter();
const overlay = createManagedOverlay(document, (action, worker, enabled) => {
  void browser.runtime.sendMessage({
    kind: UI_MESSAGE_KIND,
    action,
    workerId: worker.workerId,
    ...(action === 'set-auto-resume' ? { enabled: Boolean(enabled) } : {}),
  }).catch(() => undefined);
});
let lastPublished: string | null = null;

function publishInspection(inspection: ChatGptInspection): void {
  const signature = JSON.stringify([
    inspection.state,
    inspection.conversationId,
    inspection.composerReady,
    inspection.generating,
    inspection.issue?.code ?? null,
    inspection.error,
    inspection.url,
    inspection.assistantOutputTail,
    inspection.assistantOutputTruncated,
  ]);
  if (signature === lastPublished) return;
  lastPublished = signature;
  void browser.runtime.sendMessage({ kind: STATE_KIND, inspection }).catch(() => undefined);
}

adapter.observe(publishInspection, { reconcileIntervalMs: 2_000 });

browser.runtime.onMessage.addListener((unknownMessage: unknown) => {
  const overlayMessage = unknownMessage as Partial<OverlayUpdate>;
  if (overlayMessage.kind === OVERLAY_MESSAGE_KIND) {
    overlay.update(overlayMessage.worker ?? null, overlayMessage.overlayVisible === true);
    return undefined;
  }

  const message = unknownMessage as Partial<ContentRequest>;
  if (message.kind !== CONTENT_KIND) return undefined;

  const execute = async (): Promise<Record<string, unknown>> => {
    try {
      if (message.action === 'inspect') {
        const inspection = adapter.inspect();
        publishInspection(inspection);
        return { ok: true, inspection };
      }
      if (message.action === 'submit' && typeof message.prompt === 'string') {
        await adapter.submitPrompt(message.prompt);
        const inspection = adapter.inspect();
        publishInspection(inspection);
        return { ok: true, inspection };
      }
      if (message.action === 'steer' && typeof message.prompt === 'string') {
        await adapter.submitSteering(message.prompt);
        const inspection = adapter.inspect();
        publishInspection(inspection);
        return { ok: true, inspection };
      }
      if (message.action === 'wait' && typeof message.condition === 'string' && typeof message.timeoutMs === 'number') {
        const inspection = await adapter.waitFor(message.condition, message.timeoutMs);
        publishInspection(inspection);
        return { ok: true, inspection };
      }
      return { ok: false, code: 'INVALID_REQUEST', error: 'Unsupported content-script request.' };
    } catch (error) {
      if (error instanceof HostUiChangedError || error instanceof ChatGptProductStateError) {
        return { ok: false, code: error.code, error: error.message };
      }
      return { ok: false, code: 'INTERNAL_ERROR', error: error instanceof Error ? error.message : 'Unknown content-script error.' };
    }
  };

  return execute();
});
