"use client";

import { useState, useEffect, useCallback, useMemo } from "react";
import Link from "next/link";
import PayWithUsdBalanceButton from "@/components/PayWithUsdBalanceButton";
import ThemedLayout from "@/components/layouts/ThemedLayout";
import { getMerchantBtcAddress, isMerchantBtcConfigured } from "@/lib/merchantBtc";
import { useAccount } from "@/contexts/AccountContext";

const PRIZES = [
  { place: "1st", prize: "500 LUX Credits", sub: "Applied to your CyberLux handle." },
  { place: "2nd", prize: "250 LUX Credits", sub: "Applied to your CyberLux handle." },
  { place: "3rd", prize: "100 LUX Credits", sub: "Applied to your CyberLux handle." },
  { place: "Runner-up ×5", prize: "Handler Pass", sub: "Digital access pass upgrade." },
];

const DRAW_INTERVAL_MS = 7 * 24 * 60 * 60 * 1000; // 7 days in ms
const DRAW_EPOCH = new Date("2026-04-14T00:00:00Z").getTime();

function getNextDraw() {
  const now = Date.now();
  const elapsed = now - DRAW_EPOCH;
  const cycles = Math.floor(elapsed / DRAW_INTERVAL_MS);
  return DRAW_EPOCH + (cycles + 1) * DRAW_INTERVAL_MS;
}

function formatRemaining(ms: number) {
  if (ms <= 0) return "00:00:00";
  const totalSec = Math.floor(ms / 1000);
  const d = Math.floor(totalSec / 86400);
  const h = Math.floor((totalSec % 86400) / 3600);
  const m = Math.floor((totalSec % 3600) / 60);
  const s = totalSec % 60;
  if (d > 0) return `${d}d ${h.toString().padStart(2, "0")}:${m.toString().padStart(2, "0")}:${s.toString().padStart(2, "0")}`;
  return `${h.toString().padStart(2, "0")}:${m.toString().padStart(2, "0")}:${s.toString().padStart(2, "0")}`;
}

const TICKET_PRICE_BTC = "0.0001";
const TICKET_ENTRY_KEY = "cyberlux-raffle-entries-v1";

type Entry = { handle: string; txid: string; ts: string };

function loadEntries(): Entry[] {
  if (typeof window === "undefined") return [];
  try {
    return JSON.parse(localStorage.getItem(TICKET_ENTRY_KEY) ?? "[]") as Entry[];
  } catch { return []; }
}

function saveEntries(e: Entry[]) {
  if (typeof window === "undefined") return;
  localStorage.setItem(TICKET_ENTRY_KEY, JSON.stringify(e));
}

export default function RafflePage() {
  const { user } = useAccount();
  const [remaining, setRemaining] = useState(0);
  const [entries, setEntries] = useState<Entry[]>([]);
  const [txid, setTxid] = useState("");
  const [status, setStatus] = useState<"idle" | "success" | "error">("idle");
  const [errMsg, setErrMsg] = useState("");
  const [btcUsd, setBtcUsd] = useState<number | null>(null);
  const btcAddr = getMerchantBtcAddress();
  const btcReady = isMerchantBtcConfigured();

  const ticketUsd = useMemo(() => {
    const r = btcUsd ?? 96000;
    const v = parseFloat(TICKET_PRICE_BTC) * r;
    return Math.round(v * 100) / 100;
  }, [btcUsd]);

  useEffect(() => {
    let cancelled = false;
    void (async () => {
      try {
        const res = await fetch(
          "https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd",
          { cache: "no-store" },
        );
        const j = (await res.json()) as { bitcoin?: { usd?: number } };
        if (!cancelled && j.bitcoin?.usd && Number.isFinite(j.bitcoin.usd)) setBtcUsd(j.bitcoin.usd);
      } catch {
        if (!cancelled) setBtcUsd(96000);
      }
    })();
    return () => {
      cancelled = true;
    };
  }, []);

  const registerBalanceTicket = useCallback(() => {
    const t = `balance-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
    const entry: Entry = {
      handle: user?.username ?? "anon",
      txid: t,
      ts: new Date().toISOString(),
    };
    const cur = loadEntries();
    const updated = [...cur, entry];
    saveEntries(updated);
    setEntries(updated);
    setStatus("success");
    setTimeout(() => setStatus("idle"), 4000);
  }, [user?.username]);

  useEffect(() => {
    setEntries(loadEntries());
    const tick = () => setRemaining(getNextDraw() - Date.now());
    tick();
    const id = setInterval(tick, 1000);
    return () => clearInterval(id);
  }, []);

  const handleEnter = useCallback(
    (e: React.FormEvent) => {
      e.preventDefault();
      const t = txid.trim();
      if (!t || t.length < 20) {
        setErrMsg("Enter a valid Bitcoin transaction ID.");
        setStatus("error");
        return;
      }
      if (entries.some((x) => x.txid === t)) {
        setErrMsg("This txid has already been submitted.");
        setStatus("error");
        return;
      }
      const entry: Entry = {
        handle: user?.username ?? "anon",
        txid: t,
        ts: new Date().toISOString(),
      };
      const updated = [...entries, entry];
      setEntries(updated);
      saveEntries(updated);
      setTxid("");
      setStatus("success");
      setTimeout(() => setStatus("idle"), 4000);
    },
    [txid, entries, user]
  );

  const myEntries = user ? entries.filter((e) => e.handle === user.username) : [];

  return (
    <ThemedLayout theme="terminal" title="Shadow Raffle">
      <div className="mx-auto max-w-4xl px-4 pt-12 pb-20 font-mono text-white">
        <div className="border-4 border-white bg-[#000080] p-10 shadow-[10px_10px_0_rgba(255,255,255,0.15)]">
          <div className="mb-2 text-center text-[10px] uppercase tracking-widest text-white/50">
            ⚠ Prize pool is in LUX credits — not BTC. Entry fee covers onchain raffle infrastructure.
          </div>
          <h1 className="mb-10 text-center text-4xl font-black uppercase tracking-tighter">
            Weekly Shadow Raffle
          </h1>

          <div className="mb-10 grid grid-cols-1 gap-6 sm:grid-cols-3">
            <div className="border-2 border-white p-5 text-center">
              <div className="mb-1 text-[10px] uppercase text-white/60">Next Draw</div>
              <div className="text-2xl font-black tabular-nums text-white">
                {formatRemaining(remaining)}
              </div>
            </div>
            <div className="border-2 border-white p-5 text-center">
              <div className="mb-1 text-[10px] uppercase text-white/60">Ticket Price</div>
              <div className="text-2xl font-black">{TICKET_PRICE_BTC} BTC</div>
              <div className="mt-1 text-[11px] text-[#00ff41]/80">≈ ${ticketUsd.toFixed(2)} USD @ spot</div>
            </div>
            <div className="border-2 border-white p-5 text-center">
              <div className="mb-1 text-[10px] uppercase text-white/60">Entries This Round</div>
              <div className="text-2xl font-black">{entries.length}</div>
            </div>
          </div>

          <div className="mb-10">
            <h2 className="mb-4 border-b-2 border-white pb-2 text-xl font-black uppercase">Prize Breakdown</h2>
            <div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
              {PRIZES.map((p) => (
                <div key={p.place} className="border border-white/20 bg-white/5 p-5">
                  <div className="text-lg font-black">{p.place}: {p.prize}</div>
                  <p className="mt-1 text-xs text-white/60">{p.sub}</p>
                </div>
              ))}
            </div>
          </div>

          <div className="border-4 border-dashed border-white/40 p-8">
            <h3 className="mb-2 text-lg font-black uppercase">Enter Your Ticket</h3>
            <p className="mb-4 text-xs text-white/70 leading-relaxed">
              Send exactly {TICKET_PRICE_BTC} BTC to the address below. After at least 1 confirmation, paste your
              transaction ID here. Your handle is registered as an entrant. Draw happens at the countdown above.
            </p>

            {btcReady ? (
              <div className="mb-5 break-all border-2 border-white bg-black px-4 py-3 font-mono text-xs text-[#00ff41]">
                {btcAddr}
              </div>
            ) : (
              <div className="mb-5 border-2 border-amber-500/50 bg-black px-4 py-3 text-xs text-amber-300">
                Merchant address not configured. Set NEXT_PUBLIC_MERCHANT_BTC_ADDRESS in .env.local.
              </div>
            )}

            <form onSubmit={handleEnter} className="flex flex-col gap-4 sm:flex-row">
              <input
                type="text"
                value={txid}
                onChange={(e) => setTxid(e.target.value)}
                placeholder="Bitcoin transaction ID (64 hex chars)…"
                className="flex-1 border-2 border-white bg-black px-4 py-3 text-sm text-white focus:border-[#00ff41] focus:outline-none"
                maxLength={64}
              />
              <button
                type="submit"
                disabled={!btcReady}
                className="border-2 border-white bg-white px-6 py-3 font-black uppercase text-black transition-all hover:bg-[#00ff41] disabled:opacity-40"
              >
                Register Entry
              </button>
            </form>

            {status === "success" && (
              <p className="mt-3 text-sm text-[#00ff41]">✓ Entry registered for @{user?.username ?? "anon"}. Good luck.</p>
            )}
            {status === "error" && (
              <p className="mt-3 text-sm text-red-400">{errMsg}</p>
            )}

            <div className="mt-6 border-2 border-[#00ff41]/40 bg-black/50 p-4">
              <h4 className="mb-2 text-sm font-black uppercase text-[#00ff41]">Pay with USD balance</h4>
              <p className="mb-3 text-[11px] text-white/60 leading-relaxed">
                Same ticket — charges your Bitcoin-funded USD balance at ≈ ${ticketUsd.toFixed(2)} (live BTC spot). No separate txid needed.
              </p>
              <PayWithUsdBalanceButton
                amountUsd={ticketUsd}
                title="Shadow Raffle ticket"
                description="Weekly draw entry"
                luxBonus={50}
                onSuccess={registerBalanceTicket}
                size="sm"
              />
            </div>

            {!user && (
              <p className="mt-3 text-xs text-white/50">
                <Link href="/sign-in?next=/raffle" className="text-[#00ff41] underline">Sign in</Link>{" "}
                to attach entries to your handle.
              </p>
            )}

            {myEntries.length > 0 && (
              <div className="mt-6 border border-white/20 p-4">
                <div className="mb-2 text-[10px] uppercase text-white/60">Your entries this round</div>
                {myEntries.map((e) => (
                  <div key={e.txid} className="text-xs text-[#00ff41]/70 truncate">
                    {e.txid.slice(0, 12)}…{e.txid.slice(-8)} · {new Date(e.ts).toLocaleDateString()}
                  </div>
                ))}
              </div>
            )}
          </div>
        </div>

        <div className="mt-6 text-center text-[10px] text-white/30 leading-relaxed">
          Draw is via deterministic hash of the winning block header at the draw timestamp. Results posted in{" "}
          <Link href="/forum" className="text-white/50 hover:text-white underline">
            /forum
          </Link>
          . Prizes are LUX credits — no fiat or BTC payout. Entry fees are non-refundable.
        </div>
      </div>
    </ThemedLayout>
  );
}
