import { useState } from "react";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { Card, CardContent } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
  Table, TableBody, TableCell, TableHead, TableHeader, TableRow,
} from "@/components/ui/table";
import {
  Dialog, DialogContent, DialogDescription, DialogFooter,
  DialogHeader, DialogTitle,
} from "@/components/ui/dialog";
import { useFeesPlans, useStudentFees, useFeesPlan } from "@/hooks/queries";
import { feesService } from "@/services/fees.service";
import { useToast } from "@/hooks/use-toast";
import { Search, DollarSign, CreditCard, Eye, FileText, Wallet, Loader2 } from "lucide-react";
import type { FeesPlan } from "@/types/fees";

function stateBadge(state: string) {
  const s = (state || "").toLowerCase();
  if (s === "draft") return <Badge variant="secondary">Draft</Badge>;
  if (s === "invoice")
    return <Badge variant="outline" className="border-blue-500 text-blue-600">Invoiced</Badge>;
  if (s === "cancel") return <Badge variant="destructive">Cancelled</Badge>;
  return <Badge variant="outline" className="capitalize">{state || "—"}</Badge>;
}

function paymentBadge(state?: string) {
  const s = (state || "").toLowerCase();
  if (s === "paid")
    return <Badge className="bg-emerald-500 hover:bg-emerald-500/90 text-white">Paid</Badge>;
  if (s === "in_payment")
    return <Badge className="bg-amber-500 hover:bg-amber-500/90 text-white">In payment</Badge>;
  if (s === "partial")
    return <Badge className="bg-sky-500 hover:bg-sky-500/90 text-white">Partial</Badge>;
  if (s === "reversed") return <Badge variant="destructive">Reversed</Badge>;
  if (s === "not_paid")
    return <Badge variant="outline" className="border-rose-500 text-rose-600">Not paid</Badge>;
  return <Badge variant="outline" className="capitalize">{state || "—"}</Badge>;
}

function money(n: number | undefined, currency?: string) {
  const v = Number(n ?? 0);
  return `${v.toFixed(2)}${currency ? ` ${currency}` : ""}`;
}

export default function AdminFees() {
  const [search, setSearch] = useState("");
  const [section, setSection] = useState<"plans" | "student">("plans");
  const [detailId, setDetailId] = useState<number | null>(null);
  const [paymentFor, setPaymentFor] = useState<FeesPlan | null>(null);
  const [paymentAmount, setPaymentAmount] = useState("");
  const [paymentMemo, setPaymentMemo] = useState("");
  const { toast } = useToast();
  const qc = useQueryClient();

  const plansQ = useFeesPlans({ q: search || undefined, size: 200 });
  const feesQ = useStudentFees({ q: search || undefined, size: 200 });
  const detailQ = useFeesPlan(detailId ?? 0);

  const plans = (plansQ.data?.data ?? plansQ.data?.items ?? []) as FeesPlan[];
  const fees = (feesQ.data?.data ?? feesQ.data?.items ?? []) as FeesPlan[];
  const loading = section === "plans" ? plansQ.isLoading : feesQ.isLoading;

  const invalidateAll = () => {
    qc.invalidateQueries({ queryKey: ["fees-plans"] });
    qc.invalidateQueries({ queryKey: ["student-fees"] });
    if (detailId) qc.invalidateQueries({ queryKey: ["fees-plan", detailId] });
  };

  const invoiceMut = useMutation({
    mutationFn: (id: number) => feesService.createInvoice(id),
    onSuccess: () => {
      toast({ title: "Invoice created", description: "Accounting entry has been generated." });
      invalidateAll();
    },
    onError: (e: Error) => toast({ title: "Invoice failed", description: e.message, variant: "destructive" }),
  });

  const paymentMut = useMutation({
    mutationFn: async () => {
      if (!paymentFor) throw new Error("No plan selected");
      const amt = Number(paymentAmount);
      return feesService.registerPayment(paymentFor.id, {
        amount: Number.isFinite(amt) && amt > 0 ? amt : undefined,
        memo: paymentMemo || undefined,
      });
    },
    onSuccess: () => {
      toast({ title: "Payment registered", description: "The invoice balance has been updated." });
      setPaymentFor(null);
      setPaymentAmount("");
      setPaymentMemo("");
      invalidateAll();
    },
    onError: (e: Error) => toast({ title: "Payment failed", description: e.message, variant: "destructive" }),
  });

  if (loading) {
    return (
      <div className="flex items-center justify-center min-h-[400px]">
        <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary" />
      </div>
    );
  }

  const q = search.toLowerCase();
  const rows = section === "plans" ? plans : fees;
  const filtered = rows.filter(
    (p) =>
      (p.student_name || "").toLowerCase().includes(q) ||
      (p.course_name || "").toLowerCase().includes(q) ||
      (p.product_name || "").toLowerCase().includes(q) ||
      (p.invoice_number || "").toLowerCase().includes(q),
  );

  return (
    <div className="space-y-6">
      <div>
        <h1 className="text-2xl font-bold flex items-center gap-2">
          <DollarSign className="h-7 w-7" />
          Fees &amp; Payments
        </h1>
        <p className="text-muted-foreground">
          Fee plans, linked invoices and payment status. Paid and remaining balances are pulled live from accounting.
        </p>
      </div>

      <div className="flex flex-wrap gap-2">
        <Button variant={section === "plans" ? "default" : "outline"} onClick={() => setSection("plans")}>
          <DollarSign className="mr-2 h-4 w-4" />
          Fee plans
        </Button>
        <Button variant={section === "student" ? "default" : "outline"} onClick={() => setSection("student")}>
          <CreditCard className="mr-2 h-4 w-4" />
          Student fees
        </Button>
      </div>

      <div className="relative max-w-sm">
        <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
        <Input
          placeholder="Search students, courses, invoice numbers..."
          value={search}
          onChange={(e) => setSearch(e.target.value)}
          className="pl-9"
        />
      </div>

      <Card>
        <CardContent className="pt-6">
          <Table>
            <TableHeader>
              <TableRow>
                <TableHead className="w-12">#</TableHead>
                <TableHead>Student</TableHead>
                <TableHead>Item / Course</TableHead>
                <TableHead>Invoice</TableHead>
                <TableHead className="text-right">Total</TableHead>
                <TableHead className="text-right">Paid</TableHead>
                <TableHead className="text-right">Remaining</TableHead>
                <TableHead>Plan state</TableHead>
                <TableHead>Payment</TableHead>
                <TableHead className="text-right">Actions</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {filtered.length === 0 && (
                <TableRow>
                  <TableCell colSpan={10} className="text-center text-muted-foreground py-10">
                    No fees records match your search.
                  </TableCell>
                </TableRow>
              )}
              {filtered.map((p, i) => {
                const hasInvoice = !!p.invoice_id;
                const isPaid = (p.payment_state || "").toLowerCase() === "paid";
                const canInvoice = !hasInvoice && p.state !== "cancel";
                const canPay = hasInvoice && !isPaid;
                return (
                  <TableRow key={p.id}>
                    <TableCell>{i + 1}</TableCell>
                    <TableCell className="font-medium">{p.student_name || "—"}</TableCell>
                    <TableCell className="text-muted-foreground">
                      {p.product_name || p.course_name || "—"}
                    </TableCell>
                    <TableCell className="text-xs">
                      {p.invoice_number ? p.invoice_number : <span className="text-muted-foreground">—</span>}
                    </TableCell>
                    <TableCell className="text-right tabular-nums">{money(p.total_amount, p.currency)}</TableCell>
                    <TableCell className="text-right tabular-nums">{money(p.paid_amount, p.currency)}</TableCell>
                    <TableCell className="text-right tabular-nums">{money(p.remaining_amount, p.currency)}</TableCell>
                    <TableCell>{stateBadge(p.state)}</TableCell>
                    <TableCell>{paymentBadge(p.payment_state)}</TableCell>
                    <TableCell className="text-right space-x-1">
                      <Button size="sm" variant="ghost" onClick={() => setDetailId(p.id)} title="View">
                        <Eye className="h-4 w-4" />
                      </Button>
                      <Button
                        size="sm"
                        variant="outline"
                        disabled={!canInvoice || invoiceMut.isPending}
                        onClick={() => invoiceMut.mutate(p.id)}
                        title="Create invoice"
                      >
                        {invoiceMut.isPending && invoiceMut.variables === p.id ? (
                          <Loader2 className="h-4 w-4 animate-spin" />
                        ) : (
                          <FileText className="h-4 w-4" />
                        )}
                      </Button>
                      <Button
                        size="sm"
                        variant="default"
                        disabled={!canPay}
                        onClick={() => {
                          setPaymentFor(p);
                          setPaymentAmount(String(p.remaining_amount ?? ""));
                          setPaymentMemo(`Payment for ${p.product_name || p.course_name || "fees"}`);
                        }}
                        title="Register payment"
                      >
                        <Wallet className="h-4 w-4" />
                      </Button>
                    </TableCell>
                  </TableRow>
                );
              })}
            </TableBody>
          </Table>
        </CardContent>
      </Card>

      <Dialog open={!!detailId} onOpenChange={(v) => { if (!v) setDetailId(null); }}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Fee Plan Details</DialogTitle>
            <DialogDescription>Accounting-backed balance for this fee line.</DialogDescription>
          </DialogHeader>
          {detailQ.isLoading ? (
            <div className="flex justify-center py-4">
              <Loader2 className="h-6 w-6 animate-spin text-primary" />
            </div>
          ) : detailQ.data ? (
            <div className="space-y-2 text-sm">
              <p><span className="font-medium">Student:</span> {detailQ.data.student_name || "—"}</p>
              <p><span className="font-medium">Item / Course:</span> {detailQ.data.product_name || detailQ.data.course_name || "—"}</p>
              <p><span className="font-medium">Invoice:</span> {detailQ.data.invoice_number || "Not created"}</p>
              <p><span className="font-medium">Total:</span> {money(detailQ.data.total_amount, detailQ.data.currency)}</p>
              <p><span className="font-medium">Paid:</span> {money(detailQ.data.paid_amount, detailQ.data.currency)}</p>
              <p><span className="font-medium">Remaining:</span> {money(detailQ.data.remaining_amount, detailQ.data.currency)}</p>
              <p className="flex items-center gap-2">
                <span className="font-medium">State:</span> {stateBadge(detailQ.data.state)}
                <span>·</span>
                {paymentBadge(detailQ.data.payment_state)}
              </p>
            </div>
          ) : null}
        </DialogContent>
      </Dialog>

      <Dialog open={!!paymentFor} onOpenChange={(v) => { if (!v) { setPaymentFor(null); setPaymentAmount(""); setPaymentMemo(""); } }}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Register payment</DialogTitle>
            <DialogDescription>
              {paymentFor
                ? `Invoice ${paymentFor.invoice_number || ""} for ${paymentFor.student_name} · remaining ${money(paymentFor.remaining_amount, paymentFor.currency)}`
                : ""}
            </DialogDescription>
          </DialogHeader>
          <div className="space-y-3">
            <div className="space-y-1">
              <Label className="text-xs">Amount</Label>
              <Input
                type="number"
                step="0.01"
                value={paymentAmount}
                onChange={(e) => setPaymentAmount(e.target.value)}
                placeholder="Leave empty to settle the full remaining balance"
              />
            </div>
            <div className="space-y-1">
              <Label className="text-xs">Memo</Label>
              <Input
                value={paymentMemo}
                onChange={(e) => setPaymentMemo(e.target.value)}
                placeholder="Payment communication"
              />
            </div>
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setPaymentFor(null)}>Cancel</Button>
            <Button
              disabled={paymentMut.isPending}
              onClick={() => paymentMut.mutate()}
            >
              {paymentMut.isPending ? (
                <><Loader2 className="h-4 w-4 animate-spin mr-2" />Registering...</>
              ) : (
                "Register payment"
              )}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
