import { useEffect, useMemo, useState } from "react";
import { Check, ChevronDown, CircleAlert, ExternalLink, Eye, EyeOff, Lock, ShieldCheck } from "lucide-react";
import { readConfig, verifyConfig, writeConfig } from "../ipc";
import type {
  ConfigFieldState,
  ConfigFormState,
  ConfigVerifyResult,
  WriteResult,
} from "../ipc/types";
import { AuthPanel } from "./AuthPanel";
import { MonoChip } from "./MonoChip";

/** 配置表单（视觉规范 §3.4：单列 ≤640px、敏感字段密码框 + 密钥库说明、吸底保存条）
 *  Wave 2.1：字段按官方配置方法渲染 + 保存后「生效检查」
 *  Wave 2.2：授权/登录层改为可操作授权流程（AuthPanel） */
export function ConfigForm({ id, onAuthChanged }: { id: string; onAuthChanged?: () => void }) {
  const [state, setState] = useState<ConfigFormState | null>(null);
  const [values, setValues] = useState<Record<string, string>>({});
  const [revealed, setRevealed] = useState<Record<string, boolean>>({});
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [saved, setSaved] = useState(false);
  const [result, setResult] = useState<WriteResult | null>(null);
  const [verify, setVerify] = useState<ConfigVerifyResult | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [advancedOpen, setAdvancedOpen] = useState(false);

  useEffect(() => {
    let cancelled = false;
    readConfig(id)
      .then((s) => {
        if (cancelled) return;
        setState(s);
        const init: Record<string, string> = {};
        for (const f of s.fields) {
          if (!f.sensitive && f.value != null) init[f.id] = f.value;
        }
        setValues(init);
        setLoading(false);
      })
      .catch((e) => {
        if (!cancelled) {
          setError(String(e));
          setLoading(false);
        }
      });
    return () => {
      cancelled = true;
    };
  }, [id]);

  const sensitiveSaved = useMemo(() => {
    const m: Record<string, boolean> = {};
    state?.fields.forEach((f) => {
      if (f.sensitive) m[f.id] = f.has_value;
    });
    return m;
  }, [state]);

  if (loading) return <p className="panel-empty">配置加载中…</p>;
  if (error) return <p className="panel-empty">配置加载失败：{error}</p>;
  if (!state) return null;

  const hasFields = state.fields.length > 0;
  const authFields = state.fields.filter((f) => f.group === "auth");
  const commonFields = state.fields.filter((f) => f.group === "common");
  const advancedFields = state.fields.filter((f) => f.group === "advanced");

  function renderField(field: ConfigFieldState) {
    return (
      <Field
        key={field.id}
        field={field}
        value={values[field.id] ?? ""}
        saved={sensitiveSaved[field.id] ?? false}
        revealed={!!revealed[field.id]}
        onToggleReveal={() => setRevealed((r) => ({ ...r, [field.id]: !r[field.id] }))}
        onChange={(v) => setValues((x) => ({ ...x, [field.id]: v }))}
      />
    );
  }

  async function onSave() {
    setSaving(true);
    setSaved(false);
    setResult(null);
    setVerify(null);
    setError(null);
    const patch: Record<string, string> = {};
    for (const f of state!.fields) {
      const v = values[f.id];
      if (v != null && v !== "") {
        patch[f.id] = v;
      }
    }
    if (Object.keys(patch).length === 0) {
      setError("没有需要保存的改动");
      setSaving(false);
      return;
    }
    try {
      const r = await writeConfig(id, patch);
      setResult(r);
      setSaved(true);
      setValues({});
      // 刷新回显
      const s = await readConfig(id);
      setState(s);
      // 生效检查：写回的配置能否被 CLI 接受（配置文件解析 + CLI 版本探测）
      try {
        const v = await verifyConfig(id);
        setVerify(v);
      } catch {
        setVerify(null);
      }
    } catch (e) {
      setError(String(e));
    } finally {
      setSaving(false);
    }
  }

  return (
    <div className="config-form">
      {!hasFields && <p className="panel-empty">该 CLI 未声明可配置的中文表单字段。</p>}

      {/* 第一层：授权 / 登录（可操作授权流程 + API Key 类字段） */}
      {(state.auth_modes.length > 0 || authFields.length > 0) && (
        <section className="config-section">
          <h4 className="config-section-title">授权 / 登录</h4>
          {state.auth_modes.length > 0 && (
            <AuthPanel id={id} authModes={state.auth_modes} onAuthChanged={onAuthChanged ?? (() => {})} />
          )}
          {authFields.map(renderField)}
        </section>
      )}

      {/* 第二层：常用配置 */}
      {commonFields.length > 0 && (
        <section className="config-section">
          <h4 className="config-section-title">常用配置</h4>
          {commonFields.map(renderField)}
        </section>
      )}

      {/* 第三层：高级配置（默认折叠） */}
      {advancedFields.length > 0 && (
        <section className="config-section">
          <button
            type="button"
            className="config-advanced-toggle"
            onClick={() => setAdvancedOpen((v) => !v)}
            aria-expanded={advancedOpen}
          >
            <span className="config-section-title">高级配置</span>
            <span className="advanced-badge">高级</span>
            <ChevronDown
              size={16}
              strokeWidth={1.5}
              className={advancedOpen ? "advanced-chevron open" : "advanced-chevron"}
              aria-hidden="true"
            />
          </button>
          <p className="advanced-hint">以下为官方支持但少数用户使用的高级项，一般无需修改。</p>
          {advancedOpen && <div className="advanced-fields">{advancedFields.map(renderField)}</div>}
        </section>
      )}

      {state.files.length > 0 && (
        <div className="config-file-info">
          <span className="config-file-label">配置文件</span>
          {state.files.map((f) => (
            <span key={f.path} className="config-file-path">
              <MonoChip>{f.path}</MonoChip>
              {f.exists ? (f.parse_ok ? " · 已解析" : " · 解析异常") : " · 尚未创建"}
            </span>
          ))}
        </div>
      )}

      {hasFields && (
        <div className="config-savebar">
          <div className="config-save-msg">
            {saved && (
              <span className="save-ok">
                <Check size={14} strokeWidth={1.5} aria-hidden="true" /> 已保存
              </span>
            )}
            {verify && (
              <span className={verify.ok ? "verify-ok" : "verify-fail"}>
                {verify.ok ? (
                  <ShieldCheck size={14} strokeWidth={1.5} aria-hidden="true" />
                ) : (
                  <CircleAlert size={14} strokeWidth={1.5} aria-hidden="true" />
                )}
                {verify.message_zh}
              </span>
            )}
            {result?.backup_path && (
              <span className="save-detail">
                已备份原文件 · {result.backup_path.split(/[\\/]/).pop()}
              </span>
            )}
            {error && <span className="save-error">{error}</span>}
          </div>
          <button
            type="button"
            className="btn btn-primary"
            onClick={onSave}
            disabled={saving}
          >
            {saving ? "保存中…" : "保存配置"}
          </button>
        </div>
      )}
    </div>
  );
}

function Field({
  field,
  value,
  saved,
  revealed,
  onChange,
  onToggleReveal,
}: {
  field: ConfigFieldState;
  value: string;
  saved: boolean;
  revealed: boolean;
  onChange: (v: string) => void;
  onToggleReveal: () => void;
}) {
  const isPassword = field.sensitive;
  const isEnum = field.field_type === "enum";
  const inputType = isPassword ? (revealed ? "text" : "password") : "text";
  return (
    <div className="field">
      <label className="field-label" htmlFor={`field-${field.id}`}>
        {field.label_zh}
        {field.required && <span className="field-required"> *</span>}
      </label>
      <div className="field-control">
        {isPassword && saved && (
          <span className="field-lock" title="已加密保存于系统密钥库">
            <Lock size={12} strokeWidth={1.5} aria-hidden="true" />
          </span>
        )}
        {isEnum ? (
          <select
            id={`field-${field.id}`}
            className="field-select"
            value={value}
            onChange={(e) => onChange(e.target.value)}
          >
            <option value="">（使用 CLI 默认）</option>
            {field.options.map((o) => (
              <option key={o.value} value={o.value}>
                {o.label_zh}（{o.value}）
              </option>
            ))}
          </select>
        ) : (
          <input
            id={`field-${field.id}`}
            type={inputType}
            value={value}
            placeholder={isPassword ? (saved ? "已保存 · 留空则不变" : "输入 API Key") : ""}
            autoComplete="off"
            spellCheck={false}
            onChange={(e) => onChange(e.target.value)}
          />
        )}
        {isPassword && (
          <button
            type="button"
            className="field-eye"
            onClick={onToggleReveal}
            aria-label={revealed ? "隐藏" : "显示"}
            tabIndex={-1}
          >
            {revealed ? <EyeOff size={16} strokeWidth={1.5} /> : <Eye size={16} strokeWidth={1.5} />}
          </button>
        )}
      </div>
      <div className="field-help">
        {field.help_zh}
        {isPassword && (
          <span className="field-keyring-note">
            {saved
              ? ` · 已加密保存于系统密钥库${field.env_key ? `（${field.env_key}）` : ""}`
              : ` · 保存后写入系统密钥库，绝不明文落盘${field.env_key ? `（${field.env_key}）` : ""}`}
          </span>
        )}
        {field.docs_url && (
          <a className="field-docs-link" href={field.docs_url} target="_blank" rel="noreferrer">
            官方文档 <ExternalLink size={11} strokeWidth={1.5} aria-hidden="true" />
          </a>
        )}
      </div>
    </div>
  );
}
