import { useEffect, useState } from "react";
import { adminPacks, savePack, genRedeemCodes, listRedeemCodes, getWechatPay, saveWechatPay, type CreditPack, type RedeemCodeRow, type WechatPayConfig } from "../api";

// 充值渠道（P5.1，设计见 PAYMENT_DESIGN.md）：
//   - 积分包：钱→积分的第一层汇率（第二层 积分→token 在上方「计费规则」里，两层解耦）。
//     微信支付(P5.2)上线前包只做展示位，这里先把配置面备好。
//   - 兑换码：零资质渠道 + 线下打款核销通道。生成后明文码只显示一次（列表页常驻展示
//     等于把「钱」贴在墙上，别这么干）。
const MICRO = 1_000_000;
const credits = (micro: number) => (micro / MICRO).toLocaleString("zh-CN", { maximumFractionDigits: 2 });

export function TopupChannels() {
  return (
    <div className="space-y-4">
      <div className="flex items-center gap-2 pt-1">
        <h3 className="text-sm font-semibold text-gray-700">充值渠道</h3>
        <span className="text-[11px] text-gray-400">兑换码即刻可用；微信扫码支付在下方配好商户号即点亮</span>
      </div>
      <div className="grid grid-cols-1 gap-4 xl:grid-cols-2">
        <RedeemBlock />
        <PacksBlock />
      </div>
      <WechatConfigBlock />
    </div>
  );
}

// ---- 微信支付配置：DB 存储、保存即热生效（不重启 gateway）。
// APIv3 密钥只写不回显（密文入库，与模型 API Key 同一把密钥加密）；
// 商户证书私钥文件放服务器磁盘，这里只填路径。
function WechatConfigBlock() {
  const empty: WechatPayConfig = { mchid: "", cert_serial: "", private_key_path: "", public_key_path: "", public_key_id: "", appid: "", notify_url: "", has_apiv3_key: false };
  const [cfg, setCfg] = useState<WechatPayConfig>(empty);
  const [apiv3, setApiv3] = useState(""); // 留空=沿用已存
  const [enabled, setEnabled] = useState(false);
  const [reason, setReason] = useState("");
  const [busy, setBusy] = useState(false);
  const [err, setErr] = useState("");

  useEffect(() => {
    getWechatPay()
      .then((r) => {
        setCfg(r.config);
        setEnabled(r.enabled);
        setReason(r.reason);
      })
      .catch((e) => setErr((e as Error).message));
  }, []);

  const save = async () => {
    if (busy) return;
    setBusy(true);
    setErr("");
    try {
      const r = await saveWechatPay({
        mchid: cfg.mchid,
        cert_serial: cfg.cert_serial,
        private_key_path: cfg.private_key_path,
        public_key_path: cfg.public_key_path,
        public_key_id: cfg.public_key_id,
        apiv3_key: apiv3, // 空串=后端沿用旧密钥
        appid: cfg.appid,
        notify_url: cfg.notify_url,
      });
      setEnabled(r.enabled);
      setReason(r.reason);
      setApiv3("");
      if (apiv3) setCfg((c) => ({ ...c, has_apiv3_key: true }));
    } catch (e) {
      setErr((e as Error).message);
    } finally {
      setBusy(false);
    }
  };

  const field = (label: string, key: keyof WechatPayConfig, placeholder: string, cls = "") => (
    <label className={`text-xs text-gray-500 ${cls}`}>
      {label}
      <input
        value={String(cfg[key] ?? "")}
        onChange={(e) => setCfg((c) => ({ ...c, [key]: e.target.value }))}
        placeholder={placeholder}
        className="mt-1 block w-full rounded-lg border border-gray-200 px-2.5 py-1.5 font-mono text-sm text-gray-800 focus:border-violet-400 focus:outline-none"
      />
    </label>
  );

  return (
    <div className="rounded-xl border border-gray-100 bg-white p-5 shadow-sm">
      <div className="mb-3 flex items-center justify-between">
        <div className="flex items-center gap-2">
          <h4 className="text-sm font-semibold text-gray-700">微信支付配置</h4>
          {enabled ? (
            <span className="rounded bg-emerald-50 px-2 py-0.5 text-[10px] font-medium text-emerald-600">渠道已启用</span>
          ) : (
            <span className="rounded bg-gray-100 px-2 py-0.5 text-[10px] text-gray-500" title={reason}>未启用{reason ? ` · ${reason}` : ""}</span>
          )}
        </div>
        <span className="text-[11px] text-gray-400">保存即热生效；私钥文件放服务器磁盘，此处只填路径</span>
      </div>

      <div className="grid grid-cols-1 gap-3 md:grid-cols-3">
        {field("商户号 (mchid)", "mchid", "190000****")}
        {field("API 证书序列号", "cert_serial", "5157F09E…")}
        {field("appid（公众号/小程序）", "appid", "wx88888888")}
        {field("商户私钥文件路径（服务器磁盘）", "private_key_path", "/etc/sundynix/wechat/apiclient_key.pem", "md:col-span-2")}
        {field("公钥 ID（PUB_KEY_ID_ 开头）", "public_key_id", "PUB_KEY_ID_01…")}
        {field("微信支付公钥文件路径（服务器磁盘）", "public_key_path", "/etc/sundynix/wechat/pub_key.pem", "md:col-span-2")}
        <label className="text-xs text-gray-500">
          APIv3 密钥{cfg.has_apiv3_key && <span className="ml-1 text-emerald-600">已保存</span>}
          <input
            type="password"
            value={apiv3}
            onChange={(e) => setApiv3(e.target.value)}
            placeholder={cfg.has_apiv3_key ? "留空则沿用已保存的" : "32 字节"}
            className="mt-1 block w-full rounded-lg border border-gray-200 px-2.5 py-1.5 font-mono text-sm text-gray-800 focus:border-violet-400 focus:outline-none"
          />
        </label>
        {field("支付回调地址（公网 https）", "notify_url", "https://api.example.com/api/v1/billing/callback/wechat", "md:col-span-3")}
      </div>
      {err && <p className="mt-2 text-xs text-rose-500">{err}</p>}
      <div className="mt-3 flex items-center gap-3">
        <button onClick={() => void save()} disabled={busy}
          className="rounded-lg bg-violet-600 px-3.5 py-1.5 text-sm text-white hover:bg-violet-700 disabled:opacity-40">
          {busy ? "保存中…" : "保存并热生效"}
        </button>
        <span className="text-[11px] text-gray-400">收不到公网回调也能到账（用户端轮询会主动查单），回调只是更快的通道。</span>
      </div>
    </div>
  );
}

// ---- 兑换码：生成 + 台账 ----
function RedeemBlock() {
  const [rows, setRows] = useState<RedeemCodeRow[]>([]);
  const [creditsIn, setCreditsIn] = useState("100");
  const [count, setCount] = useState("5");
  const [memo, setMemo] = useState("");
  const [fresh, setFresh] = useState<string[]>([]); // 刚生成的明文码（只此一屏）
  const [busy, setBusy] = useState(false);
  const [err, setErr] = useState("");

  const load = () => listRedeemCodes().then(setRows).catch((e) => setErr((e as Error).message));
  useEffect(() => {
    void load();
  }, []);

  const gen = async () => {
    const c = Number(creditsIn);
    const n = Number(count);
    if (!c || c <= 0 || !n || n <= 0 || busy) return;
    setBusy(true);
    setErr("");
    try {
      setFresh(await genRedeemCodes(c, n, memo.trim()));
      await load();
    } catch (e) {
      setErr((e as Error).message);
    } finally {
      setBusy(false);
    }
  };

  const copyAll = () => void navigator.clipboard?.writeText(fresh.join("\n"));

  return (
    <div className="rounded-xl border border-gray-100 bg-white p-5 shadow-sm">
      <div className="mb-3 flex items-center justify-between">
        <h4 className="text-sm font-semibold text-gray-700">兑换码</h4>
        <span className="text-[11px] text-gray-400">用户在 Web 面「用量与账单」输码入账</span>
      </div>

      <div className="flex flex-wrap items-end gap-2">
        <label className="text-xs text-gray-500">
          面额（积分）
          <input value={creditsIn} onChange={(e) => setCreditsIn(e.target.value)} inputMode="numeric"
            className="mt-1 block w-24 rounded-lg border border-gray-200 px-2.5 py-1.5 text-sm text-gray-800 focus:border-violet-400 focus:outline-none" />
        </label>
        <label className="text-xs text-gray-500">
          张数
          <input value={count} onChange={(e) => setCount(e.target.value)} inputMode="numeric"
            className="mt-1 block w-16 rounded-lg border border-gray-200 px-2.5 py-1.5 text-sm text-gray-800 focus:border-violet-400 focus:outline-none" />
        </label>
        <label className="flex-1 text-xs text-gray-500">
          备注（发给谁/用途）
          <input value={memo} onChange={(e) => setMemo(e.target.value)} placeholder="如：X 公司 PoC"
            className="mt-1 block w-full rounded-lg border border-gray-200 px-2.5 py-1.5 text-sm text-gray-800 focus:border-violet-400 focus:outline-none" />
        </label>
        <button onClick={() => void gen()} disabled={busy}
          className="rounded-lg bg-violet-600 px-3.5 py-1.5 text-sm text-white hover:bg-violet-700 disabled:opacity-40">
          {busy ? "生成中…" : "生成"}
        </button>
      </div>
      {err && <p className="mt-2 text-xs text-rose-500">{err}</p>}

      {fresh.length > 0 && (
        <div className="mt-3 rounded-lg border border-emerald-200 bg-emerald-50 p-3">
          <div className="mb-1.5 flex items-center justify-between">
            <span className="text-xs font-medium text-emerald-700">已生成 {fresh.length} 张——明文码只显示这一次，请立即复制发放</span>
            <button onClick={copyAll} className="rounded border border-emerald-300 px-2 py-0.5 text-[11px] text-emerald-700 hover:bg-emerald-100">
              复制全部
            </button>
          </div>
          <div className="grid grid-cols-1 gap-0.5 font-mono text-xs text-emerald-900 md:grid-cols-2">
            {fresh.map((c) => (
              <span key={c}>{c}</span>
            ))}
          </div>
        </div>
      )}

      <div className="mt-4 max-h-56 overflow-auto">
        <table className="w-full text-sm">
          <thead className="sticky top-0 bg-white">
            <tr className="border-b border-gray-100 text-left text-[11px] uppercase tracking-wide text-gray-400">
              <th className="py-2 pr-3 font-medium">码</th>
              <th className="py-2 pr-3 text-right font-medium">面额</th>
              <th className="py-2 pr-3 font-medium">状态</th>
              <th className="py-2 font-medium">备注</th>
            </tr>
          </thead>
          <tbody>
            {rows.map((r) => (
              <tr key={r.id} className="border-b border-gray-50 last:border-0">
                {/* 服务端已脱敏（只露首尾）：完整明文只在生成响应里给一次 */}
                <td className="py-1.5 pr-3 font-mono text-xs text-gray-600">{r.code}</td>
                <td className="py-1.5 pr-3 text-right tabular-nums text-gray-800">{credits(r.credits_micro)}</td>
                <td className="py-1.5 pr-3">
                  {r.status === "used" ? (
                    <span className="rounded bg-gray-100 px-1.5 py-0.5 text-[10px] text-gray-500">已核销</span>
                  ) : (
                    <span className="rounded bg-emerald-50 px-1.5 py-0.5 text-[10px] text-emerald-600">未使用</span>
                  )}
                </td>
                <td className="py-1.5 text-xs text-gray-400">{r.memo || "—"}</td>
              </tr>
            ))}
            {rows.length === 0 && (
              <tr>
                <td colSpan={4} className="py-6 text-center text-xs text-gray-400">还没有兑换码</td>
              </tr>
            )}
          </tbody>
        </table>
      </div>
    </div>
  );
}

// ---- 积分包：钱→积分定价（微信支付上线后用户按包扫码） ----
function PacksBlock() {
  const [rows, setRows] = useState<CreditPack[]>([]);
  const [name, setName] = useState("");
  const [creditsIn, setCreditsIn] = useState("");
  const [yuan, setYuan] = useState("");
  const [busy, setBusy] = useState(false);
  const [err, setErr] = useState("");

  const load = () => adminPacks().then(setRows).catch((e) => setErr((e as Error).message));
  useEffect(() => {
    void load();
  }, []);

  const add = async () => {
    const c = Number(creditsIn);
    const y = Number(yuan);
    if (!name.trim() || !c || c <= 0 || y < 0 || busy) return;
    setBusy(true);
    setErr("");
    try {
      await savePack({ name: name.trim(), credits: c, price_fen: Math.round(y * 100), active: true, sort: rows.length });
      setName("");
      setCreditsIn("");
      setYuan("");
      await load();
    } catch (e) {
      setErr((e as Error).message);
    } finally {
      setBusy(false);
    }
  };

  const toggle = async (p: CreditPack) => {
    try {
      await savePack({ id: p.id, name: p.name, credits: p.credits_micro / MICRO, price_fen: p.price_fen, active: !p.active, sort: p.sort });
      await load();
    } catch (e) {
      setErr((e as Error).message);
    }
  };

  return (
    <div className="rounded-xl border border-gray-100 bg-white p-5 shadow-sm">
      <div className="mb-3 flex items-center justify-between">
        <h4 className="text-sm font-semibold text-gray-700">积分包（微信支付定价）</h4>
        <span className="text-[11px] text-gray-400">钱→积分；积分→token 的汇率在上方计费规则</span>
      </div>

      <div className="flex flex-wrap items-end gap-2">
        <label className="flex-1 text-xs text-gray-500">
          名称
          <input value={name} onChange={(e) => setName(e.target.value)} placeholder="如：入门包"
            className="mt-1 block w-full rounded-lg border border-gray-200 px-2.5 py-1.5 text-sm text-gray-800 focus:border-violet-400 focus:outline-none" />
        </label>
        <label className="text-xs text-gray-500">
          积分
          <input value={creditsIn} onChange={(e) => setCreditsIn(e.target.value)} inputMode="numeric"
            className="mt-1 block w-24 rounded-lg border border-gray-200 px-2.5 py-1.5 text-sm text-gray-800 focus:border-violet-400 focus:outline-none" />
        </label>
        <label className="text-xs text-gray-500">
          售价（¥）
          <input value={yuan} onChange={(e) => setYuan(e.target.value)} inputMode="decimal"
            className="mt-1 block w-20 rounded-lg border border-gray-200 px-2.5 py-1.5 text-sm text-gray-800 focus:border-violet-400 focus:outline-none" />
        </label>
        <button onClick={() => void add()} disabled={busy}
          className="rounded-lg bg-violet-600 px-3.5 py-1.5 text-sm text-white hover:bg-violet-700 disabled:opacity-40">
          {busy ? "…" : "新增"}
        </button>
      </div>
      {err && <p className="mt-2 text-xs text-rose-500">{err}</p>}

      <div className="mt-4">
        <table className="w-full text-sm">
          <thead>
            <tr className="border-b border-gray-100 text-left text-[11px] uppercase tracking-wide text-gray-400">
              <th className="py-2 pr-3 font-medium">名称</th>
              <th className="py-2 pr-3 text-right font-medium">积分</th>
              <th className="py-2 pr-3 text-right font-medium">售价</th>
              <th className="py-2 text-right font-medium">状态</th>
            </tr>
          </thead>
          <tbody>
            {rows.map((p) => (
              <tr key={p.id} className="border-b border-gray-50 last:border-0">
                <td className="py-2 pr-3 text-gray-800">{p.name}</td>
                <td className="py-2 pr-3 text-right tabular-nums text-gray-800">{credits(p.credits_micro)}</td>
                <td className="py-2 pr-3 text-right tabular-nums text-gray-500">¥{(p.price_fen / 100).toFixed(2)}</td>
                <td className="py-2 text-right">
                  <button onClick={() => void toggle(p)}
                    className={`rounded border px-2 py-0.5 text-[11px] ${p.active ? "border-emerald-200 text-emerald-600 hover:bg-emerald-50" : "border-gray-200 text-gray-400 hover:bg-gray-50"}`}>
                    {p.active ? "在售 · 点击下架" : "已下架 · 点击上架"}
                  </button>
                </td>
              </tr>
            ))}
            {rows.length === 0 && (
              <tr>
                <td colSpan={4} className="py-6 text-center text-xs text-gray-400">还没有积分包——微信支付上线前配好即可</td>
              </tr>
            )}
          </tbody>
        </table>
      </div>
    </div>
  );
}
