import { FormEvent, useEffect, useState } from "react";
import { apiFetch, getUsername, setSession, type NodeCard } from "../api";

export default function SettingsPage() {
  const [nodes, setNodes] = useState<NodeCard[]>([]);
  const [name, setName] = useState("");
  const [baseUrl, setBaseUrl] = useState("https://");
  const [err, setErr] = useState("");
  const [ok, setOk] = useState("");
  const [lastToken, setLastToken] = useState<{ id: number; token: string } | null>(
    null,
  );

  const [newUsername, setNewUsername] = useState(getUsername() || "admin");
  const [currentPassword, setCurrentPassword] = useState("");
  const [newPassword, setNewPassword] = useState("");
  const [confirmPassword, setConfirmPassword] = useState("");
  const [credBusy, setCredBusy] = useState(false);

  async function load() {
    const r = await apiFetch<{ nodes: NodeCard[] }>("/api/nodes/");
    setNodes(r.nodes || []);
  }

  useEffect(() => {
    load().catch((ex) => setErr(ex instanceof Error ? ex.message : String(ex)));
  }, []);

  async function onAdd(e: FormEvent) {
    e.preventDefault();
    setErr("");
    setOk("");
    try {
      await apiFetch("/api/nodes/", {
        method: "POST",
        body: JSON.stringify({ name: name.trim(), base_url: baseUrl.trim() }),
      });
      setName("");
      setOk("已添加策略机");
      await load();
    } catch (ex) {
      setErr(ex instanceof Error ? ex.message : String(ex));
    }
  }

  async function onSaveCreds(e: FormEvent) {
    e.preventDefault();
    setErr("");
    setOk("");
    if (newPassword !== confirmPassword) {
      setErr("两次新密码不一致");
      return;
    }
    setCredBusy(true);
    try {
      const r = await apiFetch<{ token: string; username: string }>(
        "/api/auth/change-credentials",
        {
          method: "POST",
          body: JSON.stringify({
            current_password: currentPassword,
            new_username: newUsername.trim(),
            new_password: newPassword,
          }),
        },
      );
      setSession(r.token, r.username);
      setCurrentPassword("");
      setNewPassword("");
      setConfirmPassword("");
      setOk("中控账号已更新");
    } catch (ex) {
      setErr(ex instanceof Error ? ex.message : String(ex));
    } finally {
      setCredBusy(false);
    }
  }

  async function genToken(id: number) {
    setErr("");
    setOk("");
    try {
      const r = await apiFetch<{ token: string; msg: string }>(
        `/api/nodes/${id}/generate-token`,
        { method: "POST" },
      );
      setLastToken({ id, token: r.token });
      setOk(r.msg || "已生成 Token");
      await load();
    } catch (ex) {
      setErr(ex instanceof Error ? ex.message : String(ex));
    }
  }

  async function remove(id: number) {
    if (!window.confirm("确认删除该策略机？")) return;
    setErr("");
    try {
      await apiFetch(`/api/nodes/${id}`, { method: "DELETE" });
      await load();
    } catch (ex) {
      setErr(ex instanceof Error ? ex.message : String(ex));
    }
  }

  return (
    <div>
      <h2>系统设置</h2>
      <p className="meta">
        中控不访问交易所。生成 Token 后登录策略机，在「登录账户」中保存同一 Token。
      </p>
      {err ? <div className="err">{err}</div> : null}
      {ok ? <div className="ok">{ok}</div> : null}

      <form className="add-form" onSubmit={onSaveCreds}>
        <h3>中控登录账号</h3>
        <p className="meta">默认 admin / admin123，建议首次登录后修改。</p>
        <label>
          新用户名
          <input
            value={newUsername}
            onChange={(e) => setNewUsername(e.target.value)}
            required
          />
        </label>
        <label>
          当前密码
          <input
            type="password"
            value={currentPassword}
            onChange={(e) => setCurrentPassword(e.target.value)}
            required
          />
        </label>
        <label>
          新密码
          <input
            type="password"
            value={newPassword}
            onChange={(e) => setNewPassword(e.target.value)}
            minLength={6}
            required
          />
        </label>
        <label>
          确认新密码
          <input
            type="password"
            value={confirmPassword}
            onChange={(e) => setConfirmPassword(e.target.value)}
            minLength={6}
            required
          />
        </label>
        <button className="btn" type="submit" disabled={credBusy}>
          {credBusy ? "保存中…" : "保存账号"}
        </button>
      </form>

      {lastToken ? (
        <div className="token-box">
          <div>
            节点 #{lastToken.id} 新 Token（只显示一次，请复制）：
          </div>
          <code className="mono">{lastToken.token}</code>
          <button
            type="button"
            className="btn ghost"
            onClick={() => {
              void navigator.clipboard.writeText(lastToken.token);
              setOk("已复制到剪贴板");
            }}
          >
            复制
          </button>
        </div>
      ) : null}

      <form className="add-form" onSubmit={onAdd}>
        <h3>添加策略机</h3>
        <label>
          名称
          <input
            value={name}
            onChange={(e) => setName(e.target.value)}
            placeholder="例如 云机-A"
            required
          />
        </label>
        <label>
          公网 Base URL
          <input
            value={baseUrl}
            onChange={(e) => setBaseUrl(e.target.value)}
            placeholder="https://dc.hyf2.cc"
            required
          />
        </label>
        <button className="btn" type="submit">
          添加
        </button>
      </form>

      <div className="table-wrap">
        <table>
          <thead>
            <tr>
              <th>ID</th>
              <th>名称</th>
              <th>URL</th>
              <th>Token</th>
              <th>操作</th>
            </tr>
          </thead>
          <tbody>
            {nodes.map((n) => (
              <tr key={n.id}>
                <td>{n.id}</td>
                <td>{n.name}</td>
                <td className="mono">{n.base_url}</td>
                <td>{n.token_configured ? "已生成" : "无"}</td>
                <td className="row-actions">
                  <button type="button" className="btn" onClick={() => void genToken(n.id)}>
                    生成 Token
                  </button>
                  <button
                    type="button"
                    className="btn ghost"
                    onClick={() => void remove(n.id)}
                  >
                    删除
                  </button>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
}
