import type { FieldDefinition } from '../domain/types';
import type { OnlyOfficeBridge } from '../onlyoffice/bridge';

import { useAnnotationStore } from '../stores/annotation';
import { usePluginContextStore } from '../stores/plugin-context';

const SDK_READY_TIMEOUT_MS = 5_000;

function errorMessage(error: unknown): string {
  return error instanceof Error ? error.message : String(error);
}

export function useTemplateAnnotator(bridge: OnlyOfficeBridge) {
  const store = useAnnotationStore();
  const contextStore = usePluginContextStore();
  let disposed = false;
  let inFlight = false;
  let readyTimeout: ReturnType<typeof setTimeout> | undefined;

  function clearReadyTimeout(): void {
    if (readyTimeout === undefined) return;
    clearTimeout(readyTimeout);
    readyTimeout = undefined;
  }

  async function runExclusive<T>(operation: () => Promise<T>): Promise<T> {
    if (inFlight) {
      throw new Error('已有操作正在执行');
    }

    inFlight = true;
    try {
      return await operation();
    } finally {
      inFlight = false;
    }
  }

  function setWorking(status: 'initializing' | 'working', message: string): void {
    if (disposed) return;
    store.setStatus(status);
    store.setOperation({ kind: 'working', message });
  }

  function initialize(): Promise<void> {
    clearReadyTimeout();
    return runExclusive(async () => {
      setWorking('initializing', '正在读取文档字段...');
      try {
        await bridge.disableTrackRevisions();
        const controls = await bridge.listControls();
        if (disposed) return;
        store.setControls(controls);
        store.setStatus('ready');
        store.setOperation({ kind: 'success', message: '文档字段已刷新' });
      } catch (error: unknown) {
        if (!disposed) {
          store.setStatus('error');
          store.setOperation({ kind: 'error', message: `读取内容控件失败：${errorMessage(error)}` });
        }
        throw error;
      }
    });
  }

  function refresh(): Promise<void> {
    return runExclusive(async () => {
      const wasFatal = store.status === 'error';
      setWorking('working', '正在读取文档字段...');
      try {
        const controls = await bridge.listControls();
        if (disposed) return;
        store.setControls(controls);
        store.setStatus('ready');
        store.setOperation({ kind: 'success', message: '文档字段已刷新' });
      } catch (error: unknown) {
        if (!disposed) {
          store.setStatus(wasFatal ? 'error' : 'ready');
          store.setOperation({ kind: 'error', message: `读取内容控件失败：${errorMessage(error)}` });
        }
        throw error;
      }
    });
  }

  function insert(definition: FieldDefinition): Promise<void> {
    return runExclusive(async () => {
      setWorking('working', '正在标注当前位置...');
      try {
        const controls = await bridge.insertField(definition);
        if (disposed) return;
        store.setControls(controls);
        store.setStatus('ready');
        store.setOperation({ kind: 'success', message: `已创建字段：${definition.alias}` });
      } catch (error: unknown) {
        if (!disposed) {
          store.setStatus('ready');
          store.setOperation({ kind: 'error', message: `标注失败：${errorMessage(error)}` });
        }
        throw error;
      }
    });
  }

  function deleteControl(internalId: string): Promise<void> {
    return runExclusive(async () => {
      setWorking('working', '正在解除标注...');
      try {
        const controls = await bridge.deleteControl(internalId);
        if (disposed) return;
        store.setControls(controls);
        store.setStatus('ready');
        store.setOperation({ kind: 'success', message: '标注已解除' });
      } catch (error: unknown) {
        if (!disposed) {
          store.setStatus('ready');
          store.setOperation({ kind: 'error', message: `解除标注失败：${errorMessage(error)}` });
        }
        throw error;
      }
    });
  }

  function select(internalId: string): Promise<void> {
    return runExclusive(async () => {
      try {
        await bridge.selectControl(internalId);
      } catch (error: unknown) {
        try {
          const controls = await bridge.listControls();
          if (!disposed) store.setControls(controls);
        } catch {
          // 定位错误是本次操作的主错误，补偿刷新不能替换它。
        }
        if (!disposed) {
          store.setStatus('ready');
          store.setOperation({ kind: 'error', message: `定位失败：${errorMessage(error)}` });
        }
        throw error;
      }
    });
  }

  const cleanup = bridge.bindLifecycle({
    onReady: () => {
      if (disposed) return;
      if (!contextStore.initialize(bridge.getRuntimeOptions())) {
        store.setStatus('error');
        store.setOperation({ kind: 'error', message: contextStore.error });
        return;
      }
      void initialize().catch(() => undefined);
    },
    onThemeChanged: () => undefined,
  });
  readyTimeout = setTimeout(() => {
    readyTimeout = undefined;
    if (disposed || store.status !== 'initializing') return;
    store.setStatus('error');
    store.setOperation({ kind: 'error', message: 'ONLYOFFICE SDK 初始化超时' });
  }, SDK_READY_TIMEOUT_MS);

  function dispose(): void {
    if (disposed) return;
    disposed = true;
    clearReadyTimeout();
    cleanup();
    contextStore.reset();
  }

  return { contextStore, store, initialize, refresh, insert, deleteControl, select, dispose };
}
