"use client";

import {
  CheckCircle2,
  KeyRound,
  PlugZap,
  Route,
  Save,
  XCircle,
  type LucideIcon,
} from "lucide-react";
import { useState, type ReactNode } from "react";

import { useToast } from "@/components/Toast";
import { KimiCodeOauth } from "@/components/settings/KimiCodeOauth";
import { Badge } from "@/components/ui/Badge";
import { Button } from "@/components/ui/Button";
import { EmptyState } from "@/components/ui/EmptyState";
import { SectionHeader } from "@/components/ui/SectionHeader";
import { SegmentedControl } from "@/components/ui/SegmentedControl";
import { Select } from "@/components/ui/Select";
import { StatusNote } from "@/components/ui/StatusNote";
import { TextInput } from "@/components/ui/TextInput";
import { api } from "@/lib/api/client";
import { cardClass } from "@/lib/ui/variants";
import {
  API_KEY_PROVIDERS,
  KNOWN_PROVIDERS,
  TIER_LABELS,
  applyProviderChange,
  draftsToRoutingInput,
  toRoutingDrafts,
  type RoutingDraft,
} from "@/lib/settings/providers";
import type {
  CapabilitiesView,
  ProvidersResponse,
} from "@/lib/api/types";

interface ProvidersSettingsProps {
  initial: ProvidersResponse;
  // Kimi Code OAuth 连接态（GET .../oauth/status，进页 Server Component 取）。
  kimiOauth: { connected: boolean; expiresAt: string | null };
}

interface TestResult {
  ok: boolean;
  capabilities: CapabilitiesView;
}

type SettingsSection = "routing" | "oauth" | "keys";

// 分组的单一标签源：桌面 aside 与移动 SegmentedControl 共用，消除「档位路由 / 路由」漂移。
const SETTINGS_SECTIONS: Array<{
  value: SettingsSection;
  label: string;
  icon: LucideIcon;
}> = [
  { value: "routing", label: "档位路由", icon: Route },
  { value: "oauth", label: "OAuth", icon: PlugZap },
  { value: "keys", label: "API Key", icon: KeyRound },
];

const SECTION_OPTIONS = SETTINGS_SECTIONS.map(({ value, label }) => ({
  value,
  label,
}));

// 档位路由「模型」输入框的候选 model id（datalist 建议，仍可自由输入）。按 provider 分组。
const MODEL_SUGGESTIONS: Record<string, readonly string[]> = {
  anthropic: ["claude-opus-4", "claude-sonnet-4", "claude-3-5-haiku"],
  deepseek: ["deepseek-chat", "deepseek-reasoner"],
  kimi: ["moonshot-v1-128k", "moonshot-v1-32k", "kimi-k2"],
  openai: ["gpt-4o", "gpt-4o-mini", "o3-mini"],
  qwen: ["qwen-max", "qwen-plus", "qwen-turbo"],
  glm: ["glm-4-plus", "glm-4-air", "glm-4-flash"],
  gemini: ["gemini-2.0-flash", "gemini-1.5-pro"],
  "kimi-code-key": ["kimi-for-coding"],
  "kimi-code": ["kimi-for-coding"],
};

// 设置页主体（UX §6.10）：档位路由（可编辑）+ API-key 凭据行 + Kimi Code OAuth 连接区。
export function ProvidersSettings({
  initial,
  kimiOauth,
}: ProvidersSettingsProps) {
  const toast = useToast();
  const [activeSection, setActiveSection] =
    useState<SettingsSection>("routing");
  const [providers, setProviders] = useState(initial.providers ?? []);
  const [routing, setRouting] = useState<RoutingDraft[]>(
    toRoutingDrafts(initial.tier_routing ?? []),
  );
  const [savingRouting, setSavingRouting] = useState(false);
  const [drafts, setDrafts] = useState<Record<string, string>>({});
  const [savingId, setSavingId] = useState<string | null>(null);
  const [testingId, setTestingId] = useState<string | null>(null);
  const [results, setResults] = useState<Record<string, TestResult>>({});

  const maskedFor = (id: string): string | null =>
    providers.find((p) => p.provider === id)?.masked_key ?? null;

  const sectionDetail = (value: SettingsSection): string => {
    if (value === "routing") {
      return `${routing.filter((r) => r.provider && r.model).length}/3 已配置`;
    }
    if (value === "oauth") {
      return kimiOauth.connected ? "Kimi 已连接" : "未连接";
    }
    return `${providers.length} 个凭据`;
  };

  const updateRouting = (tier: string, providerId: string): void => {
    setRouting((prev) =>
      prev.map((d) =>
        d.tier === tier ? applyProviderChange(d, providerId) : d,
      ),
    );
  };

  const updateRoutingModel = (tier: string, model: string): void => {
    setRouting((prev) =>
      prev.map((d) => (d.tier === tier ? { ...d, model } : d)),
    );
  };

  const saveRouting = async (): Promise<void> => {
    setSavingRouting(true);
    try {
      const { data, error } = await api.PUT("/settings/providers", {
        body: { tier_routing: draftsToRoutingInput(routing) },
      });
      if (error || !data) {
        toast("保存档位路由失败，请重试", "error");
        return;
      }
      setProviders(data.providers ?? []);
      setRouting(toRoutingDrafts(data.tier_routing ?? []));
      toast("档位路由已保存", "success");
    } catch {
      toast("保存档位路由失败，请检查后端连接", "error");
    } finally {
      setSavingRouting(false);
    }
  };

  const saveCredential = async (providerId: string): Promise<void> => {
    const apiKey = (drafts[providerId] ?? "").trim();
    if (!apiKey) {
      toast("请先输入 API Key", "error");
      return;
    }
    setSavingId(providerId);
    try {
      const { data, error } = await api.PUT("/settings/providers", {
        body: { credentials: [{ provider: providerId, api_key: apiKey }] },
      });
      if (error || !data) {
        toast("保存凭据失败，请重试", "error");
        return;
      }
      setProviders(data.providers ?? []);
      setDrafts((prev) => ({ ...prev, [providerId]: "" }));
      toast("凭据已保存", "success");
    } catch {
      toast("保存凭据失败，请检查后端连接", "error");
    } finally {
      setSavingId(null);
    }
  };

  const testConnection = async (providerId: string): Promise<void> => {
    setTestingId(providerId);
    try {
      const { data, error } = await api.POST("/settings/providers/test", {
        body: { provider: providerId },
      });
      if (error || !data) {
        toast("测试连接失败", "error");
        return;
      }
      setResults((prev) => ({
        ...prev,
        [providerId]: { ok: data.ok, capabilities: data.capabilities },
      }));
      toast(
        data.ok ? "连接成功" : "连接未通过",
        data.ok ? "success" : "error",
      );
    } catch {
      toast("测试连接失败，请检查后端连接", "error");
    } finally {
      setTestingId(null);
    }
  };

  return (
    <div className="grid gap-6 lg:grid-cols-[12rem_1fr]">
      <aside className="hidden lg:block">
        <nav aria-label="设置分组" className={cardClass("sticky top-20 p-2")}>
          {SETTINGS_SECTIONS.map((section) => (
            <SettingsNavButton
              key={section.value}
              active={activeSection === section.value}
              icon={<section.icon className="h-4 w-4" aria-hidden="true" />}
              label={section.label}
              detail={sectionDetail(section.value)}
              onClick={() => setActiveSection(section.value)}
            />
          ))}
        </nav>
      </aside>

      <div className="min-w-0">
        <SegmentedControl
          options={SECTION_OPTIONS}
          value={activeSection}
          onChange={setActiveSection}
          ariaLabel="设置分组"
          className="mb-4 w-full justify-center lg:hidden"
        />

        {activeSection === "routing" ? (
          <SettingsPanel>
            <SectionHeader
              title="能力档位路由"
              description="写手、分析、轻量三类能力可分别指向不同模型。保存时只提交完整填写的行。"
            />
            <StatusNote className="mt-3" variant="info">
              写章、审稿和摘要提炼会分别读取对应档位；未完整填写的行不会覆盖现有路由。
            </StatusNote>
            <ul className="mt-4 divide-y divide-line rounded border border-line bg-panel">
              {routing.map((row) => (
                <li
                  key={row.tier}
                  className="grid gap-3 px-4 py-3 text-sm md:grid-cols-[6rem_minmax(10rem,14rem)_1fr]"
                >
                  <span className="self-center text-ink">
                    {TIER_LABELS[row.tier] ?? row.tier}
                  </span>
                  <label
                    className="sr-only"
                    htmlFor={`route-provider-${row.tier}`}
                  >
                    {TIER_LABELS[row.tier] ?? row.tier} 提供商
                  </label>
                  <Select
                    id={`route-provider-${row.tier}`}
                    value={row.provider}
                    onChange={(e) => updateRouting(row.tier, e.target.value)}
                  >
                    <option value="">（未配置）</option>
                    {KNOWN_PROVIDERS.map((p) => (
                      <option key={p.id} value={p.id}>
                        {p.label}
                      </option>
                    ))}
                  </Select>
                  <label className="sr-only" htmlFor={`route-model-${row.tier}`}>
                    {TIER_LABELS[row.tier] ?? row.tier} 模型
                  </label>
                  <div className="min-w-0">
                    <TextInput
                      id={`route-model-${row.tier}`}
                      value={row.model}
                      onChange={(e) =>
                        updateRoutingModel(row.tier, e.target.value)
                      }
                      placeholder="model"
                      className="w-full font-mono"
                      list={`route-models-${row.tier}`}
                    />
                    <datalist id={`route-models-${row.tier}`}>
                      {(MODEL_SUGGESTIONS[row.provider] ?? []).map((m) => (
                        <option key={m} value={m} />
                      ))}
                    </datalist>
                  </div>
                </li>
              ))}
            </ul>
            <div className="mt-3 flex justify-end">
              <Button
                onClick={() => void saveRouting()}
                disabled={savingRouting}
                variant="primary"
                size="sm"
              >
                <Save className="h-4 w-4" aria-hidden="true" />
                {savingRouting ? "保存中…" : "保存档位路由"}
              </Button>
            </div>
          </SettingsPanel>
        ) : null}

        {activeSection === "oauth" ? (
          <SettingsPanel>
            <KimiCodeOauth
              initialConnected={kimiOauth.connected}
              initialExpiresAt={kimiOauth.expiresAt}
            />
          </SettingsPanel>
        ) : null}

        {activeSection === "keys" ? (
          <SettingsPanel>
            <SectionHeader
              title="提供商凭据"
              description="API Key 只用于后端探活和调用，列表中只显示脱敏后的已保存凭据。"
            />
            <div className="mt-3 grid gap-2 text-xs text-ink-soft sm:grid-cols-3">
              <div className="rounded border border-line bg-panel px-3 py-2">
                已保存 <span className="font-mono text-ink">{providers.length}</span>
              </div>
              <div className="rounded border border-line bg-panel px-3 py-2">
                可配置{" "}
                <span className="font-mono text-ink">
                  {API_KEY_PROVIDERS.length}
                </span>
              </div>
              <div className="rounded border border-line bg-panel px-3 py-2">
                测试结果{" "}
                <span className="font-mono text-ink">
                  {Object.keys(results).length}
                </span>
              </div>
            </div>
            {providers.length === 0 ? (
              <EmptyState
                icon={PlugZap}
                title="还没有可用提供商"
                description="至少连接一个提供商即可开始写作。求质量可选 Anthropic，求性价比可选 DeepSeek。"
                className="mt-4"
              />
            ) : null}
            <ul className="mt-4 divide-y divide-line rounded border border-line bg-panel">
              {API_KEY_PROVIDERS.map((prov) => {
                const masked = maskedFor(prov.id);
                const result = results[prov.id];
                return (
                  <li key={prov.id} className="px-4 py-4">
                    <div className="grid gap-3 lg:grid-cols-[10rem_8rem_minmax(12rem,1fr)_auto_auto] lg:items-center">
                      <span className="flex items-center gap-2 text-sm text-ink">
                        <span
                          className={`h-2 w-2 rounded ${
                            masked ? "bg-pass" : "bg-line"
                          }`}
                          aria-hidden="true"
                        />
                        {prov.label}
                      </span>
                      <span className="font-mono text-xs text-ink-soft">
                        {masked ?? "未配置"}
                      </span>
                      <label className="sr-only" htmlFor={`key-${prov.id}`}>
                        {prov.label} API Key
                      </label>
                      <TextInput
                        id={`key-${prov.id}`}
                        type="password"
                        autoComplete="off"
                        value={drafts[prov.id] ?? ""}
                        onChange={(e) =>
                          setDrafts((prev) => ({
                            ...prev,
                            [prov.id]: e.target.value,
                          }))
                        }
                        placeholder={
                          masked ? "输入新 Key 以更新" : "输入 API Key"
                        }
                      />
                      <Button
                        onClick={() => saveCredential(prov.id)}
                        disabled={
                          savingId === prov.id ||
                          (drafts[prov.id] ?? "").trim().length === 0
                        }
                        variant="primary"
                        size="sm"
                      >
                        <Save className="h-4 w-4" aria-hidden="true" />
                        {savingId === prov.id
                          ? "保存中…"
                          : masked
                            ? "更新"
                            : "添加"}
                      </Button>
                      <Button
                        onClick={() => testConnection(prov.id)}
                        disabled={testingId === prov.id}
                        variant="secondary"
                        size="sm"
                      >
                        <PlugZap className="h-4 w-4" aria-hidden="true" />
                        {testingId === prov.id ? "测试中…" : "测试"}
                      </Button>
                    </div>
                    <p className="mt-2 text-xs leading-5 text-ink-soft lg:pl-[10.5rem]">
                      {masked
                        ? "已保存脱敏凭据；输入新 Key 可覆盖更新。"
                        : "保存后再测试连接，成功后即可在档位路由中使用。"}
                    </p>
                    {result ? (
                      <div className="mt-2 flex flex-wrap items-center gap-2 lg:pl-[10.5rem]">
                        <Badge variant={result.ok ? "success" : "danger"}>
                          {result.ok ? (
                            <CheckCircle2
                              className="h-3 w-3"
                              aria-hidden="true"
                            />
                          ) : (
                            <XCircle className="h-3 w-3" aria-hidden="true" />
                          )}
                          {result.ok ? "已连接" : "未连接"}
                        </Badge>
                        <CapabilityBadges caps={result.capabilities} />
                      </div>
                    ) : null}
                  </li>
                );
              })}
            </ul>
          </SettingsPanel>
        ) : null}
      </div>
    </div>
  );
}

function SettingsPanel({ children }: { children: ReactNode }) {
  return <section className="min-w-0">{children}</section>;
}

interface SettingsNavButtonProps {
  active: boolean;
  icon: ReactNode;
  label: string;
  detail: string;
  onClick: () => void;
}

function SettingsNavButton({
  active,
  icon,
  label,
  detail,
  onClick,
}: SettingsNavButtonProps) {
  return (
    <button
      type="button"
      aria-pressed={active}
      onClick={onClick}
      className={`mb-1 flex w-full items-start gap-2 rounded px-3 py-2 text-left transition-colors ${
        active
          ? "bg-[var(--color-cinnabar-wash)] text-cinnabar"
          : "text-ink hover:bg-bg hover:text-cinnabar"
      }`}
    >
      <span className="mt-0.5 shrink-0">{icon}</span>
      <span className="min-w-0">
        <span className="block text-sm font-medium">{label}</span>
        <span className="block truncate text-xs text-ink-soft">{detail}</span>
      </span>
    </button>
  );
}

function CapabilityBadges({ caps }: { caps: CapabilitiesView }) {
  const badges: { on: boolean; label: string }[] = [
    { on: caps.structured_output, label: "结构化" },
    { on: caps.prefix_cache, label: "前缀缓存" },
    { on: caps.thinking, label: "思考" },
  ];
  return (
    <div className="flex gap-1.5">
      {badges.map((b) => (
        <Badge
          key={b.label}
          variant={b.on ? "accent" : "neutral"}
          className="text-2xs"
        >
          {b.label}
        </Badge>
      ))}
    </div>
  );
}
