import { createFileRoute } from "@tanstack/react-router";
import { useState } from "react";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { supabase } from "@/integrations/supabase/client";
import { PageLayout } from "@/components/PageLayout";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Card } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { toast } from "sonner";
import { usePermissions } from "@/hooks/use-permissions";
import { format } from "date-fns";

export const Route = createFileRoute("/_authenticated/staff-payroll")({
  component: PayrollPage,
});

function PayrollPage() {
  const qc = useQueryClient();
  const { isAdmin } = usePermissions();
  const [month, setMonth] = useState(format(new Date(), "yyyy-MM"));
  const monthDate = `${month}-01`;

  const { data: staff = [] } = useQuery({
    queryKey: ["staff-active-payroll"],
    queryFn: async () => {
      const { data } = await supabase.from("staff").select("id,staff_id,name,salary,role")
        .is("deleted_at", null).eq("status", "active").order("name");
      return data ?? [];
    },
  });

  const { data: payrolls = [], isLoading } = useQuery({
    queryKey: ["payroll", monthDate],
    queryFn: async () => {
      const { data } = await supabase.from("staff_payroll").select("*").eq("month", monthDate);
      return data ?? [];
    },
  });

  const byStaff = new Map(payrolls.map((p: any) => [p.staff_id, p]));

  const generate = useMutation({
    mutationFn: async () => {
      const rows = staff.filter((s: any) => !byStaff.has(s.id)).map((s: any) => ({
        staff_id: s.id, month: monthDate, basic_salary: Number(s.salary) || 0,
      }));
      if (!rows.length) throw new Error("All staff already have payroll for this month");
      const { error } = await supabase.from("staff_payroll").insert(rows);
      if (error) throw error;
    },
    onSuccess: () => {
      toast.success("Payroll generated");
      qc.invalidateQueries({ queryKey: ["payroll", monthDate] });
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const updateField = useMutation({
    mutationFn: async ({ id, field, value }: { id: string; field: string; value: number }) => {
      const { error } = await supabase.from("staff_payroll").update({ [field]: value } as any).eq("id", id);
      if (error) throw error;
    },
    onSuccess: () => qc.invalidateQueries({ queryKey: ["payroll", monthDate] }),
    onError: (e: Error) => toast.error(e.message),
  });

  const pay = useMutation({
    mutationFn: async (p: any) => {
      const { error } = await supabase.from("staff_payroll").update({
        paid_amount: p.net_payable,
        payment_date: format(new Date(), "yyyy-MM-dd"),
      }).eq("id", p.id);
      if (error) throw error;
    },
    onSuccess: () => {
      toast.success("Marked as paid");
      qc.invalidateQueries({ queryKey: ["payroll", monthDate] });
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const totalPayable = payrolls.reduce((s: number, p: any) => s + Number(p.net_payable), 0);
  const totalPaid = payrolls.reduce((s: number, p: any) => s + Number(p.paid_amount), 0);

  return (
    <PageLayout title="Staff Payroll" subtitle="Monthly salary, bonus, advance, deduction">
      <div className="grid grid-cols-2 md:grid-cols-4 gap-3 mb-4">
        <Card className="p-3"><div className="text-xs text-muted-foreground">Staff</div><div className="text-xl font-bold">{staff.length}</div></Card>
        <Card className="p-3"><div className="text-xs text-muted-foreground">Generated</div><div className="text-xl font-bold">{payrolls.length}</div></Card>
        <Card className="p-3"><div className="text-xs text-muted-foreground">Total Payable</div><div className="text-xl font-bold">৳{totalPayable.toLocaleString()}</div></Card>
        <Card className="p-3"><div className="text-xs text-muted-foreground">Total Paid</div><div className="text-xl font-bold text-green-600">৳{totalPaid.toLocaleString()}</div></Card>
      </div>

      <Card className="p-4">
        <div className="flex flex-wrap gap-3 mb-4 items-end">
          <div>
            <label className="text-xs text-muted-foreground">Month</label>
            <Input type="month" value={month} onChange={(e) => setMonth(e.target.value)} className="w-[180px]" />
          </div>
          {isAdmin && <Button onClick={() => generate.mutate()} disabled={generate.isPending}>Generate Payroll</Button>}
        </div>

        <div className="border rounded-lg overflow-x-auto">
          <Table>
            <TableHeader>
              <TableRow>
                <TableHead>Staff</TableHead>
                <TableHead className="text-right">Basic</TableHead>
                <TableHead className="text-right">Bonus</TableHead>
                <TableHead className="text-right">Commission</TableHead>
                <TableHead className="text-right">Advance</TableHead>
                <TableHead className="text-right">Deduction</TableHead>
                <TableHead className="text-right">Net Payable</TableHead>
                <TableHead>Status</TableHead>
                <TableHead className="text-right">Action</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {isLoading ? (
                <TableRow><TableCell colSpan={9} className="text-center py-8 text-muted-foreground">Loading...</TableCell></TableRow>
              ) : payrolls.length === 0 ? (
                <TableRow><TableCell colSpan={9} className="text-center py-8 text-muted-foreground">No payroll for this month. Click "Generate Payroll".</TableCell></TableRow>
              ) : payrolls.map((p: any) => {
                const s = staff.find((x: any) => x.id === p.staff_id);
                const numInput = (field: string) => (
                  <Input
                    type="number" min="0"
                    defaultValue={p[field]}
                    className="w-24 h-8 text-right"
                    disabled={!isAdmin || p.status === "paid"}
                    onBlur={(e) => {
                      const v = Number(e.target.value);
                      if (v !== Number(p[field])) updateField.mutate({ id: p.id, field, value: v });
                    }}
                  />
                );
                return (
                  <TableRow key={p.id}>
                    <TableCell>
                      <div className="font-medium text-sm">{s?.name ?? "?"}</div>
                      <div className="text-xs text-muted-foreground font-mono">{s?.staff_id}</div>
                    </TableCell>
                    <TableCell className="text-right">{numInput("basic_salary")}</TableCell>
                    <TableCell className="text-right">{numInput("bonus")}</TableCell>
                    <TableCell className="text-right">{numInput("commission")}</TableCell>
                    <TableCell className="text-right">{numInput("advance")}</TableCell>
                    <TableCell className="text-right">{numInput("deduction")}</TableCell>
                    <TableCell className="text-right font-bold">৳{Number(p.net_payable).toLocaleString()}</TableCell>
                    <TableCell><Badge variant={p.status === "paid" ? "default" : p.status === "partial" ? "secondary" : "outline"}>{p.status}</Badge></TableCell>
                    <TableCell className="text-right">
                      {isAdmin && p.status !== "paid" && (
                        <Button size="sm" onClick={() => pay.mutate(p)}>Pay</Button>
                      )}
                    </TableCell>
                  </TableRow>
                );
              })}
            </TableBody>
          </Table>
        </div>
      </Card>
    </PageLayout>
  );
}
