import { createFileRoute } from "@tanstack/react-router";
import { useMemo, useState } from "react";
import { useQuery } from "@tanstack/react-query";
import { useServerFn } from "@tanstack/react-start";
import { Download, Search, X } from "lucide-react";
import { TransactionItem } from "@/components/TransactionItem";
import { listTransactions } from "@/lib/transactions.functions";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { formatNaira, formatDate, txTypeLabel } from "@/lib/format";
import { Money } from "@/components/Money";

export const Route = createFileRoute("/app/history")({
  head: () => ({ meta: [{ title: "Transaction Center — Billsline" }] }),
  component: HistoryPage,
});

const TYPES = [
  "funding",
  "transfer_in",
  "transfer_out",
  "airtime",
  "data",
  "cable",
  "electricity",
  "exam_pin",
  "referral_bonus",
  "admin_credit",
  "admin_debit",
  "reversal",
  "withdrawal",
] as const;

const STATUSES = ["pending", "success", "failed", "reversed"] as const;

function toCsv(rows: any[]): string {
  const headers = [
    "date",
    "reference",
    "external_reference",
    "type",
    "status",
    "amount",
    "fee",
    "description",
  ];
  const esc = (v: unknown) => {
    const s = v == null ? "" : String(v);
    return /[",\n]/.test(s) ? `"${s.replace(/"/g, '""')}"` : s;
  };
  const lines = [headers.join(",")];
  for (const r of rows) {
    lines.push(
      [
        r.created_at,
        r.reference,
        r.external_reference ?? "",
        r.type,
        r.status,
        r.amount,
        r.fee ?? 0,
        r.description ?? "",
      ]
        .map(esc)
        .join(","),
    );
  }
  return lines.join("\n");
}

function downloadCsv(rows: any[]) {
  const blob = new Blob([toCsv(rows)], { type: "text/csv;charset=utf-8" });
  const url = URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.download = `billsline-transactions-${new Date().toISOString().slice(0, 10)}.csv`;
  a.click();
  URL.revokeObjectURL(url);
}

function HistoryPage() {
  const fetchTx = useServerFn(listTransactions);
  const [search, setSearch] = useState("");
  const [type, setType] = useState<string>("all");
  const [status, setStatus] = useState<string>("all");

  const filters = useMemo(
    () => ({
      limit: 200,
      ...(search.trim() ? { search: search.trim() } : {}),
      ...(type !== "all" ? { type: type as (typeof TYPES)[number] } : {}),
      ...(status !== "all" ? { status: status as (typeof STATUSES)[number] } : {}),
    }),
    [search, type, status],
  );

  const { data = [], isLoading } = useQuery({
    queryKey: ["transactions", filters],
    queryFn: () => fetchTx({ data: filters }),
  });

  const totals = useMemo(() => {
    const credit = new Set([
      "funding",
      "transfer_in",
      "referral_bonus",
      "admin_credit",
      "reversal",
    ]);
    let inflow = 0;
    let outflow = 0;
    for (const t of data) {
      const amt = Number(t.amount);
      if (t.status !== "success") continue;
      if (credit.has(t.type)) inflow += amt;
      else outflow += amt;
    }
    return { inflow, outflow, count: data.length };
  }, [data]);

  const hasFilters = search || type !== "all" || status !== "all";

  return (
    <div className="space-y-4 p-4">
      <div>
        <h1 className="text-xl font-bold text-foreground">Transaction Center</h1>
        <p className="text-xs text-muted-foreground">
          Search, filter and export every transaction on your account.
        </p>
      </div>

      <div className="grid grid-cols-3 gap-2">
        <div className="rounded-xl bg-card p-3 shadow-card">
          <div className="text-[10px] uppercase text-muted-foreground">Inflow</div>
          <div className="mt-0.5 truncate text-sm font-bold text-success">
            <Money value={totals.inflow} />
          </div>
        </div>
        <div className="rounded-xl bg-card p-3 shadow-card">
          <div className="text-[10px] uppercase text-muted-foreground">Outflow</div>
          <div className="mt-0.5 truncate text-sm font-bold text-foreground">
            <Money value={totals.outflow} />
          </div>
        </div>
        <div className="rounded-xl bg-card p-3 shadow-card">
          <div className="text-[10px] uppercase text-muted-foreground">Count</div>
          <div className="mt-0.5 text-sm font-bold">{totals.count}</div>
        </div>
      </div>

      <div className="space-y-2">
        <div className="relative">
          <Search className="pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
          <Input
            value={search}
            onChange={(e) => setSearch(e.target.value)}
            placeholder="Search reference or description"
            className="pl-9"
          />
        </div>
        <div className="grid grid-cols-2 gap-2">
          <Select value={type} onValueChange={setType}>
            <SelectTrigger>
              <SelectValue placeholder="All types" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="all">All types</SelectItem>
              {TYPES.map((t) => (
                <SelectItem key={t} value={t}>
                  {txTypeLabel[t] ?? t}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
          <Select value={status} onValueChange={setStatus}>
            <SelectTrigger>
              <SelectValue placeholder="All statuses" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="all">All statuses</SelectItem>
              {STATUSES.map((s) => (
                <SelectItem key={s} value={s}>
                  {s}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>
        <div className="flex gap-2">
          {hasFilters && (
            <Button
              variant="ghost"
              size="sm"
              onClick={() => {
                setSearch("");
                setType("all");
                setStatus("all");
              }}
            >
              <X className="mr-1 h-3.5 w-3.5" /> Clear
            </Button>
          )}
          <Button
            variant="outline"
            size="sm"
            className="ml-auto"
            disabled={data.length === 0}
            onClick={() => downloadCsv(data)}
          >
            <Download className="mr-1 h-3.5 w-3.5" /> Export CSV
          </Button>
        </div>
      </div>

      <ul className="space-y-2">
        {isLoading ? (
          Array.from({ length: 6 }).map((_, i) => (
            <li
              key={i}
              className="h-16 animate-pulse rounded-xl bg-muted/60"
              aria-hidden
            />
          ))
        ) : data.length === 0 ? (
          <li className="rounded-xl bg-card p-6 text-center text-sm text-muted-foreground shadow-card">
            No transactions match your filters.
            <div className="mt-1 text-[10px] text-muted-foreground">
              {formatDate(new Date().toISOString())}
            </div>
          </li>
        ) : (
          data.map((tx) => <TransactionItem key={tx.id} tx={tx as any} />)
        )}
      </ul>
    </div>
  );
}
