import type { ClawdbotConfig } from "../../../config/config.js";
import type { RuntimeEnv } from "../../../runtime.js";
import type { AuthChoice, OnboardOptions } from "../../onboard-types.js";
import { upsertAuthProfile } from "../../../agents/auth-profiles.js";
import { normalizeProviderId } from "../../../agents/model-selection.js";
import { parseDurationMs } from "../../../cli/parse-duration.js";
import { upsertSharedEnvVar } from "../../../infra/env-file.js";
import { shortenHomePath } from "../../../utils.js";
import { buildTokenProfileId, validateAnthropicSetupToken } from "../../auth-token.js";
import { applyGoogleGeminiModelDefault } from "../../google-gemini-model-default.js";
import {
  applyAuthProfileConfig,
  applyCloudflareAiGatewayConfig,
  applyKimiCodingConfig,
  applyMinimaxApiConfig,
  applyMinimaxConfig,
  applyMoonshotConfig,
  applyMoonshotCnConfig,
  applyOpencodeZenConfig,
  applyOpenrouterConfig,
  applySyntheticConfig,
  applyVeniceConfig,
  applyVercelAiGatewayConfig,
  applyXiaomiConfig,
  applyZaiConfig,
  setAnthropicApiKey,
  setCloudflareAiGatewayConfig,
  setGeminiApiKey,
  setKimiCodingApiKey,
  setMinimaxApiKey,
  setMoonshotApiKey,
  setOpencodeZenApiKey,
  setOpenrouterApiKey,
  setSyntheticApiKey,
  setVeniceApiKey,
  setVercelAiGatewayApiKey,
  setXiaomiApiKey,
  setZaiApiKey,
  setDashscopeCodingPlanApiKey,
  applyDashscopeCodingPlanConfig,
} from "../../onboard-auth.js";
import { resolveNonInteractiveApiKey } from "../api-keys.js";

export async function applyNonInteractiveAuthChoice(params: {
  nextConfig: ClawdbotConfig;
  authChoice: AuthChoice;
  opts: OnboardOptions;
  runtime: RuntimeEnv;
  baseConfig: ClawdbotConfig;
}): Promise<ClawdbotConfig | null> {
  const { authChoice, opts, runtime, baseConfig } = params;
  let nextConfig = params.nextConfig;

  if (authChoice === "claude-cli" || authChoice === "codex-cli") {
    runtime.error(
      [
        `Auth choice "${authChoice}" is deprecated.`,
        'Use "--auth-choice token" (Anthropic setup-token) or "--auth-choice openai-codex".',
      ].join("\n"),
    );
    runtime.exit(1);
    return null;
  }

  if (authChoice === "setup-token") {
    runtime.error(
      [
        'Auth choice "setup-token" requires interactive mode.',
        'Use "--auth-choice token" with --token and --token-provider anthropic.',
      ].join("\n"),
    );
    runtime.exit(1);
    return null;
  }

  if (authChoice === "dashscope-coding-plan-api-key") {
    const resolved = await resolveNonInteractiveApiKey({
      provider: "dashscope-coding-plan",
      cfg: baseConfig,
      flagValue: opts.dashscopeCodingPlanApiKey,
      flagName: "--dashscope-coding-plan-api-key",
      envVar: "DASHSCOPE_CODING_PLAN_API_KEY",
      runtime,
    });
    if (!resolved) {
      return null;
    }
    if (resolved.source !== "profile") {
      await setDashscopeCodingPlanApiKey(resolved.key);
    }
    nextConfig = applyAuthProfileConfig(nextConfig, {
      profileId: "dashscope-coding-plan:default",
      provider: "dashscope-coding-plan",
      mode: "api_key",
    });
    return applyDashscopeCodingPlanConfig(nextConfig);
  }

  if (authChoice === "apiKey") {
    const resolved = await resolveNonInteractiveApiKey({
      provider: "anthropic",
      cfg: baseConfig,
      flagValue: opts.anthropicApiKey,
      flagName: "--anthropic-api-key",
      envVar: "ANTHROPIC_API_KEY",
      runtime,
    });
    if (!resolved) {
      return null;
    }
    if (resolved.source !== "profile") {
      await setAnthropicApiKey(resolved.key);
    }
    return applyAuthProfileConfig(nextConfig, {
      profileId: "anthropic:default",
      provider: "anthropic",
      mode: "api_key",
    });
  }

  if (authChoice === "token") {
    const providerRaw = opts.tokenProvider?.trim();
    if (!providerRaw) {
      runtime.error("Missing --token-provider for --auth-choice token.");
      runtime.exit(1);
      return null;
    }
    const provider = normalizeProviderId(providerRaw);
    if (provider !== "anthropic") {
      runtime.error("Only --token-provider anthropic is supported for --auth-choice token.");
      runtime.exit(1);
      return null;
    }
    const tokenRaw = opts.token?.trim();
    if (!tokenRaw) {
      runtime.error("Missing --token for --auth-choice token.");
      runtime.exit(1);
      return null;
    }
    const tokenError = validateAnthropicSetupToken(tokenRaw);
    if (tokenError) {
      runtime.error(tokenError);
      runtime.exit(1);
      return null;
    }

    let expires: number | undefined;
    const expiresInRaw = opts.tokenExpiresIn?.trim();
    if (expiresInRaw) {
      try {
        expires = Date.now() + parseDurationMs(expiresInRaw, { defaultUnit: "d" });
      } catch (err) {
        runtime.error(`Invalid --token-expires-in: ${String(err)}`);
        runtime.exit(1);
        return null;
      }
    }

    const profileId = opts.tokenProfileId?.trim() || buildTokenProfileId({ provider, name: "" });
    upsertAuthProfile({
      profileId,
      credential: {
        type: "token",
        provider,
        token: tokenRaw.trim(),
        ...(expires ? { expires } : {}),
      },
    });
    return applyAuthProfileConfig(nextConfig, {
      profileId,
      provider,
      mode: "token",
    });
  }

  if (authChoice === "gemini-api-key") {
    const resolved = await resolveNonInteractiveApiKey({
      provider: "google",
      cfg: baseConfig,
      flagValue: opts.geminiApiKey,
      flagName: "--gemini-api-key",
      envVar: "GEMINI_API_KEY",
      runtime,
    });
    if (!resolved) {
      return null;
    }
    if (resolved.source !== "profile") {
      await setGeminiApiKey(resolved.key);
    }
    nextConfig = applyAuthProfileConfig(nextConfig, {
      profileId: "google:default",
      provider: "google",
      mode: "api_key",
    });
    return applyGoogleGeminiModelDefault(nextConfig).next;
  }

  if (authChoice === "zai-api-key") {
    const resolved = await resolveNonInteractiveApiKey({
      provider: "zai",
      cfg: baseConfig,
      flagValue: opts.zaiApiKey,
      flagName: "--zai-api-key",
      envVar: "ZAI_API_KEY",
      runtime,
    });
    if (!resolved) {
      return null;
    }
    if (resolved.source !== "profile") {
      await setZaiApiKey(resolved.key);
    }
    nextConfig = applyAuthProfileConfig(nextConfig, {
      profileId: "zai:default",
      provider: "zai",
      mode: "api_key",
    });
    return applyZaiConfig(nextConfig);
  }

  if (authChoice === "xiaomi-api-key") {
    const resolved = await resolveNonInteractiveApiKey({
      provider: "xiaomi",
      cfg: baseConfig,
      flagValue: opts.xiaomiApiKey,
      flagName: "--xiaomi-api-key",
      envVar: "XIAOMI_API_KEY",
      runtime,
    });
    if (!resolved) {
      return null;
    }
    if (resolved.source !== "profile") {
      await setXiaomiApiKey(resolved.key);
    }
    nextConfig = applyAuthProfileConfig(nextConfig, {
      profileId: "xiaomi:default",
      provider: "xiaomi",
      mode: "api_key",
    });
    return applyXiaomiConfig(nextConfig);
  }

  if (authChoice === "openai-api-key") {
    const resolved = await resolveNonInteractiveApiKey({
      provider: "openai",
      cfg: baseConfig,
      flagValue: opts.openaiApiKey,
      flagName: "--openai-api-key",
      envVar: "OPENAI_API_KEY",
      runtime,
      allowProfile: false,
    });
    if (!resolved) {
      return null;
    }
    const key = resolved.key;
    const result = upsertSharedEnvVar({ key: "OPENAI_API_KEY", value: key });
    process.env.OPENAI_API_KEY = key;
    runtime.log(`Saved OPENAI_API_KEY to ${shortenHomePath(result.path)}`);
    return nextConfig;
  }

  if (authChoice === "openrouter-api-key") {
    const resolved = await resolveNonInteractiveApiKey({
      provider: "openrouter",
      cfg: baseConfig,
      flagValue: opts.openrouterApiKey,
      flagName: "--openrouter-api-key",
      envVar: "OPENROUTER_API_KEY",
      runtime,
    });
    if (!resolved) {
      return null;
    }
    if (resolved.source !== "profile") {
      await setOpenrouterApiKey(resolved.key);
    }
    nextConfig = applyAuthProfileConfig(nextConfig, {
      profileId: "openrouter:default",
      provider: "openrouter",
      mode: "api_key",
    });
    return applyOpenrouterConfig(nextConfig);
  }

  if (authChoice === "ai-gateway-api-key") {
    const resolved = await resolveNonInteractiveApiKey({
      provider: "vercel-ai-gateway",
      cfg: baseConfig,
      flagValue: opts.aiGatewayApiKey,
      flagName: "--ai-gateway-api-key",
      envVar: "AI_GATEWAY_API_KEY",
      runtime,
    });
    if (!resolved) {
      return null;
    }
    if (resolved.source !== "profile") {
      await setVercelAiGatewayApiKey(resolved.key);
    }
    nextConfig = applyAuthProfileConfig(nextConfig, {
      profileId: "vercel-ai-gateway:default",
      provider: "vercel-ai-gateway",
      mode: "api_key",
    });
    return applyVercelAiGatewayConfig(nextConfig);
  }

  if (authChoice === "cloudflare-ai-gateway-api-key") {
    const accountId = opts.cloudflareAiGatewayAccountId?.trim() ?? "";
    const gatewayId = opts.cloudflareAiGatewayGatewayId?.trim() ?? "";
    if (!accountId || !gatewayId) {
      runtime.error(
        [
          'Auth choice "cloudflare-ai-gateway-api-key" requires Account ID and Gateway ID.',
          "Use --cloudflare-ai-gateway-account-id and --cloudflare-ai-gateway-gateway-id.",
        ].join("\n"),
      );
      runtime.exit(1);
      return null;
    }
    const resolved = await resolveNonInteractiveApiKey({
      provider: "cloudflare-ai-gateway",
      cfg: baseConfig,
      flagValue: opts.cloudflareAiGatewayApiKey,
      flagName: "--cloudflare-ai-gateway-api-key",
      envVar: "CLOUDFLARE_AI_GATEWAY_API_KEY",
      runtime,
    });
    if (!resolved) {
      return null;
    }
    if (resolved.source !== "profile") {
      await setCloudflareAiGatewayConfig(accountId, gatewayId, resolved.key);
    }
    nextConfig = applyAuthProfileConfig(nextConfig, {
      profileId: "cloudflare-ai-gateway:default",
      provider: "cloudflare-ai-gateway",
      mode: "api_key",
    });
    return applyCloudflareAiGatewayConfig(nextConfig, {
      accountId,
      gatewayId,
    });
  }

  if (authChoice === "moonshot-api-key") {
    const resolved = await resolveNonInteractiveApiKey({
      provider: "moonshot",
      cfg: baseConfig,
      flagValue: opts.moonshotApiKey,
      flagName: "--moonshot-api-key",
      envVar: "MOONSHOT_API_KEY",
      runtime,
    });
    if (!resolved) {
      return null;
    }
    if (resolved.source !== "profile") {
      await setMoonshotApiKey(resolved.key);
    }
    nextConfig = applyAuthProfileConfig(nextConfig, {
      profileId: "moonshot:default",
      provider: "moonshot",
      mode: "api_key",
    });
    return applyMoonshotConfig(nextConfig);
  }

  if (authChoice === "moonshot-api-key-cn") {
    const resolved = await resolveNonInteractiveApiKey({
      provider: "moonshot",
      cfg: baseConfig,
      flagValue: opts.moonshotApiKey,
      flagName: "--moonshot-api-key",
      envVar: "MOONSHOT_API_KEY",
      runtime,
    });
    if (!resolved) {
      return null;
    }
    if (resolved.source !== "profile") {
      await setMoonshotApiKey(resolved.key);
    }
    nextConfig = applyAuthProfileConfig(nextConfig, {
      profileId: "moonshot:default",
      provider: "moonshot",
      mode: "api_key",
    });
    return applyMoonshotCnConfig(nextConfig);
  }

  if (authChoice === "kimi-code-api-key") {
    const resolved = await resolveNonInteractiveApiKey({
      provider: "kimi-coding",
      cfg: baseConfig,
      flagValue: opts.kimiCodeApiKey,
      flagName: "--kimi-code-api-key",
      envVar: "KIMI_API_KEY",
      runtime,
    });
    if (!resolved) {
      return null;
    }
    if (resolved.source !== "profile") {
      await setKimiCodingApiKey(resolved.key);
    }
    nextConfig = applyAuthProfileConfig(nextConfig, {
      profileId: "kimi-coding:default",
      provider: "kimi-coding",
      mode: "api_key",
    });
    return applyKimiCodingConfig(nextConfig);
  }

  if (authChoice === "synthetic-api-key") {
    const resolved = await resolveNonInteractiveApiKey({
      provider: "synthetic",
      cfg: baseConfig,
      flagValue: opts.syntheticApiKey,
      flagName: "--synthetic-api-key",
      envVar: "SYNTHETIC_API_KEY",
      runtime,
    });
    if (!resolved) {
      return null;
    }
    if (resolved.source !== "profile") {
      await setSyntheticApiKey(resolved.key);
    }
    nextConfig = applyAuthProfileConfig(nextConfig, {
      profileId: "synthetic:default",
      provider: "synthetic",
      mode: "api_key",
    });
    return applySyntheticConfig(nextConfig);
  }

  if (authChoice === "venice-api-key") {
    const resolved = await resolveNonInteractiveApiKey({
      provider: "venice",
      cfg: baseConfig,
      flagValue: opts.veniceApiKey,
      flagName: "--venice-api-key",
      envVar: "VENICE_API_KEY",
      runtime,
    });
    if (!resolved) {
      return null;
    }
    if (resolved.source !== "profile") {
      await setVeniceApiKey(resolved.key);
    }
    nextConfig = applyAuthProfileConfig(nextConfig, {
      profileId: "venice:default",
      provider: "venice",
      mode: "api_key",
    });
    return applyVeniceConfig(nextConfig);
  }

  if (
    authChoice === "minimax-cloud" ||
    authChoice === "minimax-api" ||
    authChoice === "minimax-api-lightning" ||
    authChoice === "minimax-api-m25" ||
    authChoice === "minimax-api-m25-highspeed" ||
    authChoice === "minimax-api-m21-highspeed" ||
    authChoice === "minimax-api-m2"
  ) {
    const resolved = await resolveNonInteractiveApiKey({
      provider: "minimax",
      cfg: baseConfig,
      flagValue: opts.minimaxApiKey,
      flagName: "--minimax-api-key",
      envVar: "MINIMAX_API_KEY",
      runtime,
    });
    if (!resolved) {
      return null;
    }
    if (resolved.source !== "profile") {
      await setMinimaxApiKey(resolved.key);
    }
    nextConfig = applyAuthProfileConfig(nextConfig, {
      profileId: "minimax:default",
      provider: "minimax",
      mode: "api_key",
    });
    const modelIdMap: Record<string, string> = {
      "minimax-api-m25": "MiniMax-M2.5",
      "minimax-api-m25-highspeed": "MiniMax-M2.5-highspeed",
      "minimax-api-lightning": "MiniMax-M2.1-lightning",
      "minimax-api": "MiniMax-M2.1",
      "minimax-api-m21-highspeed": "MiniMax-M2.1-highspeed",
      "minimax-api-m2": "MiniMax-M2",
      "minimax-cloud": "MiniMax-M2.1",
    };
    const modelId = modelIdMap[authChoice] ?? "MiniMax-M2.1";
    return applyMinimaxApiConfig(nextConfig, modelId);
  }

  if (authChoice === "minimax") {
    return applyMinimaxConfig(nextConfig);
  }

  if (authChoice === "opencode-zen") {
    const resolved = await resolveNonInteractiveApiKey({
      provider: "opencode",
      cfg: baseConfig,
      flagValue: opts.opencodeZenApiKey,
      flagName: "--opencode-zen-api-key",
      envVar: "OPENCODE_API_KEY (or OPENCODE_ZEN_API_KEY)",
      runtime,
    });
    if (!resolved) {
      return null;
    }
    if (resolved.source !== "profile") {
      await setOpencodeZenApiKey(resolved.key);
    }
    nextConfig = applyAuthProfileConfig(nextConfig, {
      profileId: "opencode:default",
      provider: "opencode",
      mode: "api_key",
    });
    return applyOpencodeZenConfig(nextConfig);
  }

  if (
    authChoice === "oauth" ||
    authChoice === "chutes" ||
    authChoice === "openai-codex" ||
    authChoice === "qwen-portal" ||
    authChoice === "minimax-portal"
  ) {
    runtime.error("OAuth requires interactive mode.");
    runtime.exit(1);
    return null;
  }

  return nextConfig;
}
