import { useEffect, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import { AdminApi } from "@/lib/api";
import { useToastStore } from "@/stores/toastStore";
import type { AdminSettingsResponse } from "@/types";
import { Button } from "@/components/ui/Button";
import { Card } from "@/components/ui/Card";
import { Input } from "@/components/ui/Input";
import { Spinner } from "@/components/ui/Spinner";

const GROUP_PREFIXES: Array<{ group: string; prefixes: string[]; labelKey: string }> = [
  { group: "llm", prefixes: ["llm_", "llm."], labelKey: "admin.group_llm" },
  { group: "embeddings", prefixes: ["embeddings_", "embeddings."], labelKey: "admin.group_embeddings" },
  { group: "qdrant", prefixes: ["qdrant_", "qdrant."], labelKey: "admin.group_qdrant" },
  { group: "ui", prefixes: ["ui_", "ui.", "site_", "site."], labelKey: "admin.group_ui" },
  { group: "game", prefixes: ["game_", "game."], labelKey: "admin.group_game" },
];

function groupFor(key: string): string {
  const lower = key.toLowerCase();
  for (const g of GROUP_PREFIXES) {
    if (g.prefixes.some((p) => lower.startsWith(p))) return g.group;
  }
  return "other";
}

export function SettingsPanel() {
  const { t } = useTranslation();
  const pushToast = useToastStore((s) => s.push);
  const [data, setData] = useState<AdminSettingsResponse | null>(null);
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [draft, setDraft] = useState<Record<string, string>>({});

  useEffect(() => {
    setLoading(true);
    AdminApi.settings()
      .then((res) => {
        setData(res);
        setDraft({ ...res.settings });
      })
      .catch(() => pushToast("error", t("admin.settings_load_failed")))
      .finally(() => setLoading(false));
  }, [pushToast, t]);

  const grouped = useMemo(() => {
    if (!data) return {} as Record<string, Array<{ key: string; description?: string }>>;
    const out: Record<string, Array<{ key: string; description?: string }>> = {};
    for (const key of Object.keys(data.settings)) {
      const g = groupFor(key);
      (out[g] ||= []).push({ key, description: data.descriptions?.[key] });
    }
    return out;
  }, [data]);

  const handleSave = async () => {
    if (!data) return;
    setSaving(true);
    try {
      // Save only changed keys
      const diff: Record<string, string> = {};
      for (const [k, v] of Object.entries(draft)) {
        if (data.settings[k] !== v) diff[k] = v;
      }
      if (Object.keys(diff).length === 0) {
        pushToast("info", "No changes to save.");
        return;
      }
      const res = await AdminApi.updateSettings(diff);
      setData(res);
      setDraft({ ...res.settings });
      pushToast("success", t("admin.settings_saved"));
    } catch (err) {
      const msg = err instanceof Error ? err.message : "Failed";
      pushToast("error", msg);
    } finally {
      setSaving(false);
    }
  };

  if (loading) {
    return (
      <div className="flex items-center justify-center p-8">
        <Spinner /> <span className="ml-2 text-sm text-fg-muted">{t("common.loading")}</span>
      </div>
    );
  }

  if (!data) {
    return <p className="text-sm text-fg-muted">{t("common.no_data")}</p>;
  }

  const groupOrder = ["llm", "embeddings", "qdrant", "ui", "game", "other"];
  const groupLabelKey: Record<string, string> = {
    llm: "admin.group_llm",
    embeddings: "admin.group_embeddings",
    qdrant: "admin.group_qdrant",
    ui: "admin.group_ui",
    game: "admin.group_game",
    other: "common.details",
  };

  return (
    <div className="space-y-4">
      <div className="flex items-center justify-between">
        <h2 className="text-base font-semibold text-fg">{t("admin.tab_settings")}</h2>
        <Button onClick={handleSave} loading={saving}>
          {t("common.save")}
        </Button>
      </div>
      {groupOrder.map((g) => {
        const entries = grouped[g];
        if (!entries || entries.length === 0) return null;
        return (
          <Card key={g} title={t(groupLabelKey[g] || "common.details")}>
            <div className="grid gap-3 sm:grid-cols-2">
              {entries.map(({ key, description }) => (
                <Input
                  key={key}
                  label={key}
                  hint={description}
                  value={draft[key] ?? ""}
                  onChange={(e) => setDraft((d) => ({ ...d, [key]: e.target.value }))}
                />
              ))}
            </div>
          </Card>
        );
      })}
    </div>
  );
}
