import { apiRequest, loadTokens } from "../data/live/http";

export type ExtensionSyncResult = {
  success?: boolean;
  valid?: boolean;
  synced?: boolean;
  message?: string;
  username?: string;
  account_id?: string;
};

export function isExtensionBridgePresent() {
  return document.documentElement.dataset.haixunExtension === "1";
}

export function normalizeExtensionSyncResult(raw: ExtensionSyncResult): ExtensionSyncResult {
  const nested =
    raw && typeof (raw as { data?: ExtensionSyncResult }).data === "object"
      ? ((raw as { data?: ExtensionSyncResult }).data as ExtensionSyncResult)
      : null;

  const payload = nested ?? raw;
  return {
    success: payload.success !== false,
    valid: payload.valid !== false,
    synced: payload.synced ?? true,
    message: payload.message,
    username: payload.username,
    account_id: payload.account_id,
  };
}

export function pingExtensionBridge() {
  window.postMessage({ type: "HAIXUN_PING_EXTENSION" }, "*");
}

export function waitForExtensionBridge(timeoutMs = 8000): Promise<boolean> {
  if (isExtensionBridgePresent()) return Promise.resolve(true);

  return new Promise((resolve) => {
    const started = Date.now();

    const onMessage = (event: MessageEvent) => {
      if (event.source !== window) return;
      if (event.data?.type !== "HAIXUN_EXTENSION_READY") return;
      cleanup();
      resolve(true);
    };

    const timer = window.setInterval(() => {
      pingExtensionBridge();
      if (isExtensionBridgePresent()) {
        cleanup();
        resolve(true);
        return;
      }
      if (Date.now() - started >= timeoutMs) {
        cleanup();
        resolve(false);
      }
    }, 500);

    function cleanup() {
      window.removeEventListener("message", onMessage);
      window.clearInterval(timer);
    }

    window.addEventListener("message", onMessage);
    pingExtensionBridge();
  });
}

/** 請擴充只收集 Playwright storageState（cookies），不上傳 API */
function requestExtensionCollect(timeoutMs = 30000): Promise<string> {
  return new Promise((resolve, reject) => {
    if (!isExtensionBridgePresent()) {
      reject(
        new Error(
          "找不到巡樓 Chrome 擴充。請到 chrome://extensions 重新載入擴充後 F5 此頁。",
        ),
      );
      return;
    }

    const timeout = window.setTimeout(() => {
      window.removeEventListener("message", onMessage);
      reject(new Error("等待擴充收集 cookies 逾時。請重新載入擴充後再試。"));
    }, timeoutMs);

    function onMessage(event: MessageEvent) {
      if (event.source !== window) return;
      if (event.data?.type !== "HAIXUN_THREADS_COLLECT_RESULT") return;
      window.clearTimeout(timeout);
      window.removeEventListener("message", onMessage);
      const data = event.data as {
        success?: boolean;
        storageState?: string;
        message?: string;
      };
      if (data.success === false || !data.storageState) {
        reject(new Error(data.message || "擴充未能收集 Threads cookies"));
        return;
      }
      resolve(String(data.storageState));
    }

    window.addEventListener("message", onMessage);
    window.postMessage({ type: "HAIXUN_REQUEST_THREADS_COLLECT" }, "*");
  });
}

/**
 * 設定頁推薦流程：
 * 1) 擴充只收集 Threads cookies（storageState）
 * 2) 網頁用目前登入 JWT 呼叫 /api/v1/scout/crawler-session
 * 避免擴充帶錯／漏帶 token 造成 HTTP 401。
 */
export async function requestExtensionSync(input?: {
  accountId?: string;
  serverUrl?: string;
  accessToken?: string;
}): Promise<ExtensionSyncResult> {
  if (!loadTokens()?.access_token && !input?.accessToken?.trim()) {
    throw new Error("尚未登入巡樓，請先登入後再同步 Chrome session。");
  }

  const ready = isExtensionBridgePresent() || (await waitForExtensionBridge(4000));
  if (!ready) {
    throw new Error(
      "找不到巡樓 Chrome 擴充。請到 chrome://extensions 重新載入後 F5；選項網址須與此分頁一致。",
    );
  }

  const storageState = await requestExtensionCollect();

  // 網頁帶 JWT 上傳（會自動 refresh on 401）
  await apiRequest<{ ok?: boolean }>("/api/v1/scout/crawler-session", {
    method: "POST",
    body: { token: storageState },
  });

  // 若有經營帳號 id，一併寫舊路徑（相容／後端會再存一次 crawler session）
  const accountId = input?.accountId?.trim() || "";
  if (accountId) {
    try {
      await apiRequest(`/api/v1/threads-accounts/${encodeURIComponent(accountId)}/session/import`, {
        method: "POST",
        body: { storageState },
      });
    } catch {
      // crawler-session 已成功即可
    }
  }

  return {
    success: true,
    valid: true,
    synced: true,
    message: "",
    account_id: accountId || undefined,
  };
}
