"use client";

import { AlertTriangle, History, Loader2, RefreshCw, RotateCcw, Sparkles } from "lucide-react";
import { useCallback, useEffect, useState } from "react";

type Lang = "zh" | "en";

type ConfigIssue = {
  level: string;
  code: string;
  message: string;
  line?: number;
};

type ConfigStat = {
  key: string;
  label: string;
  value: string;
};

type ConfigAction = {
  id: string;
  label: string;
  description: string;
};

type ConfigBackup = {
  id: string;
  source: string;
  reason: string;
  label: string;
  created_at: string;
  size: number;
};

type ConfigInsights = {
  kind?: string;
  source?: string;
  summary?: string;
  issues?: ConfigIssue[];
  stats?: ConfigStat[];
  actions?: ConfigAction[];
  backups?: ConfigBackup[];
};

type Props = {
  lang: Lang;
  rootId: string;
  filePath: string;
  fileContent: string;
  refreshKey: number;
  busy: string | null;
  fetchJson: <T,>(path: string, init?: RequestInit) => Promise<T>;
  notify: (message: string) => void;
  onChangeContent: (content: string) => void;
  onRefreshListing?: () => Promise<void> | void;
};

function tr(lang: Lang, zh: string, en: string) {
  return lang === "zh" ? zh : en;
}

function formatBytes(size: number) {
  if (!size) return "0 B";
  const units = ["B", "KB", "MB", "GB"];
  let value = size;
  let unit = 0;
  while (value >= 1024 && unit < units.length - 1) {
    value /= 1024;
    unit += 1;
  }
  return `${value.toFixed(value >= 10 || unit === 0 ? 0 : 1)} ${units[unit]}`;
}

function issueTone(level: string) {
  if (level === "error") return "border-rose-500/30 bg-rose-500/10 text-rose-100";
  if (level === "warning") return "border-amber-500/30 bg-amber-500/10 text-amber-100";
  return "border-cyan-500/30 bg-cyan-500/10 text-cyan-100";
}

export function ConfigAdvisorPanel({
  lang,
  rootId,
  filePath,
  fileContent,
  refreshKey,
  busy,
  fetchJson,
  notify,
  onChangeContent,
  onRefreshListing,
}: Props) {
  const [insights, setInsights] = useState<ConfigInsights | null>(null);
  const [loading, setLoading] = useState(false);
  const [draftLoading, setDraftLoading] = useState(false);
  const [actionBusy, setActionBusy] = useState<string | null>(null);
  const [restoreBusy, setRestoreBusy] = useState<string | null>(null);

  const t = useCallback((zh: string, en: string) => tr(lang, zh, en), [lang]);

  const loadSavedInsights = useCallback(async () => {
    if (!rootId || !filePath) {
      setInsights(null);
      return;
    }
    setLoading(true);
    try {
      const params = new URLSearchParams({ root: rootId, path: filePath });
      const data = await fetchJson<ConfigInsights>(`/config_insights?${params.toString()}`);
      setInsights(data);
    } catch (reason) {
      setInsights(null);
      notify((reason as Error).message);
    } finally {
      setLoading(false);
    }
  }, [fetchJson, filePath, notify, rootId]);

  useEffect(() => {
    void loadSavedInsights();
  }, [loadSavedInsights, refreshKey]);

  const analyzeDraft = async () => {
    if (!rootId || !filePath) return;
    setDraftLoading(true);
    try {
      const data = await fetchJson<ConfigInsights>("/config_insights", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ root: rootId, path: filePath, content: fileContent }),
      });
      setInsights(data);
      notify(t("已分析当前编辑内容", "Analyzed current editor draft"));
    } catch (reason) {
      notify((reason as Error).message);
    } finally {
      setDraftLoading(false);
    }
  };

  const applyAction = async (actionId: string) => {
    if (!rootId || !filePath) return;
    setActionBusy(actionId);
    try {
      const data = await fetchJson<{ message?: string; content?: string; insights?: ConfigInsights }>(
        "/config_optimize",
        {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ root: rootId, path: filePath, content: fileContent, action: actionId }),
        },
      );
      if (typeof data.content === "string") onChangeContent(data.content);
      if (data.insights) {
        setInsights((prev) => ({ ...prev, ...data.insights, backups: prev?.backups || [] }));
      }
      notify(data.message || t("已应用优化", "Optimization applied"));
    } catch (reason) {
      notify((reason as Error).message);
    } finally {
      setActionBusy(null);
    }
  };

  const restoreFromBackup = async (backupId: string) => {
    if (!rootId || !filePath) return;
    setRestoreBusy(backupId);
    try {
      const data = await fetchJson<{ message?: string; content?: string }>("/config_restore", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ root: rootId, path: filePath, backup_id: backupId }),
      });
      if (typeof data.content === "string") onChangeContent(data.content);
      await Promise.resolve(onRefreshListing?.());
      await loadSavedInsights();
      notify(data.message || t("已恢复历史版本", "Backup restored"));
    } catch (reason) {
      notify((reason as Error).message);
    } finally {
      setRestoreBusy(null);
    }
  };

  if (!filePath) {
    return (
      <div className="rounded-2xl border border-white/8 bg-black/20 p-4 text-sm text-slate-400">
        {t("选择文件后显示诊断、回滚和一键优化。", "Pick a file to see diagnostics, rollback, and one-click optimizations.")}
      </div>
    );
  }

  const issues = insights?.issues || [];
  const actions = insights?.actions || [];
  const backups = insights?.backups || [];
  const stats = insights?.stats || [];

  return (
    <div className="space-y-4">
      <div className="rounded-2xl border border-cyan-500/15 bg-gradient-to-br from-cyan-500/[0.08] via-black/25 to-transparent p-4">
        <div className="flex flex-wrap items-start justify-between gap-3">
          <div>
            <div className="flex items-center gap-2 text-white">
              <Sparkles className="h-4 w-4 text-cyan-300" />
              <h3 className="text-sm font-semibold">{t("配置治理", "Config governance")}</h3>
              {insights?.source ? (
                <span className="rounded-full border border-white/10 bg-black/25 px-2 py-0.5 text-[10px] uppercase tracking-wider text-slate-400">
                  {insights.source}
                </span>
              ) : null}
            </div>
            <p className="mt-2 text-xs text-slate-400">
              {insights?.summary ||
                t("校验配置风险、查看历史快照，并将常见优化应用到编辑器。", "Validate risks, inspect snapshots, and apply optimizations into the editor.")}
            </p>
          </div>
          <div className="flex flex-wrap gap-2">
            <button
              type="button"
              disabled={!!busy || loading}
              onClick={() => void loadSavedInsights()}
              className="btn-focus inline-flex items-center gap-2 rounded-xl border border-white/10 bg-black/25 px-3 py-2 text-xs text-slate-100 disabled:opacity-40"
            >
              {loading ? <Loader2 className="h-3.5 w-3.5 animate-spin" /> : <RefreshCw className="h-3.5 w-3.5" />}
              {t("刷新已保存状态", "Refresh saved state")}
            </button>
            <button
              type="button"
              disabled={!!busy || draftLoading}
              onClick={() => void analyzeDraft()}
              className="btn-focus inline-flex items-center gap-2 rounded-xl border border-cyan-500/30 bg-cyan-500/15 px-3 py-2 text-xs text-cyan-100 disabled:opacity-40"
            >
              {draftLoading ? <Loader2 className="h-3.5 w-3.5 animate-spin" /> : <AlertTriangle className="h-3.5 w-3.5" />}
              {t("分析当前编辑器", "Analyze editor draft")}
            </button>
          </div>
        </div>

        <div className="mt-4 grid gap-2 sm:grid-cols-2 xl:grid-cols-4">
          {stats.slice(0, 8).map((item) => (
            <div key={item.key} className="rounded-xl border border-white/8 bg-black/20 px-3 py-2.5">
              <div className="text-[10px] uppercase tracking-wider text-slate-500">{item.label}</div>
              <div className="mt-1 truncate font-mono text-sm text-white">{item.value}</div>
            </div>
          ))}
        </div>
      </div>

      <div className="grid gap-4 xl:grid-cols-2">
        <div className="rounded-2xl border border-white/8 bg-black/20 p-4">
          <div className="flex items-center gap-2 text-white">
            <AlertTriangle className="h-4 w-4 text-amber-300" />
            <h4 className="text-sm font-semibold">{t("风险与建议", "Risks & guidance")}</h4>
          </div>
          {issues.length ? (
            <div className="mt-3 space-y-2">
              {issues.map((item, index) => (
                <div key={`${item.code}-${index}`} className={`rounded-xl border px-3 py-2 text-xs ${issueTone(item.level)}`}>
                  <div className="font-medium">
                    {item.message}
                    {item.line ? ` (L${item.line})` : ""}
                  </div>
                  <div className="mt-1 font-mono opacity-70">{item.code}</div>
                </div>
              ))}
            </div>
          ) : (
            <p className="mt-3 text-xs text-emerald-300/90">{t("当前没有发现明显配置风险。", "No obvious config risks were detected.")}</p>
          )}

          <div className="mt-4 flex flex-wrap gap-2">
            {actions.length ? (
              actions.map((item) => (
                <button
                  key={item.id}
                  type="button"
                  disabled={!!busy || !!actionBusy}
                  onClick={() => void applyAction(item.id)}
                  className="btn-focus rounded-xl border border-violet-500/30 bg-violet-500/15 px-3 py-2 text-xs text-violet-100 disabled:opacity-40"
                  title={item.description}
                >
                  {actionBusy === item.id ? t("处理中...", "Working...") : item.label}
                </button>
              ))
            ) : (
              <span className="text-xs text-slate-500">{t("当前文件没有可自动应用的预设。", "No auto-applicable presets for this file.")}</span>
            )}
          </div>
        </div>

        <div className="rounded-2xl border border-white/8 bg-black/20 p-4">
          <div className="flex items-center gap-2 text-white">
            <History className="h-4 w-4 text-cyan-300" />
            <h4 className="text-sm font-semibold">{t("历史快照", "Backup snapshots")}</h4>
          </div>
          {backups.length ? (
            <div className="mt-3 space-y-2">
              {backups.slice(0, 8).map((item) => (
                <div key={item.id} className="rounded-xl border border-white/8 bg-black/25 px-3 py-2.5">
                  <div className="flex flex-wrap items-center justify-between gap-2">
                    <div>
                      <div className="text-xs text-white">{new Date(item.created_at).toLocaleString(lang === "zh" ? "zh-CN" : "en-US", { hour12: false })}</div>
                      <div className="mt-1 text-[11px] text-slate-500">
                        {item.reason} · {formatBytes(item.size)}
                        {item.source === "legacy" ? ` · ${t("旧备份", "legacy")}` : ""}
                      </div>
                    </div>
                    <button
                      type="button"
                      disabled={!!busy || !!restoreBusy}
                      onClick={() => void restoreFromBackup(item.id)}
                      className="btn-focus inline-flex items-center gap-1 rounded-lg border border-white/10 bg-white/5 px-3 py-1.5 text-xs text-slate-100 disabled:opacity-40"
                    >
                      {restoreBusy === item.id ? (
                        <Loader2 className="h-3.5 w-3.5 animate-spin" />
                      ) : (
                        <RotateCcw className="h-3.5 w-3.5" />
                      )}
                      {t("恢复", "Restore")}
                    </button>
                  </div>
                </div>
              ))}
            </div>
          ) : (
            <p className="mt-3 text-xs text-slate-500">{t("当前文件还没有 Web 侧快照。保存、删除或恢复后会自动累积历史。", "No Web snapshots yet. Saving, deleting, or restoring will accumulate history automatically.")}</p>
          )}
        </div>
      </div>
    </div>
  );
}
