// BEGIN CHANGE: Character Market com cards + detalhes do player a venda
"use client";

import { FormEvent, useCallback, useEffect, useState, type ReactNode } from "react";
import Link from "next/link";
import { useI18n } from "@/i18n/LanguageProvider";
import { useAuth } from "@/auth/AuthProvider";
import { Navbar } from "@/components/Navbar";
import { Footer } from "@/components/Footer";
import { Outfit } from "@/components/Outfit";
import { ItemIcon } from "@/components/ItemIcon";
import {
  apiUrl,
  equipmentEmptyBgUrl,
  equipmentPanelBgUrl,
  equipmentSlotUrl,
  type Look,
} from "@/lib/api";

type EqSlot = { slot: number; itemId: number | null };
type Skill = { name: string; value: number };
type Quest = { name: string; done: boolean };
type ItemStack = { itemId: number; count: number };

type OfferPlayer = {
  id: number;
  name: string;
  level: number;
  reset: number;
  vocation: string;
  look: Look;
  experience?: number;
  magic?: number;
  sex?: string;
  healthMax?: number;
  manaMax?: number;
  residence?: string | null;
  balance?: number;
  armyLevel?: number;
  armyRank?: string | null;
  frags?: number;
  created?: number;
  lastlogin?: number;
  comment?: string | null;
  dodge?: number;
  critical?: number;
  mining?: number;
  isPremium?: boolean;
  marriedTo?: string | null;
  oldName?: string | null;
  skills?: Skill[];
  equipment?: EqSlot[];
  quests?: Quest[];
  inventory?: ItemStack[];
  depot?: ItemStack[];
  resetBonus?: {
    rr: number;
    damagePercent: number;
    hpmpPercent: number;
    damageMultiplier: number;
  };
};

type Offer = {
  id: number;
  price: number;
  created: number;
  player: OfferPlayer;
  isMine?: boolean;
};

type Listable = {
  id: number;
  name: string;
  level: number;
  reset: number;
  online: boolean;
  vocation: string;
  look: Look;
};

type Payload = {
  offers: Offer[];
  myListable: Listable[];
  myOffers: Offer[];
  premiumPoints: number | null;
  minPrice: number;
  maxPrice: number;
};

export default function CharacterMarketPage() {
  const { t } = useI18n();
  const { ready, token, account } = useAuth();
  const [status, setStatus] = useState<"loading" | "ok" | "error">("loading");
  const [data, setData] = useState<Payload | null>(null);
  const [busy, setBusy] = useState(false);
  const [msg, setMsg] = useState("");
  const [err, setErr] = useState("");
  const [playerId, setPlayerId] = useState("");
  const [price, setPrice] = useState("");
  const [selected, setSelected] = useState<Offer | null>(null);

  const authHeaders = useCallback(
    (json = true): HeadersInit => {
      const h: Record<string, string> = {};
      if (json) h["Content-Type"] = "application/json";
      if (token) h.Authorization = `Bearer ${token}`;
      return h;
    },
    [token]
  );

  const load = useCallback(() => {
    setStatus("loading");
    fetch(apiUrl("character-market.php"), { headers: authHeaders(false) })
      .then((r) => {
        if (!r.ok) throw new Error("http");
        return r.json();
      })
      .then((json: Payload) => {
        setData(json);
        setStatus("ok");
      })
      .catch(() => setStatus("error"));
  }, [authHeaders]);

  useEffect(() => {
    if (!ready) return;
    load();
  }, [ready, load]);

  function errLabel(code: string) {
    const map = t.characterMarket.errors as Record<string, string>;
    return map[code] || t.characterMarket.actionFailed;
  }

  async function post(action: string, body: Record<string, unknown>) {
    if (!token) {
      setErr(t.characterMarket.needLogin);
      return;
    }
    setBusy(true);
    setMsg("");
    setErr("");
    try {
      const r = await fetch(apiUrl("character-market.php"), {
        method: "POST",
        headers: authHeaders(true),
        body: JSON.stringify({ action, ...body }),
      });
      const json = await r.json().catch(() => ({}));
      if (!r.ok || !json.ok) {
        setErr(errLabel(typeof json.error === "string" ? json.error : "action_failed"));
        return;
      }
      const offers: Offer[] = json.offers ?? [];
      setData((cur) => ({
        offers,
        myListable: json.myListable ?? cur?.myListable ?? [],
        myOffers: offers.filter((o) => o.isMine),
        premiumPoints:
          typeof json.premiumPoints === "number"
            ? json.premiumPoints
            : (cur?.premiumPoints ?? null),
        minPrice: cur?.minPrice ?? 1,
        maxPrice: cur?.maxPrice ?? 10000000,
      }));
      setMsg(
        action === "buy"
          ? t.characterMarket.buyOk.replace("{name}", json.playerName || "")
          : t.characterMarket.actionOk
      );
      if (action === "list") {
        setPlayerId("");
        setPrice("");
      }
      if (action === "buy" || action === "unlist") {
        setSelected(null);
      } else if (selected) {
        const next = offers.find((o) => o.id === selected.id) ?? null;
        setSelected(next);
      }
    } catch {
      setErr(t.characterMarket.actionFailed);
    } finally {
      setBusy(false);
    }
  }

  function onList(e: FormEvent) {
    e.preventDefault();
    const pid = parseInt(playerId, 10);
    const p = parseInt(price, 10);
    if (!pid || !p) {
      setErr(t.characterMarket.errors.price_invalid);
      return;
    }
    void post("list", { playerId: pid, price: p });
  }

  function formatDate(ts: number) {
    if (!ts) return "-";
    return new Date(ts * 1000).toLocaleString();
  }

  function formatMoney(n: number) {
    return n.toLocaleString();
  }

  function buyOffer(o: Offer) {
    if (
      !window.confirm(
        t.characterMarket.buyConfirm
          .replace("{name}", o.player.name)
          .replace("{price}", String(o.price))
      )
    ) {
      return;
    }
    void post("buy", { id: o.id });
  }

  const loggedIn = !!(ready && token && account);
  const offers = data?.offers ?? [];

  return (
    <div className="flex min-h-screen flex-col">
      <Navbar />
      <main className="mx-auto w-full max-w-6xl flex-1 px-6 py-14">
        <h1 className="text-3xl font-semibold tracking-tight">{t.characterMarket.title}</h1>
        <p className="mt-2 text-muted">{t.characterMarket.subtitle}</p>
        <ul className="mt-4 list-disc space-y-1 pl-5 text-sm text-muted">
          <li>{t.characterMarket.ruleListed}</li>
          <li>{t.characterMarket.rulePoints}</li>
          <li>{t.characterMarket.ruleUnlist}</li>
        </ul>

        {loggedIn && data?.premiumPoints != null && (
          <p className="mt-4 text-sm">
            {t.characterMarket.yourPoints}:{" "}
            <span className="font-semibold text-brand">{data.premiumPoints}</span>
          </p>
        )}
        {!loggedIn && ready && (
          <p className="mt-4 text-sm text-muted">
            {t.characterMarket.needLogin}{" "}
            <Link href="/login" className="text-brand hover:underline">
              {t.nav.items.login}
            </Link>
          </p>
        )}

        {msg && <p className="mt-4 text-sm text-brand">{msg}</p>}
        {err && <p className="mt-4 text-sm text-red-400">{err}</p>}

        {loggedIn && (
          <section className="mt-8 rounded-xl border border-border bg-panel p-5">
            <h2 className="text-lg font-semibold">{t.characterMarket.sellTitle}</h2>
            <p className="mt-1 text-sm text-muted">{t.characterMarket.sellHint}</p>
            {(data?.myListable?.length ?? 0) === 0 ? (
              <p className="mt-4 text-sm text-muted">{t.characterMarket.noListable}</p>
            ) : (
              <form onSubmit={onList} className="mt-4 flex flex-wrap items-end gap-3">
                <label className="text-sm">
                  <span className="text-muted">{t.characterMarket.character}</span>
                  <select
                    className="mt-1 block min-w-[14rem] rounded border border-border bg-background px-3 py-2"
                    value={playerId}
                    onChange={(e) => setPlayerId(e.target.value)}
                    required
                  >
                    <option value="">{t.characterMarket.pickCharacter}</option>
                    {(data?.myListable ?? []).map((c) => (
                      <option key={c.id} value={c.id} disabled={c.online}>
                        {c.name} - {c.vocation} {c.level}
                        {c.reset > 0 ? ` R${c.reset}` : ""}
                        {c.online ? ` (${t.characterMarket.online})` : ""}
                      </option>
                    ))}
                  </select>
                </label>
                <label className="text-sm">
                  <span className="text-muted">{t.characterMarket.price}</span>
                  <input
                    type="number"
                    min={data?.minPrice ?? 1}
                    max={data?.maxPrice ?? 10000000}
                    className="mt-1 block w-36 rounded border border-border bg-background px-3 py-2"
                    value={price}
                    onChange={(e) => setPrice(e.target.value)}
                    required
                  />
                </label>
                <button
                  type="submit"
                  disabled={busy}
                  className="rounded bg-brand px-4 py-2 text-sm font-medium text-white disabled:opacity-50"
                >
                  {t.characterMarket.listBtn}
                </button>
              </form>
            )}

            {(data?.myOffers?.length ?? 0) > 0 && (
              <div className="mt-6">
                <h3 className="text-sm font-semibold">{t.characterMarket.myListings}</h3>
                <ul className="mt-2 space-y-2">
                  {(data?.myOffers ?? []).map((o) => (
                    <li
                      key={o.id}
                      className="flex flex-wrap items-center justify-between gap-2 rounded border border-border/60 px-3 py-2 text-sm"
                    >
                      <span>
                        {o.player.name} - {o.price} PP
                      </span>
                      <button
                        type="button"
                        disabled={busy}
                        className="rounded border border-border px-3 py-1 text-xs hover:bg-background disabled:opacity-50"
                        onClick={() => void post("unlist", { id: o.id })}
                      >
                        {t.characterMarket.unlistBtn}
                      </button>
                    </li>
                  ))}
                </ul>
              </div>
            )}
          </section>
        )}

        <section className="mt-10">
          <h2 className="text-xl font-semibold tracking-tight">{t.characterMarket.marketTitle}</h2>
          {status === "loading" && <p className="mt-6 text-muted">{t.common.loading}</p>}
          {status === "error" && <p className="mt-6 text-muted">{t.common.error}</p>}
          {status === "ok" && offers.length === 0 && (
            <p className="mt-6 text-muted">{t.characterMarket.empty}</p>
          )}
          {status === "ok" && offers.length > 0 && (
            <div className="mt-6 grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3">
              {offers.map((o) => {
                const p = o.player;
                const eqPreview = (p.equipment ?? [])
                  .filter((s) => s.itemId != null && s.itemId > 0)
                  .slice(0, 6);
                const questsDone = (p.quests ?? []).filter((q) => q.done).length;
                return (
                  <button
                    key={o.id}
                    type="button"
                    onClick={() => setSelected(o)}
                    className="flex flex-col rounded-xl border border-border bg-panel p-4 text-left transition-colors hover:border-brand/40"
                  >
                    <div className="flex items-start gap-3">
                      <Outfit look={p.look} size="grid" alt={p.name} />
                      <div className="min-w-0 flex-1">
                        <div className="truncate font-semibold">{p.name}</div>
                        <div className="mt-0.5 text-sm text-muted">{p.vocation}</div>
                        <div className="mt-1 text-sm">
                          {t.character.level} {p.level}
                          {p.reset > 0 ? (
                            <span className="ml-1 text-muted">R{p.reset}</span>
                          ) : null}
                        </div>
                      </div>
                    </div>

                    <div className="mt-3 grid grid-cols-2 gap-x-3 gap-y-1 text-xs text-muted">
                      <span>
                        {t.character.magic}:{" "}
                        <span className="text-foreground">{p.magic ?? 0}</span>
                      </span>
                      <span>
                        {t.character.dodge}:{" "}
                        <span className="text-foreground">{p.dodge ?? 0}</span>
                      </span>
                      <span>
                        {t.character.critical}:{" "}
                        <span className="text-foreground">{p.critical ?? 0}</span>
                      </span>
                      <span>
                        {t.character.balance}:{" "}
                        <span className="text-foreground">
                          {formatMoney(p.balance ?? 0)}
                        </span>
                      </span>
                      <span>
                        {t.characterMarket.questsDone}:{" "}
                        <span className="text-foreground">
                          {questsDone}/{(p.quests ?? []).length}
                        </span>
                      </span>
                      <span>
                        {t.characterMarket.items}:{" "}
                        <span className="text-foreground">
                          {(p.inventory ?? []).length + (p.depot ?? []).length}
                        </span>
                      </span>
                    </div>

                    {eqPreview.length > 0 && (
                      <div className="mt-3 flex flex-wrap gap-1">
                        {eqPreview.map((s) => (
                          <ItemIcon
                            key={`${o.id}-eq-${s.slot}`}
                            id={s.itemId!}
                            size={28}
                            alt={`Item ${s.itemId}`}
                          />
                        ))}
                      </div>
                    )}

                    <div className="mt-auto flex items-end justify-between gap-2 pt-4">
                      <div>
                        <div className="text-sm font-semibold text-brand">{o.price} PP</div>
                        <div className="text-[11px] text-muted">{formatDate(o.created)}</div>
                      </div>
                      <span className="text-xs text-brand">{t.characterMarket.viewDetails}</span>
                    </div>
                  </button>
                );
              })}
            </div>
          )}
        </section>
      </main>

      {selected && (
        <div
          className="fixed inset-0 z-50 flex items-end justify-center bg-black/60 p-4 sm:items-center"
          onClick={() => setSelected(null)}
        >
          <div
            className="max-h-[90vh] w-full max-w-3xl overflow-y-auto rounded-xl border border-border bg-panel p-5 shadow-xl"
            onClick={(e) => e.stopPropagation()}
          >
            <div className="flex flex-wrap items-start justify-between gap-3">
              <div className="flex items-start gap-3">
                <Outfit look={selected.player.look} size="grid" alt={selected.player.name} />
                <div>
                  <h3 className="text-xl font-semibold">{selected.player.name}</h3>
                  <p className="text-sm text-muted">{selected.player.vocation}</p>
                  <p className="mt-1 text-lg font-semibold text-brand">{selected.price} PP</p>
                </div>
              </div>
              <div className="flex flex-wrap gap-2">
                {selected.isMine ? (
                  <button
                    type="button"
                    disabled={busy}
                    className="rounded border border-border px-3 py-1.5 text-sm hover:bg-background disabled:opacity-50"
                    onClick={() => void post("unlist", { id: selected.id })}
                  >
                    {t.characterMarket.unlistBtn}
                  </button>
                ) : (
                  <button
                    type="button"
                    disabled={busy || !loggedIn}
                    className="rounded bg-brand px-3 py-1.5 text-sm font-medium text-white disabled:opacity-50"
                    onClick={() => buyOffer(selected)}
                  >
                    {t.characterMarket.buyBtn}
                  </button>
                )}
                <button
                  type="button"
                  className="rounded border border-border px-3 py-1.5 text-sm hover:bg-background"
                  onClick={() => setSelected(null)}
                >
                  {t.characterMarket.close}
                </button>
              </div>
            </div>

            <OfferDetails
              player={selected.player}
              listedAt={formatDate(selected.created)}
              formatMoney={formatMoney}
            />
          </div>
        </div>
      )}

      <Footer />
    </div>
  );
}

function OfferDetails({
  player,
  listedAt,
  formatMoney,
}: {
  player: OfferPlayer;
  listedAt: string;
  formatMoney: (n: number) => string;
}) {
  const { t } = useI18n();
  const questsDone = (player.quests ?? []).filter((q) => q.done).length;

  return (
    <div className="mt-5 space-y-5">
      <Section title={t.characterMarket.stats}>
        <div className="grid gap-2 sm:grid-cols-2">
          <Row k={t.character.level} v={player.level} />
          <Row k={t.character.resets} v={player.reset} />
          <Row k={t.character.vocation} v={player.vocation} />
          <Row k={t.character.magic} v={player.magic ?? 0} />
          <Row
            k={t.character.experience}
            v={(player.experience ?? 0).toLocaleString()}
          />
          <Row
            k={t.character.sex}
            v={
              player.sex === "female"
                ? t.character.female
                : player.sex === "male"
                  ? t.character.male
                  : "-"
            }
          />
          <Row k={t.character.healthMax} v={player.healthMax ?? 0} />
          <Row k={t.character.manaMax} v={player.manaMax ?? 0} />
          <Row k={t.character.dodge} v={player.dodge ?? 0} />
          <Row k={t.character.critical} v={player.critical ?? 0} />
          <Row k={t.character.mining} v={player.mining ?? 0} />
          <Row
            k={t.character.balance}
            v={`${formatMoney(player.balance ?? 0)} ${t.character.goldCoins}`}
          />
          <Row k={t.character.residence} v={player.residence || "-"} />
          <Row
            k={t.character.accountStatus}
            v={
              player.isPremium
                ? t.character.premiumAccount
                : t.character.freeAccount
            }
          />
          <Row k={t.character.army} v={player.armyRank || player.armyLevel || "-"} />
          <Row k={t.character.frags} v={player.frags ?? 0} />
          <Row
            k={t.character.marital}
            v={
              player.marriedTo
                ? `${t.character.marriedTo} ${player.marriedTo}`
                : t.character.single
            }
          />
          <Row k={t.character.oldName} v={player.oldName || "-"} />
          <Row
            k={t.character.created}
            v={
              player.created
                ? new Date(player.created * 1000).toLocaleString()
                : "-"
            }
          />
          <Row
            k={t.character.lastLogin}
            v={
              player.lastlogin
                ? new Date(player.lastlogin * 1000).toLocaleString()
                : t.character.never
            }
          />
          <Row k={t.characterMarket.colListed} v={listedAt} />
          <Row
            k={t.characterMarket.questsDone}
            v={`${questsDone}/${(player.quests ?? []).length}`}
          />
        </div>
        {player.comment ? (
          <p className="mt-3 whitespace-pre-wrap text-sm text-muted">{player.comment}</p>
        ) : null}
        {player.resetBonus && player.reset > 0 ? (
          <p className="mt-3 text-xs text-muted">
            {t.character.resetPowerHint} +{player.resetBonus.damagePercent}% dmg / +
            {player.resetBonus.hpmpPercent}% HP/MP
          </p>
        ) : null}
      </Section>

      <div className="grid gap-5 lg:grid-cols-[auto_1fr]">
        <EquipmentGrid slots={player.equipment ?? []} title={t.character.equipment} />
        <Section title={t.character.skills}>
          {(player.skills ?? []).length === 0 ? (
            <p className="text-sm text-muted">-</p>
          ) : (
            <div className="space-y-2">
              {(player.skills ?? []).map((s) => (
                <Row key={s.name} k={s.name} v={s.value} />
              ))}
            </div>
          )}
        </Section>
      </div>

      <Section title={t.character.quests}>
        {(player.quests ?? []).length === 0 ? (
          <p className="text-sm text-muted">-</p>
        ) : (
          <div className="grid gap-1 sm:grid-cols-2">
            {(player.quests ?? []).map((q) => (
              <div key={q.name} className="flex justify-between gap-2 text-sm">
                <span className="text-muted">{q.name}</span>
                <span className={q.done ? "text-brand" : "text-muted"}>
                  {q.done ? t.characterMarket.questDone : t.characterMarket.questOpen}
                </span>
              </div>
            ))}
          </div>
        )}
      </Section>

      <ItemGrid
        title={t.characterMarket.inventory}
        items={player.inventory ?? []}
        empty={t.characterMarket.noItems}
      />
      <ItemGrid
        title={t.characterMarket.depot}
        items={player.depot ?? []}
        empty={t.characterMarket.noItems}
      />
    </div>
  );
}

function Section({ title, children }: { title: string; children: ReactNode }) {
  return (
    <div className="rounded-xl border border-border bg-background/40 p-4">
      <h4 className="mb-3 text-sm font-semibold">{title}</h4>
      {children}
    </div>
  );
}

function Row({ k, v }: { k: string; v: ReactNode }) {
  return (
    <div className="flex justify-between gap-3 border-b border-border/30 pb-1.5 text-sm">
      <span className="shrink-0 text-muted">{k}</span>
      <span className="text-right font-medium">{v}</span>
    </div>
  );
}

function EquipmentGrid({ slots, title }: { slots: EqSlot[]; title: string }) {
  const cells: (EqSlot | null)[] = [...slots];
  const feetIdx = cells.findIndex((c) => c && c.slot === 8);
  if (feetIdx >= 0) cells.splice(feetIdx, 0, null);

  return (
    <div className="shrink-0 rounded-xl border border-border bg-background/40 p-4">
      <div className="mb-2 text-center text-xs text-muted">{title}</div>
      <div
        className="inline-grid grid-cols-3 gap-0.5 rounded border border-black/80 p-1"
        style={{ backgroundImage: `url(${equipmentPanelBgUrl()})` }}
      >
        {cells.map((cell, i) => {
          if (!cell) return <div key={`empty-${i}`} className="h-9 w-9" />;
          const filled = cell.itemId != null && cell.itemId > 0;
          return (
            <div
              key={cell.slot}
              className="flex h-9 w-9 items-center justify-center"
              style={
                filled
                  ? { backgroundImage: `url(${equipmentEmptyBgUrl()})` }
                  : undefined
              }
              title={filled ? `Item ${cell.itemId}` : `Slot ${cell.slot}`}
            >
              {filled ? (
                <ItemIcon id={cell.itemId!} size={32} />
              ) : (
                // eslint-disable-next-line @next/next/no-img-element
                <img
                  src={equipmentSlotUrl(cell.slot)}
                  alt=""
                  width={32}
                  height={32}
                  className="object-contain"
                />
              )}
            </div>
          );
        })}
      </div>
    </div>
  );
}

function ItemGrid({
  title,
  items,
  empty,
}: {
  title: string;
  items: ItemStack[];
  empty: string;
}) {
  return (
    <Section title={title}>
      {items.length === 0 ? (
        <p className="text-sm text-muted">{empty}</p>
      ) : (
        <div className="flex max-h-56 flex-wrap gap-2 overflow-y-auto">
          {items.map((it) => (
            <div
              key={`${title}-${it.itemId}`}
              className="relative rounded border border-border/50 bg-panel p-1"
              title={`Item ${it.itemId} x${it.count}`}
            >
              <ItemIcon id={it.itemId} size={32} alt={`Item ${it.itemId}`} />
              {it.count > 1 ? (
                <span className="absolute bottom-0 right-0 rounded bg-black/70 px-1 text-[10px] text-white">
                  {it.count > 999 ? "999+" : it.count}
                </span>
              ) : null}
            </div>
          ))}
        </div>
      )}
    </Section>
  );
}
// END CHANGE
