import { useMemo } from "react";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { FileText, TrendingDown, AlertTriangle, CheckCircle2 } from "lucide-react";
import { addDays, differenceInCalendarDays, format } from "date-fns";
import { toast } from "sonner";
import OrderInvoiceButton from "@/components/admin/OrderInvoiceButton";
import { grossCents } from "@/lib/vat";
import { useAuth } from "@/hooks/useAuth";

interface Props {
  companyId: string;
  /** training_companies.payment_terms_days — null/undefined falls back to 30. */
  paymentTermsDays?: number | null;
}

const DEFAULT_TERMS_DAYS = 30;
const INVOICE_METHODS = new Set(["invoice", "credit", "company_credit"]);

const fmtMoney = (cents: number) =>
  `£${(cents / 100).toLocaleString("en-GB", { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;

const csrfToken = () =>
  (document.querySelector('meta[name="csrf-token"]') as HTMLMetaElement | null)?.content ?? "";

interface OrderRow {
  id: string;
  course_id: string;
  created_at: string;
  start_date: string;
  price_cents: number;
  refund_cents: number | null;
  discount_code: string | null;
  discount_cents: number | null;
  payment_method: string;
  status: string;
  customer_name: string;
  customer_email: string;
  customer_phone?: string | null;
  num_delegates: number;
  payment_received_at?: string | null;
  courses?: { title: string } | null;
  training_companies?: { name: string } | null;
}

const CompanyInvoicesTab = ({ companyId, paymentTermsDays }: Props) => {
  const queryClient = useQueryClient();
  const termsDays = paymentTermsDays ?? DEFAULT_TERMS_DAYS;
  // Settling an invoice is a platform-staff action (matches the API gate).
  const { hasAnyRole } = useAuth();
  const canMarkPaid = hasAnyRole(["sys_admin", "sys_manager"]);

  const { data: orders, isLoading } = useQuery({
    queryKey: ["company-invoice-orders", companyId],
    queryFn: async (): Promise<OrderRow[]> => {
      const res = await fetch(`/api/admin/orders?company_id=${encodeURIComponent(companyId)}`);
      if (!res.ok) return [];
      return res.json();
    },
  });

  // Invoice = any order placed on account terms. Amounts are shown gross
  // (inc VAT) — that's what the company owes; price_cents is stored ex-VAT.
  const invoices = useMemo(() => {
    const now = new Date();
    return (orders ?? [])
      .filter((o) => INVOICE_METHODS.has(o.payment_method))
      .map((o) => {
        const dueDate = addDays(new Date(o.created_at), termsDays);
        const outstanding = o.status === "pending" || o.status === "confirmed";
        const unpaidNet = Math.max(0, o.price_cents - (o.refund_cents ?? 0));
        return {
          ...o,
          dueDate,
          outstanding,
          isOverdue: outstanding && now > dueDate,
          daysOverdue: Math.max(0, differenceInCalendarDays(now, dueDate)),
          unpaidGross: grossCents(unpaidNet),
          totalGross: grossCents(o.price_cents),
        };
      });
  }, [orders, termsDays]);

  const totals = useMemo(() => {
    const live = invoices.filter((i) => i.status !== "cancelled" && i.status !== "refunded");
    const outstanding = invoices.filter((i) => i.outstanding);
    const overdue = outstanding.filter((i) => i.isOverdue);
    const paid = invoices.filter((i) => i.status === "paid" || i.status === "completed");
    return {
      invoicedTotal: live.reduce((s, i) => s + i.totalGross, 0),
      invoicedCount: live.length,
      outstandingTotal: outstanding.reduce((s, i) => s + i.unpaidGross, 0),
      outstandingCount: outstanding.length,
      overdueTotal: overdue.reduce((s, i) => s + i.unpaidGross, 0),
      overdueCount: overdue.length,
      paidTotal: paid.reduce((s, i) => s + i.unpaidGross, 0),
      paidCount: paid.length,
    };
  }, [invoices]);

  const markPaidMutation = useMutation({
    mutationFn: async (orderId: string) => {
      const res = await fetch(`/api/admin/orders/${orderId}/mark-paid`, {
        method: "POST",
        headers: { "Content-Type": "application/json", "X-CSRF-TOKEN": csrfToken() },
        body: JSON.stringify({}),
      });
      if (!res.ok) {
        const err = await res.json().catch(() => ({ error: "Failed" }));
        throw new Error(err.error || "Failed to mark paid");
      }
      return res.json();
    },
    onSuccess: () => {
      toast.success("Invoice marked as paid");
      queryClient.invalidateQueries({ queryKey: ["company-invoice-orders", companyId] });
      // Paying an invoice releases reserved credit on the company record.
      queryClient.invalidateQueries({ queryKey: ["company", companyId] });
      queryClient.invalidateQueries({ queryKey: ["finance-overview"] });
      queryClient.invalidateQueries({ queryKey: ["finance-outstanding-invoices"] });
    },
    onError: (err: Error) => toast.error(err.message || "Failed to mark paid"),
  });

  const statusBadge = (inv: (typeof invoices)[number]) => {
    if (inv.status === "cancelled") {
      return <Badge variant="outline" className="bg-red-500/10 text-red-600 border-red-500/30">Cancelled</Badge>;
    }
    if (inv.status === "refunded") {
      return <Badge variant="outline" className="bg-purple-500/10 text-purple-600 border-purple-500/30">Refunded</Badge>;
    }
    if (inv.outstanding) {
      return inv.isOverdue ? (
        <Badge variant="destructive">Overdue</Badge>
      ) : (
        <Badge variant="outline" className="bg-yellow-500/10 text-yellow-600 border-yellow-500/30">Awaiting Payment</Badge>
      );
    }
    return <Badge variant="outline" className="bg-green-500/10 text-green-600 border-green-500/30">Paid</Badge>;
  };

  return (
    <div className="space-y-6">
      {/* KPIs */}
      <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
        <div className="bg-card border border-border rounded-xl p-4">
          <div className="flex items-center gap-2 text-muted-foreground text-xs mb-1">
            <FileText className="w-3.5 h-3.5" /> Total Invoiced
          </div>
          <p className="text-2xl font-bold text-foreground">{fmtMoney(totals.invoicedTotal)}</p>
          <p className="text-xs text-muted-foreground mt-1">{totals.invoicedCount} invoice{totals.invoicedCount === 1 ? "" : "s"}</p>
        </div>
        <div className="bg-card border border-border rounded-xl p-4">
          <div className="flex items-center gap-2 text-muted-foreground text-xs mb-1">
            <TrendingDown className="w-3.5 h-3.5" /> Outstanding
          </div>
          <p className="text-2xl font-bold text-foreground">{fmtMoney(totals.outstandingTotal)}</p>
          <p className="text-xs text-muted-foreground mt-1">{totals.outstandingCount} unpaid</p>
        </div>
        <div className="bg-card border border-border rounded-xl p-4">
          <div className="flex items-center gap-2 text-muted-foreground text-xs mb-1">
            <AlertTriangle className="w-3.5 h-3.5" /> Overdue
          </div>
          <p className={`text-2xl font-bold ${totals.overdueTotal > 0 ? "text-destructive" : "text-foreground"}`}>
            {fmtMoney(totals.overdueTotal)}
          </p>
          <p className="text-xs text-muted-foreground mt-1">{totals.overdueCount} invoice{totals.overdueCount === 1 ? "" : "s"}</p>
        </div>
        <div className="bg-card border border-border rounded-xl p-4">
          <div className="flex items-center gap-2 text-muted-foreground text-xs mb-1">
            <CheckCircle2 className="w-3.5 h-3.5" /> Paid
          </div>
          <p className="text-2xl font-bold text-foreground">{fmtMoney(totals.paidTotal)}</p>
          <p className="text-xs text-muted-foreground mt-1">{totals.paidCount} settled</p>
        </div>
      </div>

      {/* Invoice list */}
      <div className="bg-card border border-border rounded-xl overflow-hidden">
        <div className="px-4 py-3 border-b border-border flex items-center justify-between">
          <h2 className="text-base font-semibold text-foreground flex items-center gap-2">
            <FileText className="w-4 h-4" /> Invoices
          </h2>
          <span className="text-xs text-muted-foreground">
            {invoices.length} invoice{invoices.length === 1 ? "" : "s"} · {termsDays}-day terms
          </span>
        </div>
        {isLoading ? (
          <p className="text-muted-foreground text-center py-8">Loading…</p>
        ) : invoices.length === 0 ? (
          <p className="text-muted-foreground text-center py-8">No invoices for this company yet.</p>
        ) : (
          <Table className="text-sm">
            <TableHeader>
              <TableRow>
                <TableHead>Invoice #</TableHead>
                <TableHead>Date</TableHead>
                <TableHead>Course</TableHead>
                <TableHead>Customer</TableHead>
                <TableHead>Due</TableHead>
                <TableHead className="text-right">Total (inc VAT)</TableHead>
                <TableHead>Status</TableHead>
                <TableHead className="text-right">Actions</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {invoices.map((inv) => (
                <TableRow key={inv.id}>
                  <TableCell className="font-mono text-xs whitespace-nowrap">
                    INV-{inv.id.slice(0, 8).toUpperCase()}
                  </TableCell>
                  <TableCell className="whitespace-nowrap text-xs">
                    {format(new Date(inv.created_at), "dd MMM yy")}
                  </TableCell>
                  <TableCell className="max-w-[220px]">
                    <div className="font-medium truncate">{inv.courses?.title || "—"}</div>
                    <div className="text-xs text-muted-foreground">
                      {format(new Date(inv.start_date + "T00:00:00"), "dd MMM yyyy")} · {inv.num_delegates} delegate{inv.num_delegates === 1 ? "" : "s"}
                    </div>
                  </TableCell>
                  <TableCell className="text-xs">
                    <div>{inv.customer_name}</div>
                    <div className="text-muted-foreground">{inv.customer_email}</div>
                  </TableCell>
                  <TableCell className="text-xs whitespace-nowrap">
                    {inv.status === "cancelled" || inv.status === "refunded" ? (
                      <span className="text-muted-foreground">—</span>
                    ) : (
                      <>
                        <span className={inv.isOverdue ? "text-destructive font-semibold" : ""}>
                          {format(inv.dueDate, "dd MMM yy")}
                        </span>
                        {inv.isOverdue && (
                          <Badge variant="destructive" className="ml-1.5 text-[10px] h-4 px-1.5">
                            {inv.daysOverdue}d
                          </Badge>
                        )}
                      </>
                    )}
                  </TableCell>
                  <TableCell className="text-right font-semibold whitespace-nowrap">
                    {fmtMoney(inv.totalGross)}
                    {(inv.refund_cents ?? 0) > 0 && (
                      <div className="text-xs font-normal text-muted-foreground">
                        -{fmtMoney(grossCents(inv.refund_cents ?? 0))} refunded
                      </div>
                    )}
                  </TableCell>
                  <TableCell>
                    {statusBadge(inv)}
                    {inv.payment_received_at && (
                      <div className="text-[10px] text-muted-foreground mt-0.5 whitespace-nowrap">
                        {format(new Date(inv.payment_received_at), "dd MMM yy")}
                      </div>
                    )}
                  </TableCell>
                  <TableCell className="text-right">
                    <div className="flex items-center justify-end gap-2">
                      <OrderInvoiceButton
                        order={inv}
                        courseTitle={inv.courses?.title}
                        companyName={inv.training_companies?.name}
                      />
                      {inv.outstanding && canMarkPaid && (
                        <Button
                          size="sm"
                          variant="outline"
                          className="h-7 text-xs"
                          disabled={markPaidMutation.isPending && markPaidMutation.variables === inv.id}
                          onClick={() => markPaidMutation.mutate(inv.id)}
                        >
                          <CheckCircle2 className="w-3.5 h-3.5 mr-1" />
                          {markPaidMutation.isPending && markPaidMutation.variables === inv.id ? "Marking…" : "Mark Paid"}
                        </Button>
                      )}
                    </div>
                  </TableCell>
                </TableRow>
              ))}
            </TableBody>
          </Table>
        )}
      </div>
    </div>
  );
};

export default CompanyInvoicesTab;
