"use client";

import {
  CheckCircle2,
  KeyRound,
  PlugZap,
  Route,
  Save,
  XCircle,
} 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 {
  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";

const SECTION_OPTIONS: Array<{ value: SettingsSection; label: string }> = [
  { value: "routing", label: "路由" },
  { value: "oauth", label: "OAuth" },
  { value: "keys", label: "API Key" },
];

// 设置页主体（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 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);
    const { data, error } = await api.PUT("/settings/providers", {
      body: { tier_routing: draftsToRoutingInput(routing) },
    });
    setSavingRouting(false);
    if (error || !data) {
      toast("保存档位路由失败，请重试", "error");
      return;
    }
    setProviders(data.providers ?? []);
    setRouting(toRoutingDrafts(data.tier_routing ?? []));
    toast("档位路由已保存", "success");
  };

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

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

  return (
    <div className="grid gap-6 lg:grid-cols-[12rem_1fr]">
      <aside className="hidden lg:block">
        <nav
          aria-label="设置分组"
          className="sticky top-4 rounded border border-line bg-panel p-2"
        >
          <SettingsNavButton
            active={activeSection === "routing"}
            icon={<Route className="h-4 w-4" aria-hidden="true" />}
            label="档位路由"
            detail={`${routing.filter((r) => r.provider && r.model).length}/3 已配置`}
            onClick={() => setActiveSection("routing")}
          />
          <SettingsNavButton
            active={activeSection === "oauth"}
            icon={<PlugZap className="h-4 w-4" aria-hidden="true" />}
            label="OAuth"
            detail={kimiOauth.connected ? "Kimi 已连接" : "未连接"}
            onClick={() => setActiveSection("oauth")}
          />
          <SettingsNavButton
            active={activeSection === "keys"}
            icon={<KeyRound className="h-4 w-4" aria-hidden="true" />}
            label="API Key"
            detail={`${providers.length} 个凭据`}
            onClick={() => setActiveSection("keys")}
          />
        </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>
                  <TextInput
                    id={`route-model-${row.tier}`}
                    value={row.model}
                    onChange={(e) =>
                      updateRoutingModel(row.tier, e.target.value)
                    }
                    placeholder="model"
                    className="font-mono"
                  />
                </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) => (
        <span
          key={b.label}
          className={`rounded border px-2 py-0.5 text-[11px] ${
            b.on
              ? "border-cinnabar/20 bg-[var(--color-cinnabar-wash)] text-cinnabar"
              : "border-line bg-bg text-ink-soft/50"
          }`}
        >
          {b.label}
        </span>
      ))}
    </div>
  );
}
