// @File: src/pages/admin/cms/CmsBilling.tsx
// @Desc: Billing & revenue overview. Aggregates all orders by payment status,
//        shows daily revenue trend, paid invoice-style list, refund totals.
//        Supports search, status filter, date range filter and CSV export.
import { useEffect, useMemo, useState } from "react";
import {
  DollarSign,
  Download,
  Search,
  TrendingUp,
  RefreshCw,
  FileText,
} from "lucide-react";
import { createClient } from "@metagptx/web-sdk";
import CmsLayout from "./CmsLayout";
import { PageHeader } from "./ui";
import LoadingSpinner from "@/components/LoadingSpinner";
import { toast } from "sonner";

const client = createClient();

interface OrderRow {
  id: number;
  order_number: string;
  status: string;
  payment_status: string | null;
  subtotal: number | null;
  shipping_cost: number | null;
  tax: number | null;
  total: number | null;
  currency: string | null;
  billing_email: string | null;
  payment_method: string | null;
  stripe_session_id: string | null;
  created_at: string | null;
}

const PAYMENT_STATUS_COLORS: Record<string, string> = {
  paid: "bg-emerald-100 text-emerald-700",
  pending: "bg-amber-100 text-amber-700",
  failed: "bg-rose-100 text-rose-700",
  refunded: "bg-slate-200 text-slate-700",
};

function fmtMoney(v: number | null | undefined): string {
  return `SAR ${Number(v || 0).toFixed(2)}`;
}

function toCsv(rows: OrderRow[]): string {
  const header = [
    "invoice",
    "order_number",
    "status",
    "payment_status",
    "subtotal",
    "shipping",
    "tax",
    "total",
    "currency",
    "billing_email",
    "payment_method",
    "created_at",
  ];
  const lines = [header.join(",")];
  for (const o of rows) {
    lines.push(
      [
        `INV-${String(o.id).padStart(6, "0")}`,
        o.order_number,
        o.status,
        o.payment_status ?? "",
        (o.subtotal ?? 0).toFixed(2),
        (o.shipping_cost ?? 0).toFixed(2),
        (o.tax ?? 0).toFixed(2),
        (o.total ?? 0).toFixed(2),
        o.currency ?? "SAR",
        JSON.stringify(o.billing_email ?? ""),
        o.payment_method ?? "",
        o.created_at ?? "",
      ].join(",")
    );
  }
  return lines.join("\n");
}

export default function CmsBilling() {
  const [orders, setOrders] = useState<OrderRow[]>([]);
  const [loading, setLoading] = useState(true);
  const [search, setSearch] = useState("");
  const [paymentStatus, setPaymentStatus] = useState<string>("all");
  const [range, setRange] = useState<"7d" | "30d" | "90d" | "all">("30d");

  const load = async () => {
    setLoading(true);
    try {
      const res = await client.entities.orders.queryAll({
        query: {},
        sort: "-id",
        limit: 2000,
      });
      setOrders(((res?.data?.items || []) as OrderRow[]) || []);
    } catch (e) {
      const msg = e instanceof Error ? e.message : "Failed to load billing data.";
      toast.error(msg);
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    load();
  }, []);

  const cutoff = useMemo(() => {
    if (range === "all") return null;
    const days = range === "7d" ? 7 : range === "30d" ? 30 : 90;
    const d = new Date();
    d.setDate(d.getDate() - days);
    return d.toISOString();
  }, [range]);

  const scoped = useMemo(() => {
    if (!cutoff) return orders;
    return orders.filter((o) => (o.created_at ?? "") >= cutoff);
  }, [orders, cutoff]);

  const kpis = useMemo(() => {
    let gross = 0;
    let paid = 0;
    let pending = 0;
    let refunded = 0;
    let paidCount = 0;
    for (const o of scoped) {
      const total = Number(o.total || 0);
      gross += total;
      if (o.payment_status === "paid") {
        paid += total;
        paidCount += 1;
      } else if (o.payment_status === "pending") {
        pending += total;
      } else if (o.payment_status === "refunded" || o.status === "refunded") {
        refunded += total;
      }
    }
    return {
      gross,
      paid,
      pending,
      refunded,
      paidCount,
      avgOrder: paidCount > 0 ? paid / paidCount : 0,
    };
  }, [scoped]);

  const dailySeries = useMemo(() => {
    // Build a per-day revenue series (paid orders only) for the selected range.
    const map = new Map<string, number>();
    for (const o of scoped) {
      if (o.payment_status !== "paid") continue;
      const day = (o.created_at ?? "").slice(0, 10);
      if (!day) continue;
      map.set(day, (map.get(day) || 0) + Number(o.total || 0));
    }
    const days = Array.from(map.entries())
      .sort((a, b) => (a[0] < b[0] ? -1 : 1))
      .slice(-30);
    const max = days.reduce((m, [, v]) => Math.max(m, v), 0);
    return { days, max };
  }, [scoped]);

  const filtered = useMemo(() => {
    const q = search.trim().toLowerCase();
    return scoped.filter((o) => {
      if (paymentStatus !== "all" && (o.payment_status || "") !== paymentStatus) return false;
      if (!q) return true;
      return (
        o.order_number.toLowerCase().includes(q) ||
        (o.billing_email || "").toLowerCase().includes(q) ||
        (o.stripe_session_id || "").toLowerCase().includes(q)
      );
    });
  }, [scoped, search, paymentStatus]);

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

  return (
    <CmsLayout>
      <PageHeader
        icon={<DollarSign className="w-6 h-6" />}
        title="Billing & Revenue"
        description="Invoices, paid totals, refunds and daily revenue trend. Export anything as CSV."
      />

      {/* Range selector */}
      <div className="mb-4 flex flex-wrap items-center gap-2">
        {(["7d", "30d", "90d", "all"] as const).map((r) => (
          <button
            key={r}
            onClick={() => setRange(r)}
            className={`text-xs font-bold px-3 py-1.5 rounded-full border ${
              range === r
                ? "bg-[#0b6e3e] text-white border-[#0b6e3e]"
                : "bg-white text-slate-700 border-slate-200 hover:bg-slate-50"
            }`}
          >
            {r === "all" ? "All time" : `Last ${r}`}
          </button>
        ))}
        <button
          onClick={load}
          className="ml-auto inline-flex items-center gap-2 text-sm font-semibold px-3 py-1.5 rounded-lg border border-slate-200 bg-white hover:bg-slate-50"
        >
          <RefreshCw className="w-4 h-4" /> Refresh
        </button>
      </div>

      {/* KPIs */}
      <div className="grid grid-cols-2 md:grid-cols-5 gap-3 mb-5">
        <div className="bg-white border border-slate-200 rounded-2xl p-4">
          <div className="text-slate-500 text-xs uppercase font-bold tracking-wider">
            Gross
          </div>
          <div className="text-xl font-extrabold text-slate-900 mt-1">
            {fmtMoney(kpis.gross)}
          </div>
        </div>
        <div className="bg-white border border-slate-200 rounded-2xl p-4">
          <div className="text-slate-500 text-xs uppercase font-bold tracking-wider">
            Paid
          </div>
          <div className="text-xl font-extrabold text-emerald-600 mt-1">
            {fmtMoney(kpis.paid)}
          </div>
        </div>
        <div className="bg-white border border-slate-200 rounded-2xl p-4">
          <div className="text-slate-500 text-xs uppercase font-bold tracking-wider">
            Pending
          </div>
          <div className="text-xl font-extrabold text-amber-600 mt-1">
            {fmtMoney(kpis.pending)}
          </div>
        </div>
        <div className="bg-white border border-slate-200 rounded-2xl p-4">
          <div className="text-slate-500 text-xs uppercase font-bold tracking-wider">
            Refunded
          </div>
          <div className="text-xl font-extrabold text-rose-600 mt-1">
            {fmtMoney(kpis.refunded)}
          </div>
        </div>
        <div className="bg-white border border-slate-200 rounded-2xl p-4">
          <div className="text-slate-500 text-xs uppercase font-bold tracking-wider">
            Avg order
          </div>
          <div className="text-xl font-extrabold text-slate-900 mt-1">
            {fmtMoney(kpis.avgOrder)}
          </div>
        </div>
      </div>

      {/* Revenue trend */}
      <div className="bg-white border border-slate-200 rounded-2xl p-4 mb-5">
        <div className="flex items-center gap-2 mb-3">
          <TrendingUp className="w-4 h-4 text-[#0b6e3e]" />
          <h3 className="font-bold text-slate-900">Daily revenue (paid)</h3>
        </div>
        {dailySeries.days.length === 0 ? (
          <div className="text-slate-500 text-sm py-6 text-center">
            No paid orders in this range yet.
          </div>
        ) : (
          <div className="flex items-end gap-1 h-32">
            {dailySeries.days.map(([day, v]) => {
              const pct = dailySeries.max > 0 ? (v / dailySeries.max) * 100 : 0;
              return (
                <div
                  key={day}
                  className="flex-1 flex flex-col items-center justify-end gap-1 min-w-0"
                  title={`${day}: ${fmtMoney(v)}`}
                >
                  <div
                    className="w-full rounded-t bg-[#0b6e3e]"
                    style={{ height: `${Math.max(pct, 4)}%` }}
                  />
                  <div className="text-[9px] text-slate-400 truncate w-full text-center">
                    {day.slice(5)}
                  </div>
                </div>
              );
            })}
          </div>
        )}
      </div>

      {/* Filters */}
      <div className="mb-4 flex flex-col md:flex-row gap-3 md:items-center">
        <div className="relative max-w-md flex-1">
          <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-slate-400" />
          <input
            value={search}
            onChange={(e) => setSearch(e.target.value)}
            placeholder="Search invoice, order # or email…"
            className="w-full pl-9 pr-3 py-2 text-sm border border-slate-200 rounded-lg bg-white"
          />
        </div>
        <select
          value={paymentStatus}
          onChange={(e) => setPaymentStatus(e.target.value)}
          className="text-sm border border-slate-200 rounded-lg px-3 py-2 bg-white font-semibold"
        >
          <option value="all">All payment statuses</option>
          <option value="paid">Paid</option>
          <option value="pending">Pending</option>
          <option value="failed">Failed</option>
          <option value="refunded">Refunded</option>
        </select>
        <button
          onClick={exportCsv}
          className="inline-flex items-center gap-2 text-sm font-semibold px-3 py-2 rounded-lg border border-slate-200 bg-white hover:bg-slate-50"
        >
          <Download className="w-4 h-4" /> Export CSV
        </button>
      </div>

      {/* Invoices */}
      {loading ? (
        <div className="py-16 flex justify-center">
          <LoadingSpinner />
        </div>
      ) : filtered.length === 0 ? (
        <div className="bg-white border border-slate-200 rounded-2xl p-10 text-center text-slate-500">
          No invoices match your filters.
        </div>
      ) : (
        <div className="bg-white border border-slate-200 rounded-2xl overflow-hidden">
          <div className="overflow-x-auto">
            <table className="w-full text-sm">
              <thead className="bg-slate-50 text-slate-600 text-xs uppercase tracking-wider">
                <tr>
                  <th className="text-left px-4 py-3">Invoice</th>
                  <th className="text-left px-4 py-3">Order</th>
                  <th className="text-left px-4 py-3">Customer</th>
                  <th className="text-left px-4 py-3">Date</th>
                  <th className="text-left px-4 py-3">Payment</th>
                  <th className="text-right px-4 py-3">Total</th>
                </tr>
              </thead>
              <tbody className="divide-y divide-slate-100">
                {filtered.map((o) => (
                  <tr key={o.id} className="hover:bg-slate-50">
                    <td className="px-4 py-3 font-mono text-xs font-semibold text-slate-700">
                      <FileText className="w-3.5 h-3.5 inline mr-1 text-slate-400" />
                      INV-{String(o.id).padStart(6, "0")}
                    </td>
                    <td className="px-4 py-3 font-semibold text-slate-900">
                      {o.order_number}
                    </td>
                    <td className="px-4 py-3 text-slate-700">
                      {o.billing_email || "—"}
                    </td>
                    <td className="px-4 py-3 text-slate-600">
                      {o.created_at ? o.created_at.slice(0, 10) : "—"}
                    </td>
                    <td className="px-4 py-3">
                      <span
                        className={`text-[10px] uppercase font-bold px-2 py-0.5 rounded-full ${
                          PAYMENT_STATUS_COLORS[o.payment_status || ""] ||
                          "bg-slate-100 text-slate-700"
                        }`}
                      >
                        {o.payment_status || "—"}
                      </span>
                      {o.payment_method && (
                        <span className="ml-2 text-[10px] text-slate-500">
                          {o.payment_method}
                        </span>
                      )}
                    </td>
                    <td className="px-4 py-3 text-right font-bold text-[#0b6e3e]">
                      {fmtMoney(o.total)}
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>
      )}
    </CmsLayout>
  );
}