/**
 * TokenExtractionConfig — Login & cookie extraction configs for web-cookie providers
 *
 * Each config describes how to:
 *   1. Open a browser window/navigate to the provider's login page
 *   2. Detect successful login (URL change + token presence)
 *   3. Extract session cookies / tokens from the browser context
 *
 * Used by InAppLoginService (Electron BrowserWindow path) and
 * the Playwright-based login flow (dashboard API).
 */

// ─── Types ──────────────────────────────────────────────────────────────────

/** Describes where to extract credential data from after login */
export type TokenSource =
  | { type: "cookie"; name: string; domain?: string }
  | { type: "localStorage"; key: string }
  | { type: "sessionStorage"; key: string }
  | { type: "header"; name: string };

export interface PollingConfig {
  /** Milliseconds between extraction polls (default 1000) */
  pollInterval: number;
  /** Total timeout in ms (default 300000 = 5 min) */
  timeout: number;
  /** Minimum time in ms before first extraction attempt (default 5000) */
  minLoginTime: number;
}

export interface TokenExtractionConfig {
  /** Matches the executor's provider ID (e.g. "claude-web", "gemini-web") */
  providerId: string;
  /** Human-readable name shown in dashboard UI */
  displayName: string;
  /** The URL to navigate to for login */
  loginUrl: string;
  /** The provider's home page URL (for cookie domain binding) */
  homeUrl: string;
  /** Optional regex. If current URL matches → login is likely complete */
  successUrlPattern?: RegExp;
  /** Sources to extract credentials from after login */
  tokenSources: TokenSource[];
  /** Polling behaviour */
  pollingConfig: PollingConfig;
  /** Short instructions shown to the user in the login modal */
  instructions: string;
  /** Optional: cookie domain override for cookie injection */
  cookieDomain?: string;
}

// ─── Defaults ───────────────────────────────────────────────────────────────

const DEFAULT_POLLING: PollingConfig = {
  pollInterval: 1000,
  timeout: 300_000,
  minLoginTime: 5000,
};

const QUICK_POLLING: PollingConfig = {
  pollInterval: 800,
  timeout: 120_000,
  minLoginTime: 3000,
};

// ─── Helper ──────────────────────────────────────────────────────────────────

function config(
  providerId: string,
  displayName: string,
  loginUrl: string,
  homeUrl: string,
  tokenSources: TokenSource[],
  instructions: string,
  opts?: {
    successUrlPattern?: RegExp;
    pollingConfig?: Partial<PollingConfig>;
    cookieDomain?: string;
  }
): TokenExtractionConfig {
  return {
    providerId,
    displayName,
    loginUrl,
    homeUrl,
    tokenSources,
    instructions,
    pollingConfig: { ...DEFAULT_POLLING, ...opts?.pollingConfig },
    successUrlPattern: opts?.successUrlPattern,
    cookieDomain: opts?.cookieDomain,
  };
}

// ─── Configuration Map ──────────────────────────────────────────────────────

const RAW_CONFIGS: TokenExtractionConfig[] = [
  // ── Claude Web ────────────────────────────────────────────
  config(
    "claude-web",
    "Claude Web",
    "https://claude.ai/login",
    "https://claude.ai",
    [{ type: "cookie", name: "sessionKey", domain: ".claude.ai" }],
    "Log in to your Claude account at claude.ai. After login, the session cookie will be extracted automatically."
  ),

  // ── ChatGPT Web ───────────────────────────────────────────
  config(
    "chatgpt-web",
    "ChatGPT Web",
    "https://chatgpt.com/auth/login",
    "https://chatgpt.com",
    [
      { type: "cookie", name: "__Secure-next-auth.session-token", domain: ".chatgpt.com" },
    ],
    "Log in to ChatGPT. The __Secure-next-auth.session-token cookie will be extracted after login."
  ),

  // ── Gemini Web ────────────────────────────────────────────
  config(
    "gemini-web",
    "Gemini Web",
    "https://gemini.google.com/app",
    "https://gemini.google.com",
    [
      { type: "cookie", name: "__Secure-1PSID", domain: ".google.com" },
      { type: "cookie", name: "__Secure-1PSIDTS", domain: ".google.com" },
    ],
    "Log in to your Google account at gemini.google.com. Both __Secure-1PSID and __Secure-1PSIDTS cookies will be extracted.",
    { cookieDomain: ".google.com" }
  ),

  // ── Grok Web ──────────────────────────────────────────────
  config(
    "grok-web",
    "Grok Web",
    "https://grok.com/login",
    "https://grok.com",
    [{ type: "cookie", name: "sso", domain: ".grok.com" }],
    "Log in to your xAI account at grok.com. The sso session cookie will be extracted."
  ),

  // ── Perplexity Web ────────────────────────────────────────
  config(
    "perplexity-web",
    "Perplexity Web",
    "https://www.perplexity.ai/login",
    "https://www.perplexity.ai",
    [
      { type: "cookie", name: "__Secure-next-auth.session-token", domain: ".perplexity.ai" },
    ],
    "Log in to Perplexity. The __Secure-next-auth.session-token cookie will be extracted.",
    { cookieDomain: ".perplexity.ai" }
  ),

  // ── DeepSeek Web ──────────────────────────────────────────
  config(
    "deepseek-web",
    "DeepSeek Web",
    "https://chat.deepseek.com/sign_in",
    "https://chat.deepseek.com",
    [
      { type: "cookie", name: "user-token", domain: ".deepseek.com" },
      { type: "localStorage", key: "userToken" },
    ],
    "Log in to DeepSeek at chat.deepseek.com. The user-token cookie will be extracted.",
    { cookieDomain: ".deepseek.com" }
  ),

  // ── Qwen Web ──────────────────────────────────────────────
  config(
    "qwen-web",
    "Qwen Web (Tongyi)",
    "https://chat.qwen.ai/",
    "https://chat.qwen.ai",
    [
      { type: "cookie", name: "XSRF_TOKEN", domain: ".chat.qwen.ai" },
      { type: "localStorage", key: "token" },
    ],
    "Log in to Qwen at chat.qwen.ai using your Alibaba account. The session token will be extracted.",
    { cookieDomain: ".chat.qwen.ai" }
  ),

  // ── Kimi Web ──────────────────────────────────────────────
  config(
    "kimi-web",
    "Kimi (Moonshot)",
    "https://kimi.moonshot.cn/",
    "https://kimi.moonshot.cn",
    [
      { type: "cookie", name: "kimi_token", domain: ".kimi.moonshot.cn" },
      { type: "localStorage", key: "kimi_token" },
    ],
    "Log in to Kimi at kimi.moonshot.cn via phone/WeChat. The session token will be extracted.",
    { cookieDomain: ".kimi.moonshot.cn" }
  ),

  // ── Blackbox Web ──────────────────────────────────────────
  config(
    "blackbox-web",
    "Blackbox AI",
    "https://app.blackbox.ai/login",
    "https://app.blackbox.ai",
    [
      { type: "cookie", name: "connect.sid", domain: ".blackbox.ai" },
      { type: "localStorage", key: "token" },
    ],
    "Log in to Blackbox AI at app.blackbox.ai using Google/GitHub. The session cookie will be extracted.",
    { cookieDomain: ".blackbox.ai" }
  ),

  // ── Poe Web ───────────────────────────────────────────────
  config(
    "poe-web",
    "Poe (Quora)",
    "https://poe.com/login",
    "https://poe.com",
    [
      { type: "cookie", name: "p-b", domain: ".poe.com" },
    ],
    "Log in to Poe at poe.com. The session cookie will be extracted.",
    { cookieDomain: ".poe.com" }
  ),

  // ── Copilot Web ───────────────────────────────────────────
  config(
    "copilot-web",
    "Microsoft Copilot",
    "https://copilot.microsoft.com/",
    "https://copilot.microsoft.com",
    [
      { type: "cookie", name: "RPSCAuth", domain: ".microsoft.com" },
    ],
    "Log in with your Microsoft account at copilot.microsoft.com. The session auth cookie will be extracted.",
    { cookieDomain: ".microsoft.com" }
  ),

  // ── DuckDuckGo Web ────────────────────────────────────────
  config(
    "duckduckgo-web",
    "DuckDuckGo AI Chat",
    "https://duckduckgo.com/?q=DuckDuckGo+AI+Chat&ia=chat&duckai=1",
    "https://duckduckgo.com",
    [
      { type: "cookie", name: "duckai", domain: ".duckduckgo.com" },
    ],
    "Open DuckDuckGo AI Chat. Some models may require a free account. The duckai cookie will be extracted.",
    {
      cookieDomain: ".duckduckgo.com",
      pollingConfig: QUICK_POLLING,
    }
  ),

  // ── DouBao Web ────────────────────────────────────────────
  config(
    "doubao-web",
    "DouBao (ByteDance)",
    "https://www.doubao.com/",
    "https://www.doubao.com",
    [
      { type: "cookie", name: "sessionid", domain: ".doubao.com" },
    ],
    "Log in to DouBao at doubao.com with your ByteDance account. The sessionid will be extracted.",
    { cookieDomain: ".doubao.com" }
  ),

  // ── T3 Chat Web ───────────────────────────────────────────
  config(
    "t3-chat-web",
    "T3 Chat",
    "https://t3.chat/login",
    "https://t3.chat",
    [
      { type: "localStorage", key: "token" },
    ],
    "Log in to T3 Chat at t3.chat using Google/GitHub. The token from localStorage will be extracted.",
    { pollingConfig: QUICK_POLLING }
  ),

  // ── Venice Web ────────────────────────────────────────────
  config(
    "venice-web",
    "Venice AI",
    "https://venice.ai/login",
    "https://venice.ai",
    [
      { type: "cookie", name: "venice_session", domain: ".venice.ai" },
      { type: "localStorage", key: "token" },
    ],
    "Log in to Venice AI at venice.ai. The session cookie will be extracted.",
    { cookieDomain: ".venice.ai" }
  ),

  // ── v0 Dev Web ────────────────────────────────────────────
  config(
    "v0-vercel-web",
    "v0 by Vercel",
    "https://v0.dev/login",
    "https://v0.dev",
    [
      { type: "cookie", name: "__Secure-next-auth.session-token", domain: ".v0.dev" },
    ],
    "Log in to v0.dev with your Vercel/Google/GitHub account. The session cookie will be extracted.",
    { cookieDomain: ".v0.dev" }
  ),

  // ── Muse / Spark Web ──────────────────────────────────────
  config(
    "muse-spark-web",
    "Meta AI (Muse)",
    "https://www.meta.ai/",
    "https://www.meta.ai",
    [
      { type: "cookie", name: "session", domain: ".meta.ai" },
    ],
    "Log in to Meta AI at meta.ai with your Facebook/Instagram account. The session cookie will be extracted.",
    { cookieDomain: ".meta.ai" }
  ),

  // ── Adapta Web ────────────────────────────────────────────
  config(
    "adapta-web",
    "Adapta AI",
    "https://agent.adapta.one/login",
    "https://agent.adapta.one",
    [
      { type: "cookie", name: "__session", domain: ".adapta.one" },
    ],
    "Log in to Adapta at agent.adapta.one. The session token will be extracted.",
    { cookieDomain: ".adapta.one" }
  ),

  // ── VeoAI Free Web ────────────────────────────────────────
  config(
    "veoaifree-web",
    "VeoAI Free",
    "https://veoaifree.com/",
    "https://veoaifree.com",
    [
      { type: "cookie", name: "wordpress_logged_in", domain: ".veoaifree.com" },
    ],
    "Log in to VeoAI Free at veoaifree.com. The WordPress session cookie will be extracted.",
    {
      cookieDomain: ".veoaifree.com",
      pollingConfig: QUICK_POLLING,
    }
  ),

  // ── Missing Provider: ChatGLM (Zhipu) ──────────────────────
  config(
    "chatglm-web",
    "ChatGLM (Zhipu AI)",
    "https://chatglm.cn/",
    "https://chatglm.cn",
    [
      { type: "cookie", name: "chatglm_session", domain: ".chatglm.cn" },
      { type: "localStorage", key: "token" },
    ],
    "Log in to ChatGLM at chatglm.cn with your phone number. The session token will be extracted.",
    { cookieDomain: ".chatglm.cn" }
  ),

  // ── Missing Provider: Xiaomi MiMo ──────────────────────────
  config(
    "xiaomimimo-web",
    "Xiaomi MiMo AI Studio",
    "https://aistudio.xiaomimimo.com/login",
    "https://aistudio.xiaomimimo.com",
    [
      { type: "cookie", name: "session", domain: ".xiaomimimo.com" },
      { type: "localStorage", key: "access_token" },
    ],
    "Log in to Xiaomi MiMo AI Studio at aistudio.xiaomimimo.com. The session token will be extracted.",
    { cookieDomain: ".xiaomimimo.com" }
  ),

  // ── Missing Provider: Manus ────────────────────────────────
  config(
    "manus-web",
    "Manus AI",
    "https://manus.im/login",
    "https://manus.im",
    [
      { type: "cookie", name: "manus_session", domain: ".manus.im" },
      { type: "localStorage", key: "auth_token" },
    ],
    "Log in to Manus at manus.im. The session cookie will be extracted.",
    { cookieDomain: ".manus.im" }
  ),
];

// ─── Registry ───────────────────────────────────────────────────────────────

const CONFIG_MAP = new Map<string, TokenExtractionConfig>();

for (const cfg of RAW_CONFIGS) {
  CONFIG_MAP.set(cfg.providerId, cfg);
}

/** Get extraction config for a specific provider */
export function getExtractionConfig(providerId: string): TokenExtractionConfig | undefined {
  return CONFIG_MAP.get(providerId);
}

/** List all registered extraction configs */
export function listExtractionConfigs(): TokenExtractionConfig[] {
  return [...RAW_CONFIGS];
}

/** The shared config map — used by LoginManager and InAppLoginService */
export const TOKEN_EXTRACTION_CONFIGS = CONFIG_MAP;
