import React, { useEffect, useMemo, useState } from "react";
import {
  getCurrentUser,
  getMyTransactions,   
  getMyTopups,         
  createTopup,         
} from "../../api";
import {
  FiCreditCard,
  FiSave,
  FiCopy,
  FiCheck,
  FiExternalLink,
  FiRefreshCw,
} from "react-icons/fi";

/* ---------- Geld & PayPal ---------- */

function parseEuroToCents(input) {
  if (typeof input !== "string") return null;
  const s = input.trim().replace(/\s/g, "").replace(",", ".");
  if (!s) return null;
  const n = Number(s);
  if (!isFinite(n)) return null;
  const cents = Math.round(n * 100);
  return cents > 0 ? cents : null;
}
function genCode5() {
  return String(Math.floor(Math.random() * 100000)).padStart(5, "0");
}
function buildPaypalUrl(amountCents, code, topupId) {
  if (!amountCents || amountCents <= 0) return null;
  const amountEuro = (amountCents / 100).toFixed(2);
  const me = import.meta.env.VITE_PAYPAL_ME && String(import.meta.env.VITE_PAYPAL_ME).trim();
  const receiver = import.meta.env.VITE_PAYPAL_RECEIVER && String(import.meta.env.VITE_PAYPAL_RECEIVER).trim();
  if (me) {
    return `https://www.paypal.me/${encodeURIComponent(me)}/${encodeURIComponent(amountEuro)}?locale.x=de_DE&country.x=DE&note=${encodeURIComponent("Bacchus Top-Up " + (code || ""))}`;
  }
  if (receiver) {
    const qs = new URLSearchParams({
      cmd: "_xclick",
      business: receiver,
      currency_code: "EUR",
      amount: amountEuro,
      item_name: `Bacchus Top-Up ${code || ""}`,
      no_note: "1",
      custom: `topup:${topupId || ""}|code:${code || ""}`,
      notify_url: `${window.location.origin.replace(/\/$/, "")}/api/paypal/ipn`,
      return: `${window.location.origin}/management/transactions?ok=1`,
      cancel_return: `${window.location.origin}/management/transactions?canceled=1`,
    });
    return `https://www.paypal.com/cgi-bin/webscr?${qs.toString()}`;
  }
  return null;
}

/* ---------- Zeitformat (warum 2h verzug??) ---------- */
const fmtBerlin = new Intl.DateTimeFormat("de-DE", {
  dateStyle: "short",
  timeStyle: "medium",
  timeZone: "Europe/Berlin",
});
const toISOish = (s) =>
  typeof s === "string"
    ? s.replace(" ", "T").replace(/(\.\d{3})\d+([Z+-])/, "$1$2").replace(/([+-]\d{2})$/, "$1:00")
    : s;
function parseTs(s) { const d = new Date(toISOish(s)); return isNaN(d) ? null : d; }
const fmtTs = (s) => { const d = parseTs(s); return d ? fmtBerlin.format(d) : "—"; };

/* ---------- Normalisierung ---------- */
function normStatus(s) {
  if (!s) return "";
  if (typeof s === "string") return s.toLowerCase();
  if (typeof s === "object") {
    const v = s.value ?? s.status ?? s.state ?? s.name;
    return typeof v === "string" ? v.toLowerCase() : "";
  }
  return String(s).toLowerCase();
}
function normNote(n) {
  if (n == null) return "—";
  if (typeof n === "string") return n;
  if (typeof n === "object") {
    if (typeof n.text === "string") return n.text;
    if (typeof n.note === "string") return n.note;
    try { return JSON.stringify(n); } catch { return String(n); }
  }
  return String(n);
}

/* ---------- Mapper ---------- */
function mapTopup(t) {
  return {
    id: t.id ?? t.topup_id ?? `topup-${t.code || Math.random()}`,
    ts: t.created_at ?? t.timestamp,
    amount_cents: typeof t.amount_cents === "number" ? t.amount_cents : null,
    status: normStatus(t.status ?? t.state),   
    note: normNote(t.note ?? t.code),          
    source: "topup",
  };
}
function mapAdjustment(tx) {
  const cents =
    (typeof tx.amount_cents === "number" && tx.amount_cents) ??
    (typeof tx.delta_cents === "number" && tx.delta_cents) ?? null;
  return {
    id: tx.id ?? tx.tx_id ?? tx.transaction_id ?? `adj-${Math.random()}`,
    ts: tx.created_at ?? tx.timestamp,
    amount_cents: cents,
    status: normStatus(tx.status ?? tx.state),
    note: normNote(tx.note ?? tx.info),
    source: "adjustment",
  };
}

// Saldo-Anpassungen
function looksLikeAdjustment(tx) {
  const type = String(tx.type || "").toLowerCase();
  if (type === "booking" || type === "topup") return false;
  if (type.includes("adjust") || type.includes("balance")) return true;

  const hasBalanceFields = tx.new_balance_cents != null || tx.old_balance_cents != null;
  const hasProductFields = tx.product_id != null || tx.product != null;
  const hasPriceFields = tx.total_cents != null || tx.price_cents != null;
  const amount =
    (typeof tx.amount_cents === "number" && tx.amount_cents) ??
    (typeof tx.delta_cents === "number" && tx.delta_cents) ?? null;

  if (hasProductFields || hasPriceFields) return false;
  if (typeof amount === "number" && amount < 0) return false;
  return hasBalanceFields || typeof amount === "number";
}

/* ---------- Komponente ---------- */
export default function TransactionPage() {
  const [loading, setLoading] = useState(true);
  const [err, setErr] = useState(null);
  const [balanceCents, setBalanceCents] = useState(null);

  const euroFmt = new Intl.NumberFormat("de-DE", { style: "currency", currency: "EUR" });
  const [topupId, setTopupId] = useState(null);

  const [amountInput, setAmountInput] = useState("");
  const amountCents = useMemo(() => parseEuroToCents(amountInput), [amountInput]);
  const [saved, setSaved] = useState(false);
  const [code, setCode] = useState("");
  const [copied, setCopied] = useState(false);

  const [txLoading, setTxLoading] = useState(true);
  const [txErr, setTxErr] = useState(null);
  const [rows, setRows] = useState([]);

  useEffect(() => {
    let alive = true;
    (async () => {
      try {
        const me = await getCurrentUser();
        if (!alive) return;
        setBalanceCents(typeof me?.balance_cents === "number" ? me.balance_cents : null);
      } catch (e) {
        if (alive) setErr(e?.message || "Konnte Guthaben nicht laden.");
      } finally {
        if (alive) setLoading(false);
      }
    })();
    reloadTx();
    return () => { alive = false; };
  }, []);

  async function reloadTx() {
    setTxLoading(true);
    setTxErr(null);
    try {
      const [topups, txs] = await Promise.all([
        getMyTopups({ limit: 50, offset: 0 }).catch(() => []),
        getMyTransactions({ limit: 100, offset: 0 }).catch(() => []),
      ]);

      const topupRows = (Array.isArray(topups) ? topups : (topups.items || [])).map(mapTopup);

      const adjustRows = (Array.isArray(txs) ? txs : (txs.items || []))
        .filter((t) => {
          const type = String(t.type || "").toLowerCase();
          if (type === "booking" || type === "topup") return false;
          return looksLikeAdjustment(t);
        })
        .map(mapAdjustment);

      const merged = [...topupRows, ...adjustRows]
        .filter((r) => r.amount_cents != null)
        .sort((a, b) => (parseTs(b.ts)?.getTime() ?? 0) - (parseTs(a.ts)?.getTime() ?? 0))
        .slice(0, 20);

      setRows(merged);
    } catch (e) {
      setTxErr(e?.message || "Konnte Guthaben-Transaktionen nicht laden.");
    } finally {
      setTxLoading(false);
    }
  }

  const readyToSave = amountCents != null && amountCents > 0;
  const paypalUrl = useMemo(
    () => (saved ? buildPaypalUrl(amountCents, code, topupId) : null),
    [saved, amountCents, code, topupId]
  );

  async function onSave() {
    if (!readyToSave) return;
    const newCode = genCode5();
    setSaved(true);
    setCode(newCode);
    setCopied(false);
    try {
      const created = await createTopup(amountCents, newCode); 
      setTopupId(created?.id ?? null);
      await reloadTx();
    } catch (e) {
      setTxErr(e?.message || "Top-up konnte nicht angelegt werden.");
    }
  }
  async function onCopy() {
    try { await navigator.clipboard.writeText(code); setCopied(true); setTimeout(() => setCopied(false), 1200); } catch {}
  }

  return (
    <div className="p-4 md:p-6" style={{ contentVisibility: "auto", containIntrinsicSize: "1000px" }}>
      <h1 className="text-white/90 text-xl font-semibold mb-4">Transaktion / Aufladen</h1>

      {loading && <div className="text-white/60">Lade…</div>}
      {err && !loading && <div className="text-red-300">{String(err)}</div>}

      {!loading && !err && (
        <div className="grid gap-4 md:grid-cols-3">
          {/* Guthaben */}
          <Card title="Aktuelles Guthaben" icon={<FiCreditCard className="text-white/80" />}>
            <div className="text-3xl font-mono">
              {typeof balanceCents === "number" ? euroFmt.format(balanceCents / 100) : "—"}
            </div>
          </Card>

          {/* Aufladen */}
          <Card className="md:col-span-2" title="Aufladen">
            <div className="flex flex-wrap items-end gap-3">
              <label className="block">
                <div className="text-white/70 text-sm mb-1">Betrag (EUR)</div>
                <input
                  inputMode="decimal"
                  placeholder="z. B. 10,00"
                  value={amountInput}
                  onChange={(e) => setAmountInput(e.target.value)}
                  className="w-44 px-3 py-2 rounded-xl bg-white/10 border border-white/15 text-white placeholder:text-white/40 focus:outline-none focus:ring-2 focus:ring-cyan-500"
                />
              </label>

              <div className="text-white/60 text-sm mb-2">
                {amountCents ? `= ${euroFmt.format(amountCents / 100)}` : "—"}
              </div>

              <button
                onClick={onSave}
                disabled={!readyToSave}
                className="inline-flex items-center gap-2 px-4 py-2 rounded-xl border disabled:opacity-50 bg-cyan-600 hover:bg-cyan-700 border-cyan-400/40 text-white font-semibold"
                title="Topup speichern"
              >
                <FiSave /> Speichern
              </button>
            </div>
            <div className="text-white/50 text-xs mt-3">
              Betrag eingeben und „Speichern“ klicken. 
            </div>
          </Card>

          {/* Zahlungsdetails */}
          {saved && (
            <Card className="md:col-span-3" title="Zahlungsdetails">
              <div className="flex flex-wrap items-center gap-4">
                <button type="button" onClick={onCopy}
                  className="group relative overflow-hidden rounded-xl border border-white/15 bg-white/5 hover:bg-white/10 px-4 py-3"
                  title="Code kopieren">
                  <div className="text-white/60 text-xs mb-1">Dein Code</div>
                  <div className="flex items-center gap-2">
                    <span className="text-2xl font-mono tracking-widest">{code}</span>
                    {copied ? <FiCheck className="text-emerald-300" /> : <FiCopy className="text-white/70 group-hover:text-white" />}
                  </div>
                  <div className="text-white/40 text-xs mt-1">Tippen/Klicken zum Kopieren</div>
                </button>

                <a
                  href={paypalUrl || "#"}
                  onClick={(e) => { if (!paypalUrl) e.preventDefault(); }}
                  target="_blank" rel="noopener noreferrer"
                  className={`inline-flex items-center gap-2 px-4 py-3 rounded-xl border ${
                    paypalUrl ? "bg-blue-600 hover:bg-blue-700 border-blue-400/40 text-white"
                              : "bg-white/5 border-white/15 text-white/40 cursor-not-allowed"
                  }`}
                  title={paypalUrl ? "Zu PayPal" : "PayPal-Link nicht konfiguriert"}
                >
                  <FiExternalLink /><span>PayPal</span>
                </a>

                <div className="text-white/50 text-xs">
                  Betrag: {amountCents ? euroFmt.format(amountCents / 100) : "—"}
                </div>
              </div>
            </Card>
          )}

          {/* Tabelle */}
          <Card className="md:col-span-3" title="Letzte Guthaben-Transaktionen">
            <div className="flex items-center justify-between mb-2">
              <div className="text-white/60 text-sm">Zeigt die letzten 20 Einträge.</div>
              <button onClick={reloadTx}
                className="inline-flex items-center gap-2 px-3 py-1.5 rounded-lg bg-white/10 border border-white/15 text-white/90 hover:bg-white/15"
                title="Neu laden">
                <FiRefreshCw /> Neu laden
              </button>
            </div>

            {txLoading ? (
              <div className="text-white/60">Lade…</div>
            ) : txErr ? (
              <div className="text-red-300">{txErr}</div>
            ) : (
              <div className="overflow-x-auto">
                <table className="min-w-full text-sm text-white/80">
                  <thead className="text-white/60">
                    <tr>
                      <th className="text-left py-2 pr-4">Transaktions-ID</th>
                      <th className="text-left py-2 pr-4">Zeit</th>
                      <th className="text-left py-2 pr-4">Betrag</th>
                      <th className="text-left py-2 pr-4">Status</th>
                      <th className="text-left py-2 pr-4">Notiz</th>
                    </tr>
                  </thead>
                  <tbody>
                    {rows.map((r) => {
                      const amount = r.amount_cents != null ? euroFmt.format(r.amount_cents / 100) : "—";
                      const s = r.status || "";
                      const status =
                        s === "approved" || s === "completed" || s === "success" || s === "confirmed"
                          ? "genehmigt"
                          : s === "pending" || s === "waiting"
                          ? "wartend"
                          : s === "rejected"
                          ? "abgelehnt"
                          : (r.status || "—");
                      return (
                        <tr key={`${r.source}-${r.id}`} className="border-t border-white/10">
                          <td className="py-2 pr-4 font-mono">{r.id}</td>
                          <td className="py-2 pr-4 font-mono">{fmtTs(r.ts)}</td>
                          <td className="py-2 pr-4 font-mono">{amount}</td>
                          <td className="py-2 pr-4">
                            {status === "genehmigt" ? (
                              <span className="text-emerald-300">genehmigt</span>
                            ) : status === "wartend" ? (
                              <span className="text-amber-300">wartend</span>
                            ) : status === "abgelehnt" ? (
                              <span className="text-rose-300">abgelehnt</span>
                            ) : (
                              <span className="text-white/70">{status}</span>
                            )}
                          </td>
                          <td className="py-2 pr-4">{r.note ?? "—"}</td>
                        </tr>
                      );
                    })}
                    {!rows.length && (
                      <tr><td className="py-6 pr-4 text-white/60" colSpan={5}>Keine Einträge vorhanden.</td></tr>
                    )}
                  </tbody>
                </table>
              </div>
            )}
          </Card>
        </div>
      )}
    </div>
  );
}

/* ---------- UI-Baustein ---------- */
function Card({ title, icon, children, className = "" }) {
  return (
    <div className={`rounded-2xl bg-white/5 backdrop-blur-md border border-cyan-400/25 shadow-[0_0_0_1px_rgba(34,211,238,0.06)] p-5 ${className}`}>
      {(title || icon) && (
        <div className="flex items-center gap-2 mb-3">
          {icon}
          <h2 className="text-white/90 font-semibold">{title}</h2>
        </div>
      )}
      {children}
    </div>
  );
}
