import { t } from "../config/site.js";
import { fetchSessionUser, fetchSpecialOddsPublic, fetchSpecialOddsMyBets, postSpecialOddsBet } from "../auth/session.js";
import { showToast } from "../components/toast.js";
import { escapeHtml } from "../utils/escape-html.js";
import { resolveTeamLogoUrl } from "../utils/logo-url.js";

function fmtKickoffShort(sec) {
  if (!sec) return "—";
  try {
    const d = new Date(Number(sec) * 1000);
    const dd = String(d.getDate()).padStart(2, "0");
    const mm = String(d.getMonth() + 1).padStart(2, "0");
    const hh = String(d.getHours()).padStart(2, "0");
    const mi = String(d.getMinutes()).padStart(2, "0");
    return `${dd}/${mm} ${hh}:${mi}`;
  } catch {
    return "—";
  }
}

function fmtTs(sec) {
  if (!sec) return "—";
  try {
    return new Date(Number(sec) * 1000).toLocaleString(undefined, { dateStyle: "short", timeStyle: "short" });
  } catch {
    return "—";
  }
}

const cardBg = "bg-[#161b22]";
const predBox = "bg-[#1e2739] border border-[#0958d8]/28";

function iconBolt() {
  return `<svg class="so-tab-ic mr-1 inline h-3.5 w-3.5 text-[#0958d8]" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M7 2v11h3v9l7-12h-4l4-8H7z"/></svg>`;
}

function iconClock() {
  return `<svg class="so-tab-ic mr-1 inline h-3.5 w-3.5 text-slate-500" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm.5-13H11v6l5.2 3.2.8-1.3-4.5-2.7V7z"/></svg>`;
}

function iconClockSm() {
  return `<svg class="mr-1 inline h-3 w-3 shrink-0 text-[#0958d8]" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm.5-13H11v6l5.2 3.2.8-1.3-4.5-2.7V7z"/></svg>`;
}

function renderActiveCard(m, user, serverTimeSec, stakeMin, stakeMax) {
  const canBet = user && m.bettingOpen && m.matchStatus === "open";
  const kickFuture = Number(m.kickoffAt) > serverTimeSec;
  const homeSrc = resolveTeamLogoUrl(m.logoHomeUrl);
  const awaySrc = resolveTeamLogoUrl(m.logoAwayUrl);
  const homeL = homeSrc
    ? `<img src="${escapeHtml(homeSrc)}" alt="" class="h-10 w-10 rounded-full border border-white/10 bg-[#1c2128] object-contain p-0.5" loading="lazy" />`
    : `<span class="flex h-10 w-10 items-center justify-center rounded-full border border-white/10 bg-[#1c2128] text-xs font-bold text-slate-500">—</span>`;
  const awayL = awaySrc
    ? `<img src="${escapeHtml(awaySrc)}" alt="" class="h-10 w-10 rounded-full border border-white/10 bg-[#1c2128] object-contain p-0.5" loading="lazy" />`
    : `<span class="flex h-10 w-10 items-center justify-center rounded-full border border-white/10 bg-[#1c2128] text-xs font-bold text-slate-500">—</span>`;
  const pred = String(m.predictionText || "").trim();
  const oddsOne = Number(m.oddsOffered != null ? m.oddsOffered : m.oddsHome) || 0;
  const pool = Number(m.poolTotal) || 0;
  const maxP = Number(m.maxParticipants) || 0;
  const pc = Number(m.participantCount) || 0;
  const barPct = maxP > 0 ? Math.min(100, (pc / maxP) * 100) : pc > 0 ? 100 : 0;
  const partLabel = maxP > 0 ? `${pc} / ${maxP} ${t("specialOddsParticipantsShort")}` : `${pc} ${t("specialOddsParticipantsShort")}`;

  const predBlock = pred
    ? `<div class="mt-3 rounded-lg ${predBox} px-3 py-2">
         <p class="text-[9px] font-bold uppercase tracking-wider text-[#91caff]">${t("specialOddsPredictionHeading")}</p>
         <p class="mt-1 text-xs font-medium leading-snug text-white">${escapeHtml(pred)}</p>
       </div>`
    : `<div class="mt-3 rounded-lg ${predBox} px-3 py-2 opacity-90">
         <p class="text-[9px] font-bold uppercase tracking-wider text-[#91caff]">${t("specialOddsPredictionHeading")}</p>
         <p class="mt-1 text-xs text-slate-400">${t("specialOddsNoPredictionText")}</p>
       </div>`;

  const defaultStake = Math.min(Math.max(50, stakeMin), stakeMax);
  let footerBtn = "";
  if (canBet) {
    footerBtn = `<div class="mt-3 flex flex-col gap-2 sm:flex-row sm:items-end">
      <label class="flex flex-col gap-0.5 text-[10px] font-medium uppercase tracking-wide text-slate-500">
        ${t("specialOddsStakeLabel")}
        <input type="number" min="${stakeMin}" max="${stakeMax}" step="1" class="so-stake w-full rounded-lg border border-white/10 bg-[#0d1117] px-2.5 py-2 text-sm font-semibold text-white sm:w-28" value="${defaultStake}" />
      </label>
      <button type="button" class="k-btn k-btn--primary btn-site-action so-submit flex flex-1 items-center justify-center rounded-lg py-2.5 text-sm font-bold">${t("specialOddsPlayNow")}</button>
    </div>`;
  } else if (user && m.matchStatus === "open" && m.bettingFull && kickFuture) {
    footerBtn = `<div class="mt-3 flex items-center justify-center gap-2 rounded-lg border border-sky-500/25 bg-sky-500/10 py-2 text-xs font-semibold text-sky-200">${t("specialOddsQuotaFull")}</div>`;
  } else if (user) {
    footerBtn = `<div class="mt-3 flex items-center justify-center gap-1.5 rounded-lg border border-accent/22 bg-[#151518] py-2 text-xs text-slate-300">${iconClockSm()}${t("specialOddsWaitingResults")}</div>`;
  } else {
    footerBtn = `<div class="mt-3 flex items-center justify-center gap-2 rounded-lg border border-white/10 bg-[#1c2128] py-2 text-xs text-slate-400">${t("specialOddsLoginToBet")}</div>`;
  }

  return `
    <article class="special-odds-card overflow-hidden rounded-xl border border-white/[0.08] ${cardBg}" data-match-id="${m.id}">
      <div class="flex items-center justify-between border-b border-white/[0.06] px-3 py-2">
        <div class="flex items-center text-xs font-semibold text-white"><span class="mr-1 text-sm leading-none" aria-hidden="true">⚽</span>${t("specialOddsLeagueDefault")}</div>
        <div class="flex items-center text-xs font-semibold text-[#91caff]">${iconClockSm()}${escapeHtml(fmtKickoffShort(m.kickoffAt))}</div>
      </div>
      <div class="px-3 pb-3 pt-3">
        <div class="flex items-start justify-between gap-2">
          <div class="flex min-w-0 flex-1 flex-col items-center text-center">
            ${homeL}
            <p class="mt-1.5 max-w-[120px] truncate text-xs font-bold text-white">${escapeHtml(m.homeName)}</p>
          </div>
          <div class="flex shrink-0 flex-col items-center justify-center pt-1">
            <span class="flex h-7 w-7 items-center justify-center rounded-full border border-[#0958d8]/45 text-[9px] font-black text-white shadow-[inset_0_1px_0_rgba(255,255,255,0.18)]" style="background:linear-gradient(to bottom,#0958d8,#1677ff,#003eb3)">vs</span>
          </div>
          <div class="flex min-w-0 flex-1 flex-col items-center text-center">
            ${awayL}
            <p class="mt-1.5 max-w-[120px] truncate text-xs font-bold text-white">${escapeHtml(m.awayName)}</p>
          </div>
        </div>
        ${predBlock}
        <div class="mt-3 grid grid-cols-3 gap-1.5 border-t border-white/[0.06] pt-3 text-center">
          <div>
            <p class="text-lg font-black tabular-nums text-[#91caff]">${oddsOne.toFixed(2)}<span class="text-sm font-bold">x</span></p>
            <p class="mt-0.5 text-[9px] font-medium uppercase tracking-wide text-slate-500">${t("specialOddsStatOdds")}</p>
          </div>
          <div>
            <p class="text-xs font-bold tabular-nums text-white">${stakeMin}–${stakeMax}</p>
            <p class="mt-0.5 text-[9px] font-medium uppercase tracking-wide text-slate-500">${t("specialOddsStatStakeRange")}</p>
          </div>
          <div>
            <p class="text-xs font-bold tabular-nums text-white">${pool.toLocaleString()}</p>
            <p class="mt-0.5 text-[9px] font-medium uppercase tracking-wide text-slate-500">${t("specialOddsStatPool")}</p>
          </div>
        </div>
        <div class="mt-2.5">
          <p class="mb-1 text-[10px] font-medium text-slate-500">${partLabel}</p>
          <div class="h-1.5 w-full overflow-hidden rounded-full bg-white/[0.08]">
            <div class="h-full rounded-full transition-all duration-500" style="width:${barPct}%;background:linear-gradient(to right,#0958d8,#69b1ff,#91caff)"></div>
          </div>
        </div>
        ${footerBtn}
      </div>
    </article>`;
}

function renderHistoryCard(m) {
  const homeSrc = resolveTeamLogoUrl(m.logoHomeUrl);
  const awaySrc = resolveTeamLogoUrl(m.logoAwayUrl);
  const homeL = homeSrc
    ? `<img src="${escapeHtml(homeSrc)}" alt="" class="h-9 w-9 rounded-full border border-white/10 bg-[#1c2128] object-contain p-0.5 opacity-95" loading="lazy" />`
    : "";
  const awayL = awaySrc
    ? `<img src="${escapeHtml(awaySrc)}" alt="" class="h-9 w-9 rounded-full border border-white/10 bg-[#1c2128] object-contain p-0.5 opacity-95" loading="lazy" />`
    : "";
  const pred = String(m.predictionText || "").trim();
  const oddsOne = Number(m.oddsOffered != null ? m.oddsOffered : m.oddsHome) || 0;
  const pool = Number(m.poolTotal) || 0;
  const st = String(m.matchStatus || "");
  const statusLabel =
    st === "cancelled" ? t("specialOddsStatusCancelled") : st === "settled" ? t("specialOddsStatusSettled") : st;
  const score = m.homeGoals != null && m.awayGoals != null ? `${m.homeGoals}-${m.awayGoals}` : "—";
  const res =
    m.result && st === "settled"
      ? `${t("specialOddsResult")}: ${escapeHtml(m.result)} (${score})`
      : st === "cancelled"
        ? t("specialOddsCancelledHint")
        : "";

  return `
    <article class="overflow-hidden rounded-xl border border-white/[0.07] bg-[#131820]">
      <div class="flex items-center justify-between border-b border-white/[0.06] px-3 py-2">
        <span class="rounded border border-white/10 bg-white/[0.04] px-1.5 py-0.5 text-[9px] font-bold uppercase tracking-wide text-slate-400">${escapeHtml(statusLabel)}</span>
        <span class="text-[11px] text-slate-500">${escapeHtml(fmtKickoffShort(m.kickoffAt))}</span>
      </div>
      <div class="px-3 pb-3 pt-2.5">
        <div class="flex items-center justify-between gap-2">
          <div class="flex min-w-0 flex-1 flex-col items-center">${homeL}<p class="mt-1 truncate text-[11px] font-bold text-white">${escapeHtml(m.homeName)}</p></div>
          <span class="shrink-0 text-[9px] font-black text-[#91caff]">VS</span>
          <div class="flex min-w-0 flex-1 flex-col items-center">${awayL}<p class="mt-1 truncate text-[11px] font-bold text-white">${escapeHtml(m.awayName)}</p></div>
        </div>
        ${pred ? `<p class="mt-2 line-clamp-2 text-center text-[11px] text-slate-400">${escapeHtml(pred)}</p>` : ""}
        <div class="mt-2 flex items-center justify-between text-[10px] text-slate-500">
          <span class="font-bold text-[#91caff]">${oddsOne.toFixed(2)}x</span>
          <span>${t("specialOddsStatPool")}: <strong class="text-slate-300">${pool.toLocaleString()}</strong></span>
        </div>
        ${res ? `<p class="mt-2 text-center text-xs font-medium text-accent-bright/90">${res}</p>` : ""}
      </div>
    </article>`;
}

export async function renderSpecialOddsPage(outlet) {
  const [user, pub, mine] = await Promise.all([
    fetchSessionUser(),
    fetchSpecialOddsPublic(),
    fetchSpecialOddsMyBets(),
  ]);
  const matches = pub.ok && Array.isArray(pub.data?.matches) ? pub.data.matches : [];
  const history = pub.ok && Array.isArray(pub.data?.history) ? pub.data.history : [];
  const bets = mine.ok && Array.isArray(mine.data?.bets) ? mine.data.bets : [];
  const coins = user ? Number(user.coins) || 0 : 0;
  const serverT = pub.ok && pub.data?.serverTime != null ? Number(pub.data.serverTime) : Math.floor(Date.now() / 1000);
  const stakeMin = pub.ok && pub.data?.stakeMin != null ? Number(pub.data.stakeMin) : 10;
  const stakeMax = pub.ok && pub.data?.stakeMax != null ? Number(pub.data.stakeMax) : 100000;

  const matchCards = matches.map((m) => renderActiveCard(m, user, serverT, stakeMin, stakeMax)).join("");
  const historyCards = history.map((m) => renderHistoryCard(m)).join("");

  const betRows = bets
    .map((b) => {
      const st = String(b.status || "");
      const stLabel =
        st === "won"
          ? t("specialOddsStatusWon")
          : st === "lost"
            ? t("specialOddsStatusLost")
            : st === "void"
              ? t("specialOddsStatusVoid")
              : t("specialOddsStatusPending");
      const ptxt = String(b.predictionText || "").trim();
      const predShort = ptxt.length > 72 ? `${escapeHtml(ptxt.slice(0, 72))}…` : escapeHtml(ptxt);
      return `<tr class="border-b border-white/[0.06]">
        <td class="px-1.5 py-1.5 align-top text-[10px] text-slate-400">${fmtTs(b.createdAt)}</td>
        <td class="px-1.5 py-1.5 align-top text-[11px] text-slate-200">
          <div>${escapeHtml(b.homeName)} — ${escapeHtml(b.awayName)}</div>
          ${ptxt ? `<div class="mt-0.5 max-w-[200px] text-[10px] text-slate-500">${predShort}</div>` : ""}
        </td>
        <td class="px-1.5 py-1.5 align-top font-mono text-[10px] font-semibold text-[#91caff]">${Number(b.oddsApplied).toFixed(2)}x</td>
        <td class="px-1.5 py-1.5 align-top font-mono text-[10px]">${b.stake}</td>
        <td class="px-1.5 py-1.5 align-top text-[10px] font-semibold ${st === "won" ? "text-accent-bright" : st === "lost" ? "text-rose-300" : "text-slate-400"}">${stLabel}</td>
      </tr>`;
    })
    .join("");

  const myBetsBlock =
    user && bets.length
      ? `<details class="group rounded-xl border border-white/[0.08] bg-[#161b22] open:shadow-sm">
        <summary class="flex cursor-pointer list-none items-center justify-between gap-2 px-3 py-2.5 text-sm font-semibold text-white marker:content-none [&::-webkit-details-marker]:hidden">
          <span>${t("specialOddsMyBets")} <span class="font-normal text-slate-500">(${bets.length})</span></span>
          <svg class="h-4 w-4 shrink-0 text-slate-500 transition group-open:rotate-180" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M6 9l6 6 6-6"/></svg>
        </summary>
        <div class="max-h-56 overflow-x-auto overflow-y-auto border-t border-white/[0.06] px-2 pb-2 pt-1">
          <table class="w-full min-w-[420px] text-left text-[11px]">
            <thead class="sticky top-0 bg-[#161b22] text-[9px] font-bold uppercase tracking-wide text-slate-500">
              <tr><th class="pb-1 pt-1">${t("specialOddsColTime")}</th><th class="pb-1 pt-1">${t("specialOddsColMatch")}</th><th class="pb-1 pt-1">${t("specialOddsColOdds")}</th><th class="pb-1 pt-1">${t("specialOddsColStake")}</th><th class="pb-1 pt-1">${t("specialOddsColStatus")}</th></tr>
            </thead>
            <tbody>${betRows}</tbody>
          </table>
        </div>
      </details>`
      : "";

  const balanceBadge = user
    ? `<p class="inline-flex shrink-0 items-center gap-1.5 self-start rounded-xl border border-white/10 bg-white/[0.04] px-3 py-2 text-sm text-slate-200 sm:self-center"><span class="text-slate-500">${t("headerCoinBalance")}</span><strong class="font-bold tabular-nums text-white">${coins.toLocaleString()}</strong></p>`
    : "";

  outlet.innerHTML = `
    <section class="special-odds-page relative w-full min-w-0 space-y-8 px-1 pb-4">
      <header class="relative overflow-hidden rounded-3xl border border-white/[0.08] bg-[#1e2739] p-8 shadow-panel ring-1 ring-white/[0.04] sm:p-10">
        <div class="pointer-events-none absolute inset-0 bg-[radial-gradient(ellipse_80%_60%_at_100%_0%,rgba(22,119,255,0.09),transparent)]"></div>
        <div class="relative flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between">
          <div class="min-w-0 flex-1 space-y-3 text-left">
            <span class="inline-flex items-center gap-2 rounded-full border border-accent/25 bg-accent/10 px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.18em] text-accent-bright">${escapeHtml(t("specialOddsEyebrow"))}</span>
            <h1 class="text-3xl font-bold tracking-tight text-white sm:text-4xl">${escapeHtml(t("specialOddsTitle"))}</h1>
            <p class="max-w-2xl text-sm leading-relaxed text-slate-400 sm:text-base">${escapeHtml(t("specialOddsSubtitle"))}</p>
          </div>
          ${balanceBadge}
        </div>
      </header>

      <div class="flex gap-0 border-b border-white/[0.08]">
        <button type="button" class="k-tab so-tab group flex flex-1 items-center justify-center border-b-2 border-[#0958d8] py-2 text-xs font-bold text-white" data-so-tab="active">
          ${iconBolt()}${t("specialOddsTabActive")}
        </button>
        <button type="button" class="k-tab so-tab group flex flex-1 items-center justify-center border-b-2 border-transparent py-2 text-xs font-medium text-slate-500 hover:text-slate-300" data-so-tab="history">
          ${iconClock()}${t("specialOddsTabHistory")}${history.length ? `<span class="ml-1 rounded bg-white/10 px-1 py-px text-[10px] text-slate-400">${history.length}</span>` : ""}
        </button>
      </div>

      <div id="so-panel-active" class="so-panel space-y-3">
        ${matches.length ? `<div class="space-y-3">${matchCards}</div>` : `<p class="rounded-xl border border-white/[0.06] bg-[#161b22] px-3 py-6 text-center text-xs text-slate-500">${t("specialOddsNoMatches")}</p>`}
      </div>

      <div id="so-panel-history" class="so-panel hidden space-y-3">
        ${history.length ? `<div class="space-y-2.5">${historyCards}</div>` : `<p class="rounded-xl border border-white/[0.06] bg-[#161b22] px-3 py-6 text-center text-xs text-slate-500">${t("specialOddsNoHistory")}</p>`}
      </div>

      ${myBetsBlock}
    </section>
  `;

  outlet.querySelectorAll(".so-tab").forEach((btn) => {
    btn.addEventListener("click", () => {
      const tab = btn.getAttribute("data-so-tab") || "active";
      const pa = outlet.querySelector("#so-panel-active");
      const ph = outlet.querySelector("#so-panel-history");
      outlet.querySelectorAll(".so-tab").forEach((b) => {
        b.classList.remove("border-[#0958d8]", "font-bold", "text-white");
        b.classList.add("border-transparent", "font-medium", "text-slate-500");
        b.querySelectorAll(".so-tab-ic").forEach((ic) => {
          ic.classList.remove("text-[#0958d8]");
          ic.classList.add("text-slate-500");
        });
      });
      btn.classList.add("border-[#0958d8]", "font-bold", "text-white");
      btn.classList.remove("font-medium", "text-slate-500");
      btn.querySelectorAll(".so-tab-ic").forEach((ic) => {
        ic.classList.add("text-[#0958d8]");
        ic.classList.remove("text-slate-500");
      });
      if (tab === "history") {
        pa?.classList.add("hidden");
        ph?.classList.remove("hidden");
      } else {
        ph?.classList.add("hidden");
        pa?.classList.remove("hidden");
      }
    });
  });

  outlet.querySelectorAll(".so-submit").forEach((btn) => {
    btn.addEventListener("click", async () => {
      const card = btn.closest("[data-match-id]");
      if (!card) return;
      const mid = parseInt(card.getAttribute("data-match-id") || "0", 10);
      const stakeEl = card.querySelector(".so-stake");
      const stake = stakeEl && "value" in stakeEl ? parseInt(String(stakeEl.value), 10) : 0;
      const res = await postSpecialOddsBet({ matchId: mid, stake });
      if (res.ok && res.data?.ok) {
        showToast(t("specialOddsBetOk"));
        void globalThis.__siteRefreshUser?.();
        await renderSpecialOddsPage(outlet);
      } else {
        const err = res.data?.error || "fail";
        showToast(
          err === "insufficient_coins"
            ? t("specialOddsErrCoins")
            : err === "already_bet"
              ? t("specialOddsErrAlready")
              : err === "kickoff_passed"
                ? t("specialOddsErrKickoff")
                : err === "participants_full"
                  ? t("specialOddsErrFull")
                  : t("specialOddsErrGeneric"),
        );
      }
    });
  });
}
