import { createFileRoute } from "@tanstack/react-router";
import { useState } from "react";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { supabase } from "@/integrations/supabase/client";
import { Card, CardContent } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger, DialogFooter } from "@/components/ui/dialog";
import { toast } from "sonner";
import { Plus, Trash2, Truck, FileSpreadsheet, Wallet } from "lucide-react";
import { useT, fmtMoney } from "@/lib/i18n";
import { downloadCSV } from "@/lib/export-csv";

export const Route = createFileRoute("/_authenticated/purchases")({
  head: () => ({ meta: [{ title: "ক্রয়" }] }),
  component: PurchasesPage,
});

function PurchasesPage() {
  const { t, lang } = useT();
  const qc = useQueryClient();
  const [open, setOpen] = useState(false);
  const [deposit, setDeposit] = useState<any>(null);

  const { data: purchases = [] } = useQuery({
    queryKey: ["purchases"],
    queryFn: async () => (await supabase.from("purchases").select("*, purchase_items(*)").order("created_at", { ascending: false }).limit(100)).data || [],
  });
  const { data: suppliers = [] } = useQuery({
    queryKey: ["suppliers"],
    queryFn: async () => (await supabase.from("suppliers").select("*").order("name")).data || [],
  });

  const totalDue = purchases.reduce((a: number, p: any) => a + Number(p.due || 0), 0);
  const suppliersWithDue = suppliers.filter((s: any) => Number(s.due) > 0);

  const exportXls = () => {
    const rows: (string | number)[][] = [
      ["Date", "Supplier", "Items", "Total", "Paid", "Due", "Note"],
      ...purchases.map((p: any) => [
        new Date(p.created_at).toLocaleString(),
        p.supplier_name || "",
        (p.purchase_items || []).map((it: any) => `${it.product_name}×${it.quantity}`).join(" | "),
        Number(p.total), Number(p.paid), Number(p.due), p.note || "",
      ]),
    ];
    downloadCSV(`purchases-${new Date().toISOString().slice(0, 10)}`, rows);
  };

  return (
    <div className="space-y-6 max-w-6xl mx-auto">
      <div className="grid grid-cols-[minmax(0,1fr)_auto] items-center gap-4">
        <h1 className="text-2xl md:text-3xl font-extrabold">{t("purchases")}</h1>
        <div className="flex gap-2">
          <Button variant="outline" onClick={exportXls}><FileSpreadsheet className="size-4 mr-1" /> Excel</Button>
          <Dialog open={open} onOpenChange={setOpen}>
            <DialogTrigger asChild><Button className="gradient-primary text-white"><Plus className="size-4 mr-1" /> {t("new_purchase")}</Button></DialogTrigger>
            {open && <PurchaseDialog onDone={() => { setOpen(false); qc.invalidateQueries({ queryKey: ["purchases"] }); qc.invalidateQueries({ queryKey: ["products"] }); qc.invalidateQueries({ queryKey: ["suppliers"] }); }} />}
          </Dialog>
        </div>
      </div>

      {totalDue > 0 && (
        <Card className="border-destructive/30 bg-destructive/5">
          <CardContent className="p-4">
            <div className="flex justify-between items-center mb-2">
              <span className="font-bold text-destructive">{t("supplier_due")}: {fmtMoney(totalDue, lang)}</span>
            </div>
            <div className="grid sm:grid-cols-2 lg:grid-cols-3 gap-2">
              {suppliersWithDue.map((s: any) => (
                <div key={s.id} className="flex items-center justify-between gap-2 p-2 bg-background rounded-lg border">
                  <div className="min-w-0">
                    <div className="font-medium truncate">{s.name}</div>
                    <div className="text-xs text-destructive">{fmtMoney(s.due, lang)}</div>
                  </div>
                  <Button size="sm" variant="outline" onClick={() => setDeposit(s)}><Wallet className="size-3 mr-1" />{t("deposit")}</Button>
                </div>
              ))}
            </div>
          </CardContent>
        </Card>
      )}

      {purchases.length === 0 ? (
        <Card><CardContent className="p-12 text-center text-muted-foreground">{t("no_data")}</CardContent></Card>
      ) : (
        <div className="space-y-3">
          {purchases.map((p: any) => (
            <Card key={p.id} className="shadow-card">
              <CardContent className="p-4">
                <div className="flex justify-between gap-3 flex-wrap">
                  <div className="min-w-0 flex-1">
                    <div className="flex items-center gap-2"><Truck className="size-4 text-info" /><span className="font-bold">{p.supplier_name || "—"}</span></div>
                    <div className="text-xs text-muted-foreground mt-1">{new Date(p.created_at).toLocaleString(lang === "bn" ? "bn-BD" : "en-IN")}</div>
                    <div className="text-sm text-muted-foreground mt-2 line-clamp-2">
                      {p.purchase_items?.map((it: any) => `${it.product_name} × ${it.quantity}`).join(" · ")}
                    </div>
                  </div>
                  <div className="text-right">
                    <div className="text-xl font-extrabold text-info">{fmtMoney(p.total, lang)}</div>
                    <div className="text-xs text-success">{t("paid")}: {fmtMoney(p.paid, lang)}</div>
                    {Number(p.due) > 0 && <div className="text-xs text-destructive font-bold">{t("due")}: {fmtMoney(p.due, lang)}</div>}
                  </div>
                </div>
              </CardContent>
            </Card>
          ))}
        </div>
      )}

      <Dialog open={!!deposit} onOpenChange={(v) => !v && setDeposit(null)}>
        {deposit && <DepositDialog supplier={deposit} onDone={() => { setDeposit(null); qc.invalidateQueries({ queryKey: ["suppliers"] }); qc.invalidateQueries({ queryKey: ["purchases"] }); }} />}
      </Dialog>
    </div>
  );
}

function DepositDialog({ supplier, onDone }: { supplier: any; onDone: () => void }) {
  const { t, lang } = useT();
  const [amount, setAmount] = useState("");
  const submit = async () => {
    const n = Number(amount);
    if (!n || n <= 0) return toast.error("?");
    if (n > Number(supplier.due)) return toast.error(lang === "bn" ? "বকেয়ার চেয়ে বেশি" : "More than due");
    const newDue = Number(supplier.due) - n;
    const { error } = await supabase.from("suppliers").update({ due: newDue }).eq("id", supplier.id);
    if (error) return toast.error(error.message);
    // Apply to oldest unpaid purchases
    const { data: open } = await supabase.from("purchases").select("id, due, paid").eq("supplier_id", supplier.id).gt("due", 0).order("created_at");
    let remain = n;
    for (const p of open || []) {
      if (remain <= 0) break;
      const apply = Math.min(remain, Number(p.due));
      await supabase.from("purchases").update({ due: Number(p.due) - apply, paid: Number(p.paid) + apply }).eq("id", p.id);
      remain -= apply;
    }
    toast.success(t("saved"));
    onDone();
  };
  return (
    <DialogContent>
      <DialogHeader><DialogTitle>{t("deposit")} — {supplier.name}</DialogTitle></DialogHeader>
      <div className="space-y-3">
        <div className="text-sm">{t("due")}: <b className="text-destructive">{fmtMoney(supplier.due, lang)}</b></div>
        <div className="space-y-1.5"><Label className="text-sm font-semibold">{t("amount")}</Label><Input type="number" step="0.01" value={amount} onChange={(e) => setAmount(e.target.value)} autoFocus /></div>
      </div>
      <DialogFooter><Button onClick={submit} className="gradient-primary text-white">{t("save")}</Button></DialogFooter>
    </DialogContent>
  );
}

type Item = { product_id: string; name: string; cartons: number; per_carton: number; cost: number; unit: string };

function PurchaseDialog({ onDone }: { onDone: () => void }) {
  const { t, lang } = useT();
  const qc = useQueryClient();
  const [supplierId, setSupplierId] = useState("");
  const [items, setItems] = useState<Item[]>([]);
  const [productPick, setProductPick] = useState("");
  const [paid, setPaid] = useState<number | "">("");
  const [note, setNote] = useState("");
  const [saving, setSaving] = useState(false);
  const [showAddSupplier, setShowAddSupplier] = useState(false);
  const [showAddProduct, setShowAddProduct] = useState(false);

  const { data: suppliers = [] } = useQuery({ queryKey: ["suppliers"], queryFn: async () => (await supabase.from("suppliers").select("*").order("name")).data || [] });
  const { data: products = [] } = useQuery({ queryKey: ["products"], queryFn: async () => (await supabase.from("products").select("*").order("name")).data || [] });

  const total = items.reduce((a, it) => a + (it.cartons * it.per_carton) * it.cost, 0);
  const due = Math.max(0, total - (Number(paid) || 0));

  const addItem = () => {
    const p: any = products.find((x: any) => x.id === productPick);
    if (!p) return;
    setItems((arr) => [...arr, {
      product_id: p.id, name: p.name,
      cartons: 1, per_carton: Number(p.pack_size) || 1,
      cost: Number(p.cost_price) || 0, unit: p.unit || "Pcs",
    }]);
    setProductPick("");
  };

  const save = async () => {
    if (items.length === 0) return toast.error(lang === "bn" ? "পণ্য যোগ করুন" : "Add items");
    setSaving(true);
    try {
      const { data: u } = await supabase.auth.getUser();
      if (!u.user) throw new Error("Unauthorized");
      const supplier: any = suppliers.find((s: any) => s.id === supplierId);
      const { data: purchase, error } = await supabase.from("purchases").insert({
        user_id: u.user.id, supplier_id: supplierId || null, supplier_name: supplier?.name || null,
        total, paid: Number(paid) || 0, due, note: note || null,
      }).select().single();
      if (error) throw error;
      const rows = items.map((it) => {
        const qty = it.cartons * it.per_carton;
        return {
          purchase_id: purchase.id, user_id: u.user!.id, product_id: it.product_id,
          product_name: it.name, quantity: qty, unit_cost: it.cost, subtotal: qty * it.cost,
        };
      });
      const { error: e2 } = await supabase.from("purchase_items").insert(rows);
      if (e2) throw e2;
      toast.success(t("saved"));
      onDone();
    } catch (e: any) { toast.error(e.message); } finally { setSaving(false); }
  };

  const updateItem = (i: number, patch: Partial<Item>) =>
    setItems((arr) => arr.map((x, idx) => idx === i ? { ...x, ...patch } : x));

  return (
    <>
      <DialogContent className="max-w-2xl" onInteractOutside={(e) => e.preventDefault()}>
        <DialogHeader><DialogTitle>{t("new_purchase")}</DialogTitle></DialogHeader>
        <div className="space-y-3 max-h-[70vh] overflow-y-auto pr-1">
          <div>
            <Label className="text-sm font-semibold">{t("supplier")}</Label>
            <div className="flex gap-1">
              <Select value={supplierId || "none"} onValueChange={(v) => setSupplierId(v === "none" ? "" : v)}>
                <SelectTrigger className="flex-1"><SelectValue placeholder="—" /></SelectTrigger>
                <SelectContent>
                  <SelectItem value="none">—</SelectItem>
                  {suppliers.map((s: any) => <SelectItem key={s.id} value={s.id}>{s.name}{s.phone ? ` (${s.phone})` : ""}</SelectItem>)}
                </SelectContent>
              </Select>
              <Button type="button" size="icon" variant="outline" onClick={() => setShowAddSupplier(true)} title={t("add_supplier")}><Plus className="size-4" /></Button>
            </div>
          </div>

          <div className="flex gap-1">
            <Select value={productPick} onValueChange={setProductPick}>
              <SelectTrigger className="flex-1"><SelectValue placeholder={t("add_product")} /></SelectTrigger>
              <SelectContent>{products.map((p: any) => <SelectItem key={p.id} value={p.id}>{p.name} — {p.stock} {p.unit}</SelectItem>)}</SelectContent>
            </Select>
            <Button type="button" onClick={addItem} disabled={!productPick}><Plus className="size-4" /></Button>
            <Button type="button" variant="outline" onClick={() => setShowAddProduct(true)}>+ {lang === "bn" ? "নতুন" : "New"}</Button>
          </div>

          <div className="space-y-2">
            {items.map((it, i) => {
              const qty = it.cartons * it.per_carton;
              const sub = qty * it.cost;
              return (
                <div key={i} className="p-2 rounded-md border space-y-2">
                  <div className="flex items-center gap-2">
                    <div className="flex-1 font-semibold truncate">{it.name}</div>
                    <Button size="icon" variant="ghost" onClick={() => setItems((arr) => arr.filter((_, idx) => idx !== i))}><Trash2 className="size-4 text-destructive" /></Button>
                  </div>
                  <div className="grid grid-cols-2 sm:grid-cols-4 gap-2 text-xs">
                    <div className="space-y-1">
                      <Label className="text-[11px]">{t("cartons")}</Label>
                      <Input type="number" step="0.01" value={it.cartons} onChange={(e) => updateItem(i, { cartons: Number(e.target.value) || 0 })} />
                    </div>
                    <div className="space-y-1">
                      <Label className="text-[11px]">{t("per_carton")} ({it.unit})</Label>
                      <Input type="number" step="0.01" value={it.per_carton} onChange={(e) => updateItem(i, { per_carton: Number(e.target.value) || 0 })} />
                    </div>
                    <div className="space-y-1">
                      <Label className="text-[11px]">{t("cost_price")} / {it.unit}</Label>
                      <Input type="number" step="0.01" value={it.cost} onChange={(e) => updateItem(i, { cost: Number(e.target.value) || 0 })} />
                    </div>
                    <div className="space-y-1">
                      <Label className="text-[11px]">{t("unit_qty")}</Label>
                      <div className="h-10 px-3 rounded-md border bg-muted/40 grid items-center font-bold text-primary text-sm">{qty} {it.unit}</div>
                    </div>
                  </div>
                  <div className="text-right text-sm font-bold">{fmtMoney(sub, lang)}</div>
                </div>
              );
            })}
          </div>

          <div className="grid grid-cols-2 gap-2">
            <div><Label className="text-sm font-semibold">{t("paid")}</Label><Input type="number" value={paid} onChange={(e) => setPaid(e.target.value === "" ? "" : Number(e.target.value))} /></div>
            <div><Label className="text-sm font-semibold">{t("note")}</Label><Input value={note} onChange={(e) => setNote(e.target.value)} /></div>
          </div>
          <div className="flex justify-between p-3 rounded-lg bg-muted font-bold">
            <span>{t("total")}: {fmtMoney(total, lang)}</span>
            <span className={due > 0 ? "text-destructive" : "text-success"}>{t("due")}: {fmtMoney(due, lang)}</span>
          </div>
        </div>
        <DialogFooter>
          <Button onClick={save} disabled={saving || items.length === 0} className="gradient-primary text-white">{t("save")}</Button>
        </DialogFooter>
      </DialogContent>

      <Dialog open={showAddSupplier} onOpenChange={setShowAddSupplier}>
        {showAddSupplier && <QuickSupplierDialog onDone={(id) => { setShowAddSupplier(false); qc.invalidateQueries({ queryKey: ["suppliers"] }); if (id) setSupplierId(id); }} />}
      </Dialog>
      <Dialog open={showAddProduct} onOpenChange={setShowAddProduct}>
        {showAddProduct && <QuickProductDialog onDone={(p) => {
          setShowAddProduct(false);
          qc.invalidateQueries({ queryKey: ["products"] });
          if (p) setItems((arr) => [...arr, {
            product_id: p.id, name: p.name,
            cartons: 1, per_carton: Number(p.pack_size) || 1,
            cost: Number(p.cost_price) || 0, unit: p.unit,
          }]);
        }} />}
      </Dialog>
    </>
  );
}

function QuickSupplierDialog({ onDone }: { onDone: (id?: string) => void }) {
  const { t } = useT();
  const [f, setF] = useState({ name: "", phone: "", address: "" });
  const save = async () => {
    if (!f.name.trim()) return;
    const { data: u } = await supabase.auth.getUser();
    if (!u.user) return;
    const { data, error } = await supabase.from("suppliers").insert({ user_id: u.user.id, name: f.name, phone: f.phone || null, address: f.address || null }).select().single();
    if (error) return toast.error(error.message);
    toast.success(t("saved"));
    onDone(data.id);
  };
  return (
    <DialogContent>
      <DialogHeader><DialogTitle>{t("add_supplier")}</DialogTitle></DialogHeader>
      <div className="space-y-3">
        <div className="space-y-1.5"><Label className="text-sm font-semibold">{t("name")} *</Label><Input autoFocus value={f.name} onChange={(e) => setF({ ...f, name: e.target.value })} /></div>
        <div className="space-y-1.5"><Label className="text-sm font-semibold">{t("phone")}</Label><Input value={f.phone} onChange={(e) => setF({ ...f, phone: e.target.value })} /></div>
        <div className="space-y-1.5"><Label className="text-sm font-semibold">{t("address")}</Label><Input value={f.address} onChange={(e) => setF({ ...f, address: e.target.value })} /></div>
      </div>
      <DialogFooter><Button onClick={save} disabled={!f.name} className="gradient-primary text-white">{t("save")}</Button></DialogFooter>
    </DialogContent>
  );
}

function QuickProductDialog({ onDone }: { onDone: (p?: any) => void }) {
  const { t, lang } = useT();
  const { data: units = [] } = useQuery({ queryKey: ["units"], queryFn: async () => (await supabase.from("units" as any).select("*").order("name")).data || [] });
  const [f, setF] = useState({ name: "", unit: "Pcs", pack_size: "1", cartons: "", cost_price: "", sale_price: "" });
  const allUnits = (units as any[]).length ? (units as any[]).map((x) => x.name) : ["Pcs", "Kg", "gm", "Ta", "Carton", "Bosta", "Packet", "Drum", "Liter", "Dozen"];
  const stock = (Number(f.cartons) || 0) * (Number(f.pack_size) || 0);

  const save = async () => {
    if (!f.name.trim()) return;
    const { data: u } = await supabase.auth.getUser();
    if (!u.user) return;
    const prefix = f.name.slice(0, 3).toUpperCase().replace(/[^A-Z0-9]/g, "X");
    const sku = `${prefix}-${Date.now().toString().slice(-6)}`;
    const { data, error } = await supabase.from("products").insert({
      user_id: u.user.id, name: f.name, sku, unit: f.unit,
      pack_size: Number(f.pack_size) || 1, stock,
      cost_price: Number(f.cost_price) || 0, sale_price: Number(f.sale_price) || 0,
    }).select().single();
    if (error) return toast.error(error.message);
    toast.success(t("saved"));
    onDone(data);
  };

  return (
    <DialogContent>
      <DialogHeader><DialogTitle>{t("add_product")}</DialogTitle></DialogHeader>
      <div className="space-y-3">
        <div className="space-y-1.5"><Label className="text-sm font-semibold">{t("name")} *</Label><Input autoFocus value={f.name} placeholder="e.g. Chal" onChange={(e) => setF({ ...f, name: e.target.value })} /></div>
        <div className="grid grid-cols-2 gap-2">
          <div className="space-y-1.5">
            <Label className="text-sm font-semibold">{t("unit")}</Label>
            <Select value={f.unit} onValueChange={(v) => setF({ ...f, unit: v })}>
              <SelectTrigger><SelectValue /></SelectTrigger>
              <SelectContent>{allUnits.map((n: string) => <SelectItem key={n} value={n}>{n}</SelectItem>)}</SelectContent>
            </Select>
          </div>
          <div className="space-y-1.5"><Label className="text-sm font-semibold">{t("cartons")}/{lang === "bn" ? "বস্তা" : "Bosta"}</Label><Input type="number" value={f.cartons} placeholder="10" onChange={(e) => setF({ ...f, cartons: e.target.value })} /></div>
          <div className="space-y-1.5"><Label className="text-sm font-semibold">{t("units_per_carton")} ({f.unit})</Label><Input type="number" value={f.pack_size} placeholder="10" onChange={(e) => setF({ ...f, pack_size: e.target.value })} /></div>
          <div className="space-y-1.5"><Label className="text-sm font-semibold">{t("total_stock")}</Label><div className="h-10 px-3 rounded-md border bg-muted/40 grid items-center font-bold text-primary">{stock} {f.unit}</div></div>
          <div className="space-y-1.5"><Label className="text-sm font-semibold">{t("cost_price")}</Label><Input type="number" step="0.01" value={f.cost_price} onChange={(e) => setF({ ...f, cost_price: e.target.value })} /></div>
          <div className="space-y-1.5"><Label className="text-sm font-semibold">{t("sale_price")}</Label><Input type="number" step="0.01" value={f.sale_price} onChange={(e) => setF({ ...f, sale_price: e.target.value })} /></div>
        </div>
      </div>
      <DialogFooter><Button onClick={save} disabled={!f.name} className="gradient-primary text-white">{t("save")}</Button></DialogFooter>
    </DialogContent>
  );
}
