// BEGIN CHANGE: dashboard da conta + gerenciar (paridade accountmanagement)
"use client";

import { useEffect, useState, FormEvent, type ReactNode } from "react";
import Link from "next/link";
import { useI18n } from "@/i18n/LanguageProvider";
import { useAuth, type Character, type Account } from "@/auth/AuthProvider";
import { Navbar } from "@/components/Navbar";
import { Footer } from "@/components/Footer";
import { PlayerName } from "@/components/PlayerName";
import { Outfit } from "@/components/Outfit";
import { VocationMatcher } from "@/components/VocationMatcher";
import { ShopHistorySerials, ShopHistoryWhat } from "@/components/ShopHistoryWhat";
import { CollapsiblePanel } from "@/components/CollapsiblePanel";
import { apiUrl, type Look } from "@/lib/api";

type VocPreview = { id: number; name: string; look: Look };

type ShopHistoryRow = {
  kind: "item" | "pacc";
  id: number;
  toName: string;
  price: number;
  offerId: number;
  state: string;
  started: number;
  realized: number;
  itemName: string;
  days: number;
  catalog: string;
  // BEGIN CHANGE: icons from account-history
  items?: { itemId: number; count: number; name: string }[];
  serialItem?: string;
  // END CHANGE
};

type DonateHistoryRow = {
  provider: string;
  id: string;
  status: string;
  amount: number;
  currency: string;
  points: number;
  processed: boolean;
  createdAt: string;
};

export default function AccountPage() {
  const { t } = useI18n();
  const { ready, token, account, setSession, logout } = useAuth();
  const [characters, setCharacters] = useState<Character[]>([]);
  const [acc, setAcc] = useState<Account | null>(null);
  const [status, setStatus] = useState<"loading" | "ok" | "error">("loading");
  const [busy, setBusy] = useState(false);
  const [msg, setMsg] = useState("");
  const [err, setErr] = useState("");
  const [shownKey, setShownKey] = useState("");
  // BEGIN CHANGE: historico shop + doacoes na conta
  const [shopHistory, setShopHistory] = useState<ShopHistoryRow[]>([]);
  const [donateHistory, setDonateHistory] = useState<DonateHistoryRow[]>([]);
  // END CHANGE
  // BEGIN CHANGE: banner e-mail apos criar conta
  const [registerMailNote, setRegisterMailNote] = useState<{ mail: string; email: string } | null>(
    null,
  );
  // END CHANGE

  const [oldPass, setOldPass] = useState("");
  const [newPass, setNewPass] = useState("");
  const [newPass2, setNewPass2] = useState("");
  const [email, setEmail] = useState("");
  const [emailPass, setEmailPass] = useState("");
  const [rlname, setRlname] = useState("");
  const [location, setLocation] = useState("");
  const [charName, setCharName] = useState("");
  const [sex, setSex] = useState("male");
  const [voc, setVoc] = useState(1);
  const [rkPass, setRkPass] = useState("");
  const [comments, setComments] = useState<Record<string, string>>({});
  const [nickProps, setNickProps] = useState<Record<string, string>>({});
  const [vocs, setVocs] = useState<VocPreview[]>([]);

  const vocLabels: Record<number, string> = {
    1: t.auth.vocSorcerer,
    2: t.auth.vocDruid,
    3: t.auth.vocPaladin,
    4: t.auth.vocKnight,
  };
  function load() {
    if (!token) return;
    setStatus("loading");
    fetch(apiUrl("me.php"), { headers: { Authorization: `Bearer ${token}` } })
      .then((r) => {
        if (r.status === 401) {
          logout();
          window.location.href = "/login";
          return null;
        }
        if (!r.ok) throw new Error("http " + r.status);
        return r.json();
      })
      .then((json) => {
        if (!json) return;
        const a = json.account as Account;
        const chars = (json.characters ?? []) as Character[];
        setAcc(a);
        setCharacters(chars);
        setRlname(a.rlname || "");
        setLocation(a.location || "");
        const c: Record<string, string> = {};
        const n: Record<string, string> = {};
        for (const ch of chars) {
          c[ch.name] = ch.comment || "";
          n[ch.name] = "";
        }
        setComments(c);
        setNickProps(n);
        setSession({ token, account: a, characters: chars });
        setStatus("ok");
      })
      .catch(() => setStatus("error"));
  }

  useEffect(() => {
    if (!ready) return;
    if (!token) {
      window.location.href = "/login";
      return;
    }
    load();
    fetch(apiUrl("vocations.php"))
      .then((r) => (r.ok ? r.json() : null))
      .then((json) => {
        if (json?.data) setVocs(json.data);
      })
      .catch(() => undefined);
    // BEGIN CHANGE: carrega historico shop + doacoes
    fetch(apiUrl("account-history.php"), {
      headers: { Authorization: `Bearer ${token}` },
    })
      .then((r) => (r.ok ? r.json() : null))
      .then((json) => {
        if (!json?.ok) return;
        setShopHistory((json.shop ?? []) as ShopHistoryRow[]);
        setDonateHistory((json.donations ?? []) as DonateHistoryRow[]);
      })
      .catch(() => undefined);
    // END CHANGE
    // BEGIN CHANGE: le aviso de e-mail pos-registro
    try {
      const raw = sessionStorage.getItem("waRegisterMail");
      if (raw) {
        sessionStorage.removeItem("waRegisterMail");
        const parsed = JSON.parse(raw) as { mail?: string; email?: string };
        if (parsed?.mail === "sent" || parsed?.mail === "fail") {
          setRegisterMailNote({ mail: parsed.mail, email: parsed.email || "" });
        }
      }
    } catch {
      /* ignore */
    }
    // END CHANGE
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [ready, token]);

  async function manage(body: Record<string, unknown>) {
    if (!token) return null;
    setBusy(true);
    setMsg("");
    setErr("");
    try {
      const r = await fetch(apiUrl("account-manage.php"), {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${token}`,
        },
        body: JSON.stringify(body),
      });
      const j = await r.json().catch(() => ({}));
      if (!r.ok || !j.ok) {
        setErr(t.auth.accountFailed);
        return null;
      }
      setMsg(t.auth.accountSaved);
      return j;
    } catch {
      setErr(t.auth.accountFailed);
      return null;
    } finally {
      setBusy(false);
    }
  }

  function onLogout() {
    logout();
    window.location.href = "/";
  }

  const emailReady =
    !!acc?.emailNew &&
    !!acc.emailNewTime &&
    acc.emailNewTime > 10 &&
    acc.emailNewTime <= Math.floor(Date.now() / 1000);

  return (
    <div className="flex min-h-screen flex-col">
      <Navbar />
      <main className="mx-auto w-full max-w-3xl flex-1 px-6 py-14">
        <div className="flex items-center justify-between gap-3">
          <h1 className="text-3xl font-semibold tracking-tight">{t.auth.myAccount}</h1>
          <button
            onClick={onLogout}
            className="rounded-lg border border-border px-4 py-2 text-sm text-muted transition-colors hover:text-foreground"
          >
            {t.auth.logout}
          </button>
        </div>

        {status === "loading" && <p className="mt-8 text-muted">{t.common.loading}</p>}
        {status === "error" && <p className="mt-8 text-muted">{t.common.error}</p>}

        {status === "ok" && acc && (
          <div className="mt-8 space-y-6">
            {/* BEGIN CHANGE: banner e-mail apos criar conta */}
            {registerMailNote && (
              <div
                className={`rounded-xl border p-4 text-sm ${
                  registerMailNote.mail === "fail"
                    ? "border-amber-500/40 text-amber-300"
                    : "border-brand/40 text-brand"
                }`}
              >
                {registerMailNote.mail === "sent"
                  ? t.auth.registerEmailSent.replace("{email}", registerMailNote.email || acc.email || "")
                  : t.auth.registerEmailFail}
              </div>
            )}
            {/* END CHANGE */}
            {(msg || err || shownKey) && (
              <div className={`rounded-xl border p-4 text-sm ${err ? "border-red-500/40 text-red-400" : "border-brand/40 text-brand"}`}>
                {err || msg}
                {shownKey && (
                  <p className="mt-2 font-mono text-base text-foreground">
                    {t.auth.recoveryKey}: {shownKey}
                    <br />
                    <span className="text-xs text-muted">{t.auth.showReckeyOnce}</span>
                  </p>
                )}
              </div>
            )}

            <div className="rounded-xl border border-border bg-panel p-6">
              <div className="text-sm text-muted">{t.auth.welcome}</div>
              <div className="mt-1 text-xl font-semibold">{acc.name}</div>
              {/* BEGIN CHANGE: dados da conta (e-mail completo; sem recovery key) */}
              <dl className="mt-4 grid gap-2 text-sm sm:grid-cols-2">
                <div>
                  <dt className="text-muted">{t.auth.email}</dt>
                  <dd className="font-medium break-all">{acc.email || "-"}</dd>
                </div>
                <div>
                  <dt className="text-muted">{t.auth.premiumPoints}</dt>
                  <dd className="font-medium">{acc.premiumPoints ?? 0}</dd>
                </div>
                <div>
                  <dt className="text-muted">{t.auth.backupPoints}</dt>
                  <dd className="font-medium">{acc.backupPoints ?? 0}</dd>
                </div>
                <div>
                  <dt className="text-muted">{t.auth.premiumDays}</dt>
                  <dd className="font-medium">{acc.premdays ?? 0}</dd>
                </div>
                <div>
                  <dt className="text-muted">{t.auth.realName}</dt>
                  <dd className="font-medium">{acc.rlname || "-"}</dd>
                </div>
                <div>
                  <dt className="text-muted">{t.auth.location}</dt>
                  <dd className="font-medium">{acc.location || "-"}</dd>
                </div>
                <div>
                  <dt className="text-muted">{t.auth.createdAt}</dt>
                  <dd className="font-medium">
                    {acc.created && acc.created > 0
                      ? new Date(acc.created * 1000).toLocaleString()
                      : "-"}
                  </dd>
                </div>
                <div>
                  <dt className="text-muted">{t.auth.recoveryKey}</dt>
                  <dd className="font-medium">
                    {acc.hasRecoveryKey ? t.auth.hasRecoveryKey : t.auth.noRecoveryKey}
                  </dd>
                </div>
              </dl>
              {/* END CHANGE */}
              {acc.emailNew && (acc.emailNewTime || 0) > 10 && (
                <div className="mt-4 space-y-2 text-sm">
                  <p className="text-muted">
                    {t.auth.emailPending}: <b>{acc.emailNew}</b> (
                    {new Date((acc.emailNewTime || 0) * 1000).toLocaleString()})
                  </p>
                  <div className="flex flex-wrap gap-2">
                    {emailReady && (
                      <button
                        type="button"
                        disabled={busy}
                        className="rounded border border-border px-3 py-1 text-xs"
                        onClick={async () => {
                          const pass = window.prompt(t.auth.password) || "";
                          const j = await manage({ action: "change_email_accept", password: pass });
                          if (j) load();
                        }}
                      >
                        {t.auth.acceptEmail}
                      </button>
                    )}
                    <button
                      type="button"
                      disabled={busy}
                      className="rounded border border-border px-3 py-1 text-xs"
                      onClick={async () => {
                        const j = await manage({ action: "change_email_cancel" });
                        if (j) load();
                      }}
                    >
                      {t.auth.cancelEmail}
                    </button>
                  </div>
                </div>
              )}
              {acc.pageAccess && acc.pageAccess > 0 && (
                <p className="mt-3 text-sm">
                  <Link href="/namelock/" className="text-brand hover:underline">
                    {t.auth.namelockTitle}
                  </Link>
                </p>
              )}
            </div>

            {/* BEGIN CHANGE: historico de compras do shop */}
            <CollapsiblePanel
              id="account-shop-history"
              title={t.auth.shopHistoryTitle}
              headerRight={
                <Link href="/shop" className="text-xs text-brand hover:underline">
                  {t.auth.goToShop}
                </Link>
              }
            >
              {shopHistory.length === 0 ? (
                <p className="text-sm text-muted">{t.auth.emptyShopHistory}</p>
              ) : (
                <div className="overflow-x-auto">
                  <table className="w-full min-w-[580px] text-left text-sm">
                    <thead className="text-muted">
                      <tr>
                        <th className="px-2 py-1.5 font-medium">{t.auth.histWhen}</th>
                        <th className="px-2 py-1.5 font-medium">{t.auth.histCatalog}</th>
                        <th className="px-2 py-1.5 font-medium">{t.auth.histTo}</th>
                        <th className="px-2 py-1.5 font-medium">{t.auth.histWhat}</th>
                        <th className="px-2 py-1.5 font-medium">{t.auth.histPrice}</th>
                        <th className="px-2 py-1.5 font-medium">{t.auth.histState}</th>
                        <th className="px-2 py-1.5 font-medium">{t.auth.histSerial}</th>
                      </tr>
                    </thead>
                    <tbody>
                      {shopHistory.map((h) => (
                        <tr key={`${h.catalog}-${h.kind}-${h.id}`} className="border-t border-border/40">
                          <td className="px-2 py-1.5 text-xs text-muted">
                            {h.started > 0 ? new Date(h.started * 1000).toLocaleString() : "-"}
                          </td>
                          <td className="px-2 py-1.5 text-xs text-muted">
                            {h.catalog === "guild" ? t.auth.catalogGuild : t.auth.catalogDonate}
                          </td>
                          <td className="px-2 py-1.5">{h.toName || "-"}</td>
                          <td className="px-2 py-1.5">
                            <ShopHistoryWhat
                              kind={h.kind}
                              itemName={h.itemName}
                              days={h.days}
                              premiumDaysLabel={t.auth.premiumDays}
                              items={h.items}
                              serialItem={h.serialItem}
                            />
                          </td>
                          <td className="px-2 py-1.5 text-brand">
                            {h.price}{" "}
                            {h.catalog === "guild" ? "GP" : "PP"}
                          </td>
                          <td className="px-2 py-1.5 text-muted">
                            {h.state === "wait" || h.state === "pending"
                              ? t.auth.histStateWait
                              : t.auth.histStateDone}
                          </td>
                          <td className="px-2 py-1.5 align-top">
                            {h.kind === "pacc" ? (
                              <span className="text-muted">-</span>
                            ) : (
                              <ShopHistorySerials serialItem={h.serialItem} />
                            )}
                          </td>
                        </tr>
                      ))}
                    </tbody>
                  </table>
                </div>
              )}
            </CollapsiblePanel>
            {/* END CHANGE */}

            {/* historico de doacoes */}
            <CollapsiblePanel
              id="account-donate-history"
              title={t.auth.donateHistoryTitle}
              defaultOpen={false}
              headerRight={
                <Link href="/donate" className="text-xs text-brand hover:underline">
                  {t.auth.goToDonate}
                </Link>
              }
            >
              {donateHistory.length === 0 ? (
                <p className="text-sm text-muted">{t.auth.emptyDonateHistory}</p>
              ) : (
                <div className="overflow-x-auto">
                  <table className="w-full min-w-[480px] text-left text-sm">
                    <thead className="text-muted">
                      <tr>
                        <th className="px-2 py-1.5 font-medium">{t.auth.histProvider}</th>
                        <th className="px-2 py-1.5 font-medium">{t.auth.histStatus}</th>
                        <th className="px-2 py-1.5 font-medium">{t.auth.histAmount}</th>
                        <th className="px-2 py-1.5 font-medium">{t.auth.histPoints}</th>
                        <th className="px-2 py-1.5 font-medium">{t.auth.histWhen}</th>
                      </tr>
                    </thead>
                    <tbody>
                      {donateHistory.map((h) => (
                        <tr key={`${h.provider}-${h.id}`} className="border-t border-border/40">
                          <td className="px-2 py-1.5 capitalize">{h.provider}</td>
                          <td className="px-2 py-1.5">
                            <span className="text-muted">{h.status}</span>
                            {h.processed && (
                              <span className="ml-2 text-[10px] uppercase text-emerald-400">OK</span>
                            )}
                          </td>
                          <td className="px-2 py-1.5 text-muted">
                            {h.amount} {h.currency}
                          </td>
                          <td className="px-2 py-1.5">{h.points}</td>
                          <td className="px-2 py-1.5 text-xs text-muted">{h.createdAt || "-"}</td>
                        </tr>
                      ))}
                    </tbody>
                  </table>
                </div>
              )}
            </CollapsiblePanel>

            <CollapsiblePanel id="account-characters" title={t.auth.characters}>
              {characters.length === 0 ? (
                <p className="text-sm text-muted">{t.auth.noCharacters}</p>
              ) : (
                <>
                  <p className="mb-3 text-xs text-muted">{t.auth.deleteCharHint}</p>
                  <ul className="divide-y divide-border/50">
                  {characters.map((c) => (
                    <li key={c.name} className="space-y-2 py-3 text-sm">
                      <div className="flex flex-wrap items-center justify-between gap-2">
                        <div className="flex items-center gap-2">
                          <PlayerName name={c.name} look={c.look} size="inline" />
                          {c.deleted && (
                            <span className="text-xs text-red-400">({t.auth.deletedTag})</span>
                          )}
                          {c.namelocked && c.oldName && (
                            <span className="text-xs text-muted">
                              {t.auth.proposeNick}: {c.oldName}
                            </span>
                          )}
                          {c.namelocked && !c.oldName && (
                            <span className="text-xs text-amber-400">{t.auth.namelockedHint}</span>
                          )}
                        </div>
                        <span className="text-muted">
                          {c.vocation} - Lv {c.level}
                        </span>
                      </div>
                      {!c.deleted && (
                        <div className="flex flex-wrap items-end gap-2">
                          <input
                            value={comments[c.name] ?? ""}
                            onChange={(e) =>
                              setComments((prev) => ({ ...prev, [c.name]: e.target.value }))
                            }
                            placeholder={t.auth.comment}
                            className="min-w-[10rem] flex-1 rounded border border-border bg-background px-2 py-1 text-xs"
                          />
                          <button
                            type="button"
                            disabled={busy}
                            className="rounded border border-border px-2 py-1 text-xs"
                            onClick={async () => {
                              const j = await manage({
                                action: "change_comment",
                                name: c.name,
                                comment: comments[c.name] || "",
                              });
                              if (j) load();
                            }}
                          >
                            {t.auth.comment}
                          </button>
                          {c.namelocked && !c.oldName && (
                            <>
                              <input
                                value={nickProps[c.name] ?? ""}
                                onChange={(e) =>
                                  setNickProps((prev) => ({ ...prev, [c.name]: e.target.value }))
                                }
                                placeholder={t.auth.proposeNick}
                                className="rounded border border-border bg-background px-2 py-1 text-xs"
                              />
                              <button
                                type="button"
                                disabled={busy || !(nickProps[c.name] || "").trim()}
                                className="rounded border border-border px-2 py-1 text-xs disabled:opacity-40"
                                onClick={async () => {
                                  const j = await manage({
                                    action: "propose_nick",
                                    name: c.name,
                                    nameNew: (nickProps[c.name] || "").trim(),
                                  });
                                  if (j) load();
                                }}
                              >
                                {t.auth.proposeNick}
                              </button>
                            </>
                          )}
                          <button
                            type="button"
                            disabled={busy}
                            className="rounded border border-border px-2 py-1 text-xs text-red-400"
                            onClick={async () => {
                              if (!window.confirm(t.auth.deleteCharHint)) return;
                              const pass = window.prompt(t.auth.password) || "";
                              const j = await manage({
                                action: "delete_character",
                                name: c.name,
                                password: pass,
                              });
                              if (j) load();
                            }}
                          >
                            {t.auth.deleteCharacter}
                          </button>
                        </div>
                      )}
                      {c.deleted && (
                        <button
                          type="button"
                          disabled={busy}
                          className="rounded border border-border px-2 py-1 text-xs"
                          onClick={async () => {
                            const j = await manage({ action: "undelete_character", name: c.name });
                            if (j) load();
                          }}
                        >
                          {t.auth.undeleteCharacter}
                        </button>
                      )}
                    </li>
                  ))}
                  </ul>
                </>
              )}
            </CollapsiblePanel>

            <FormCard id="account-create-character" title={t.auth.createCharacter}>
              <form
                className="space-y-4"
                onSubmit={async (e: FormEvent) => {
                  e.preventDefault();
                  const j = await manage({
                    action: "create_character",
                    charName,
                    sex,
                    vocation: voc,
                  });
                  if (j) {
                    setCharName("");
                    load();
                  }
                }}
              >
                <input
                  value={charName}
                  onChange={(e) => setCharName(e.target.value)}
                  placeholder={t.auth.charName}
                  autoCapitalize="off"
                  autoCorrect="off"
                  spellCheck={false}
                  className="w-full rounded border border-border bg-background px-2 py-1.5 text-sm"
                />
                <div>
                  <span className="mb-1.5 block text-xs text-muted">{t.auth.sex}</span>
                  <div className="flex gap-4 text-sm">
                    <label className="flex items-center gap-2">
                      <input
                        type="radio"
                        checked={sex === "male"}
                        onChange={() => setSex("male")}
                      />
                      {t.auth.male}
                    </label>
                    <label className="flex items-center gap-2">
                      <input
                        type="radio"
                        checked={sex === "female"}
                        onChange={() => setSex("female")}
                      />
                      {t.auth.female}
                    </label>
                  </div>
                </div>
                {/* BEGIN CHANGE: matcher de preferencia acima do seletor de vocacao */}
                <div>
                  <VocationMatcher value={voc} onSuggest={setVoc} className="mb-4" />
                  <span className="mb-2 block text-xs text-muted">{t.auth.vocation}</span>
                  <div className="grid grid-cols-2 gap-3 sm:grid-cols-4">
                    {vocs.map((v) => (
                      <label
                        key={v.id}
                        className={`flex cursor-pointer flex-col items-center rounded-xl border px-2 py-3 text-center text-sm transition-colors ${
                          voc === v.id
                            ? "border-brand bg-brand/10"
                            : "border-border bg-background hover:border-brand/40"
                        }`}
                      >
                        <input
                          type="radio"
                          className="sr-only"
                          checked={voc === v.id}
                          onChange={() => setVoc(v.id)}
                        />
                        <Outfit look={v.look} size="grid" alt={vocLabels[v.id] ?? v.name} />
                        <span className="mt-1 font-medium">{vocLabels[v.id] ?? v.name}</span>
                      </label>
                    ))}
                  </div>
                  <p className="mt-3 text-sm">
                    <Link href="/vocations" className="text-brand hover:underline">
                      {t.auth.compareVocations}
                    </Link>
                  </p>
                </div>
                {/* END CHANGE */}
                <button
                  type="submit"
                  disabled={busy || !charName.trim()}
                  className="rounded-lg bg-brand px-4 py-2 text-sm font-medium text-background disabled:opacity-50"
                >
                  {t.auth.createCharacter}
                </button>
              </form>
            </FormCard>

            <FormCard id="account-change-password" title={t.auth.changePassword} defaultOpen={false}>
              <form
                className="grid gap-2 sm:grid-cols-3"
                onSubmit={async (e) => {
                  e.preventDefault();
                  const j = await manage({
                    action: "change_password",
                    oldPassword: oldPass,
                    newPassword: newPass,
                    newPassword2: newPass2,
                  });
                  if (j) {
                    // BEGIN CHANGE: keep session alive with rotated token after password change
                    if (typeof j.token === "string" && j.token && account) {
                      setSession({
                        token: j.token,
                        account,
                        characters,
                      });
                    }
                    // END CHANGE
                    setOldPass("");
                    setNewPass("");
                    setNewPass2("");
                  }
                }}
              >
                <input
                  type="password"
                  value={oldPass}
                  onChange={(e) => setOldPass(e.target.value)}
                  placeholder={t.auth.currentPassword}
                  className="rounded border border-border bg-background px-2 py-1.5 text-sm"
                />
                <input
                  type="password"
                  value={newPass}
                  onChange={(e) => setNewPass(e.target.value)}
                  placeholder={t.auth.newPassword}
                  className="rounded border border-border bg-background px-2 py-1.5 text-sm"
                />
                <input
                  type="password"
                  value={newPass2}
                  onChange={(e) => setNewPass2(e.target.value)}
                  placeholder={t.auth.confirmPassword}
                  className="rounded border border-border bg-background px-2 py-1.5 text-sm"
                />
                <button
                  type="submit"
                  disabled={busy}
                  className="rounded-lg bg-brand px-4 py-2 text-sm font-medium text-background disabled:opacity-50 sm:col-span-3"
                >
                  {t.auth.changePassword}
                </button>
              </form>
            </FormCard>

            <FormCard id="account-change-email" title={t.auth.changeEmail} defaultOpen={false}>
              <form
                className="flex flex-wrap gap-2"
                onSubmit={async (e) => {
                  e.preventDefault();
                  const j = await manage({
                    action: "change_email_request",
                    email,
                    password: emailPass,
                  });
                  if (j) {
                    setEmail("");
                    setEmailPass("");
                    load();
                  }
                }}
              >
                <input
                  value={email}
                  onChange={(e) => setEmail(e.target.value)}
                  placeholder={t.auth.email}
                  className="rounded border border-border bg-background px-2 py-1.5 text-sm"
                />
                <input
                  type="password"
                  value={emailPass}
                  onChange={(e) => setEmailPass(e.target.value)}
                  placeholder={t.auth.password}
                  className="rounded border border-border bg-background px-2 py-1.5 text-sm"
                />
                <button
                  type="submit"
                  disabled={busy}
                  className="rounded-lg bg-brand px-4 py-2 text-sm font-medium text-background disabled:opacity-50"
                >
                  {t.auth.changeEmail}
                </button>
              </form>
            </FormCard>

            <FormCard id="account-change-info" title={t.auth.changeInfo} defaultOpen={false}>
              <form
                className="flex flex-wrap gap-2"
                onSubmit={async (e) => {
                  e.preventDefault();
                  const j = await manage({ action: "change_info", rlname, location });
                  if (j) load();
                }}
              >
                <input
                  value={rlname}
                  onChange={(e) => setRlname(e.target.value)}
                  placeholder={t.auth.realName}
                  className="rounded border border-border bg-background px-2 py-1.5 text-sm"
                />
                <input
                  value={location}
                  onChange={(e) => setLocation(e.target.value)}
                  placeholder={t.auth.location}
                  className="rounded border border-border bg-background px-2 py-1.5 text-sm"
                />
                <button
                  type="submit"
                  disabled={busy}
                  className="rounded-lg bg-brand px-4 py-2 text-sm font-medium text-background disabled:opacity-50"
                >
                  {t.auth.changeInfo}
                </button>
              </form>
            </FormCard>

            <FormCard id="account-recovery-key" title={t.auth.recoveryKey} defaultOpen={false}>
              <div className="flex flex-wrap items-end gap-2">
                <input
                  type="password"
                  value={rkPass}
                  onChange={(e) => setRkPass(e.target.value)}
                  placeholder={t.auth.password}
                  className="rounded border border-border bg-background px-2 py-1.5 text-sm"
                />
                {!acc.hasRecoveryKey ? (
                  <button
                    type="button"
                    disabled={busy || !rkPass}
                    className="rounded-lg bg-brand px-4 py-2 text-sm font-medium text-background disabled:opacity-50"
                    onClick={async () => {
                      const j = await manage({ action: "register_account", password: rkPass });
                      if (j?.recoveryKey) {
                        setShownKey(j.recoveryKey);
                        setRkPass("");
                        load();
                      }
                    }}
                  >
                    {t.auth.registerAccount}
                  </button>
                ) : (
                  <button
                    type="button"
                    disabled={busy || !rkPass}
                    className="rounded-lg bg-brand px-4 py-2 text-sm font-medium text-background disabled:opacity-50"
                    onClick={async () => {
                      const j = await manage({ action: "new_reckey", password: rkPass });
                      if (j?.recoveryKey) {
                        setShownKey(j.recoveryKey);
                        setRkPass("");
                        load();
                      }
                    }}
                  >
                    {t.auth.newReckey} ({acc.reckeyPrice ?? 15} PP)
                  </button>
                )}
              </div>
            </FormCard>
          </div>
        )}
      </main>
      <Footer />
    </div>
  );
}

function FormCard({
  id,
  title,
  children,
  defaultOpen = true,
}: {
  id: string;
  title: string;
  children: ReactNode;
  defaultOpen?: boolean;
}) {
  return (
    <CollapsiblePanel id={id} title={title} defaultOpen={defaultOpen}>
      {children}
    </CollapsiblePanel>
  );
}
// END CHANGE
