import { createFileRoute, useNavigate, Link } from "@tanstack/react-router";
import { PageLayout } from "@/components/PageLayout";
import { useLanguage } from "@/hooks/use-language";
import { supabase } from "@/integrations/supabase/client";
import { useState, useRef, useEffect, useMemo } from "react";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";
import { Search, Trash2, Loader2, ArrowLeft, Save } from "lucide-react";

export const Route = createFileRoute("/_authenticated/sales-orders/$orderId/edit")({
  head: () => ({ meta: [{ title: "Edit Sales Order — Niyamah ERP" }] }),
  component: EditSalesOrderPage,
});

type Item = {
  id?: string;
  product_id: string;
  product_name: string;
  quantity: number;
  price: number;
  total: number;
  stock: number;
  original_qty: number; // 0 for newly added
};

function EditSalesOrderPage() {
  const { orderId } = Route.useParams();
  const { lang } = useLanguage();
  const isBn = lang === "bn";
  const navigate = useNavigate();
  const qc = useQueryClient();

  const [selectedCust, setSelectedCust] = useState<any>(null);
  const [custQuery, setCustQuery] = useState("");
  const [custResults, setCustResults] = useState<any[]>([]);
  const [showCustDrop, setShowCustDrop] = useState(false);
  const custRef = useRef<HTMLDivElement>(null);

  const [prodQuery, setProdQuery] = useState("");
  const [prodResults, setProdResults] = useState<any[]>([]);
  const [showProdDrop, setShowProdDrop] = useState(false);
  const prodRef = useRef<HTMLDivElement>(null);

  const [items, setItems] = useState<Item[]>([]);
  const [discount, setDiscount] = useState(0);
  const [paidAmount, setPaidAmount] = useState(0);
  const [paymentMethod, setPaymentMethod] = useState("cash");
  const [orderDate, setOrderDate] = useState("");
  const [deliveryDate, setDeliveryDate] = useState("");
  const [branchId, setBranchId] = useState("");
  const [note, setNote] = useState("");
  const [loaded, setLoaded] = useState(false);
  const [stockDeducted, setStockDeducted] = useState(false);
  const [orderStatus, setOrderStatus] = useState("");
  const [orderNo, setOrderNo] = useState("");

  const { data: branches = [] } = useQuery({
    queryKey: ["branches-list"],
    queryFn: async () => {
      const { data } = await supabase.from("branches").select("id, name").eq("status", "active");
      return (data as any[]) || [];
    },
  });

  // Load order
  useEffect(() => {
    (async () => {
      const { data: order, error } = await supabase
        .from("sales_orders" as any)
        .select("*, customers(*)")
        .eq("id", orderId)
        .single();
      if (error || !order) { toast.error(error?.message || "Not found"); return; }
      const o = order as any;
      setOrderNo(o.order_no);
      setStockDeducted(!!o.stock_deducted);
      setOrderStatus(o.status);
      setOrderDate(o.order_date || "");
      setDeliveryDate(o.delivery_date || "");
      setBranchId(o.branch_id || "");
      setDiscount(Number(o.discount) || 0);
      setPaidAmount(Number(o.paid_amount) || 0);
      setPaymentMethod(o.payment_method || "cash");
      setNote(o.note || "");
      if (o.customers) setSelectedCust(o.customers);

      const { data: its } = await supabase
        .from("sales_order_items" as any)
        .select("*, products(name, sku, stock_quantity)")
        .eq("sales_order_id", orderId);
      setItems(((its as any[]) || []).map((it) => ({
        id: it.id,
        product_id: it.product_id,
        product_name: it.products?.name || "",
        quantity: Number(it.quantity),
        price: Number(it.price),
        total: Number(it.total),
        stock: Number(it.products?.stock_quantity) || 0,
        original_qty: Number(it.quantity),
      })));
      setLoaded(true);
    })();
  }, [orderId]);

  // Customer search
  useEffect(() => {
    if (custQuery.length < 2) { setCustResults([]); return; }
    const t = setTimeout(async () => {
      const { data } = await supabase
        .from("customers")
        .select("*")
        .or(`name.ilike.%${custQuery}%,name_bn.ilike.%${custQuery}%,mobile.ilike.%${custQuery}%`)
        .limit(10);
      setCustResults((data as any[]) || []);
      setShowCustDrop(true);
    }, 300);
    return () => clearTimeout(t);
  }, [custQuery]);

  // Product search
  useEffect(() => {
    if (prodQuery.length < 2) { setProdResults([]); return; }
    const t = setTimeout(async () => {
      const { data } = await supabase
        .from("products")
        .select("*")
        .eq("is_deleted", false)
        .or(`name.ilike.%${prodQuery}%,name_bn.ilike.%${prodQuery}%,sku.ilike.%${prodQuery}%,barcode.ilike.%${prodQuery}%`)
        .limit(10);
      setProdResults((data as any[]) || []);
      setShowProdDrop(true);
    }, 300);
    return () => clearTimeout(t);
  }, [prodQuery]);

  useEffect(() => {
    const h = (e: MouseEvent) => {
      if (custRef.current && !custRef.current.contains(e.target as Node)) setShowCustDrop(false);
      if (prodRef.current && !prodRef.current.contains(e.target as Node)) setShowProdDrop(false);
    };
    document.addEventListener("mousedown", h);
    return () => document.removeEventListener("mousedown", h);
  }, []);

  const subtotal = useMemo(() => items.reduce((s, i) => s + i.total, 0), [items]);
  const totalAmount = Math.max(0, subtotal - discount);
  const dueAmount = Math.max(0, totalAmount - paidAmount);

  const addProduct = (p: any) => {
    const existing = items.find((i) => i.product_id === p.id);
    const price = Number(p.retail_price) || 0;
    if (existing) {
      setItems(items.map((i) => i.product_id === p.id
        ? { ...i, quantity: i.quantity + 1, total: (i.quantity + 1) * i.price }
        : i));
    } else {
      setItems([...items, {
        product_id: p.id,
        product_name: p.name,
        quantity: 1,
        price,
        total: price,
        stock: Number(p.stock_quantity) || 0,
        original_qty: 0,
      }]);
    }
    setProdQuery(""); setShowProdDrop(false);
  };

  const updateItem = (idx: number, field: "quantity" | "price", value: number) => {
    setItems(items.map((it, i) => {
      if (i !== idx) return it;
      const u = { ...it, [field]: value };
      u.total = u.quantity * u.price;
      return u;
    }));
  };

  const removeItem = (idx: number) => setItems(items.filter((_, i) => i !== idx));

  const saveMutation = useMutation({
    mutationFn: async () => {
      if (items.length === 0) throw new Error(isBn ? "অন্তত একটি পণ্য রাখুন" : "Keep at least one item");

      // Stock validation only when stock has been deducted (delivered/completed orders)
      if (stockDeducted) {
        // For new items or qty increases, ensure available stock can absorb the delta
        for (const it of items) {
          const delta = it.quantity - it.original_qty; // positive means more deduction needed
          if (delta > 0 && delta > it.stock) {
            throw new Error(
              isBn
                ? `${it.product_name}: পর্যাপ্ত স্টক নেই (অতিরিক্ত প্রয়োজন: ${delta}, স্টক: ${it.stock})`
                : `${it.product_name}: insufficient stock (need ${delta} more, have ${it.stock})`
            );
          }
        }
      }

      // Build product delta map (oldQty - newQty) -> positive = restore, negative = deduct
      const deltaMap = new Map<string, number>();
      // Existing items: account current vs original
      for (const it of items) {
        const prev = deltaMap.get(it.product_id) || 0;
        deltaMap.set(it.product_id, prev + (it.original_qty - it.quantity));
      }
      // Removed items (in original load but not in items now)
      // We need to find them: query existing by IDs not in items
      const remainingIds = new Set(items.filter((i) => i.id).map((i) => i.id));
      const { data: oldItems } = await supabase
        .from("sales_order_items" as any)
        .select("id, product_id, quantity")
        .eq("sales_order_id", orderId);
      for (const oi of (oldItems as any[]) || []) {
        if (!remainingIds.has(oi.id)) {
          const prev = deltaMap.get(oi.product_id) || 0;
          deltaMap.set(oi.product_id, prev + Number(oi.quantity)); // restore
        }
      }

      // Apply stock deltas only if stock was deducted
      if (stockDeducted) {
        for (const [pid, delta] of deltaMap.entries()) {
          if (delta === 0) continue;
          const { data: prod } = await supabase
            .from("products").select("stock_quantity").eq("id", pid).single();
          const cur = Number((prod as any)?.stock_quantity) || 0;
          await supabase
            .from("products")
            .update({ stock_quantity: Math.max(0, cur + delta) } as any)
            .eq("id", pid);
        }
      }

      // Replace items: delete all then insert
      const { error: delErr } = await supabase
        .from("sales_order_items" as any)
        .delete()
        .eq("sales_order_id", orderId);
      if (delErr) throw delErr;

      const rows = items.map((it) => ({
        sales_order_id: orderId,
        product_id: it.product_id,
        quantity: it.quantity,
        price: it.price,
        total: it.total,
      }));
      const { error: insErr } = await supabase.from("sales_order_items" as any).insert(rows);
      if (insErr) throw insErr;

      // Update header
      const { error: updErr } = await supabase
        .from("sales_orders" as any)
        .update({
          customer_id: selectedCust?.id || null,
          branch_id: branchId || null,
          order_date: orderDate,
          delivery_date: deliveryDate || null,
          discount,
          total_amount: totalAmount,
          paid_amount: paidAmount,
          payment_method: paymentMethod,
          note,
        } as any)
        .eq("id", orderId);
      if (updErr) throw updErr;
    },
    onSuccess: () => {
      toast.success(isBn ? "ইনভয়েস আপডেট হয়েছে" : "Invoice updated");
      qc.invalidateQueries({ queryKey: ["sales-order", orderId] });
      qc.invalidateQueries({ queryKey: ["sales-orders"] });
      navigate({ to: "/sales-orders/$orderId", params: { orderId } });
    },
    onError: (e: any) => toast.error(e.message),
  });

  const inputCls = "w-full rounded-lg border border-border bg-card px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary/40";

  const isLocked = orderStatus === "cancelled" || orderStatus === "returned";

  if (!loaded) return <PageLayout><div className="p-8 text-center text-muted-foreground">Loading...</div></PageLayout>;

  return (
    <PageLayout>
      <div className="mb-6 flex items-center justify-between flex-wrap gap-3">
        <div className="flex items-center gap-3">
          <Link to="/sales-orders/$orderId" params={{ orderId }} className="flex items-center gap-2 text-sm text-muted-foreground hover:text-foreground">
            <ArrowLeft className="h-4 w-4" />
            {isBn ? "ফিরে যান" : "Back"}
          </Link>
          <div>
            <h1 className="text-xl font-bold text-foreground">
              {isBn ? "ইনভয়েস এডিট" : "Edit Invoice"} <span className="text-sm font-mono text-muted-foreground ml-2">{orderNo}</span>
            </h1>
            {stockDeducted && (
              <p className="text-xs text-orange-600 dark:text-orange-400 mt-0.5">
                {isBn
                  ? "⚠ স্টক ইতিমধ্যে কাটা হয়েছে — পরিমাণ পরিবর্তনে স্টক স্বয়ংক্রিয় সমন্বয় হবে"
                  : "⚠ Stock already deducted — qty changes will auto-adjust product stock"}
              </p>
            )}
          </div>
        </div>
        <button
          disabled={saveMutation.isPending || isLocked}
          onClick={() => saveMutation.mutate()}
          className="flex items-center gap-2 rounded-lg bg-primary px-4 py-2 text-sm font-semibold text-primary-foreground hover:opacity-90 disabled:opacity-50"
        >
          {saveMutation.isPending ? <Loader2 className="h-4 w-4 animate-spin" /> : <Save className="h-4 w-4" />}
          {isBn ? "সংরক্ষণ" : "Save Changes"}
        </button>
      </div>

      {isLocked && (
        <div className="mb-4 rounded-lg border border-destructive/40 bg-destructive/10 p-3 text-sm text-destructive">
          {isBn ? "এই ইনভয়েস বাতিল/রিটার্ন হয়েছে — এডিট করা যাবে না।" : "This invoice is cancelled/returned — editing is disabled."}
        </div>
      )}

      <div className={`grid gap-6 lg:grid-cols-3 ${isLocked ? "pointer-events-none opacity-60" : ""}`}>
        <div className="lg:col-span-2 space-y-6">
          <div className="rounded-xl border border-border bg-card p-5">
            <h3 className="text-sm font-semibold mb-3">{isBn ? "গ্রাহক" : "Customer"}</h3>
            <div ref={custRef} className="relative">
              <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
              <input
                className={`${inputCls} pl-9`}
                placeholder={isBn ? "নাম / মোবাইল দিয়ে খুঁজুন" : "Search name / mobile"}
                value={selectedCust ? selectedCust.name : custQuery}
                onChange={(e) => { setCustQuery(e.target.value); setSelectedCust(null); }}
              />
              {showCustDrop && custResults.length > 0 && (
                <div className="absolute z-30 mt-1 w-full rounded-lg border border-border bg-popover shadow-lg max-h-48 overflow-y-auto">
                  {custResults.map((c: any) => (
                    <button key={c.id} className="w-full text-left px-4 py-2 text-sm hover:bg-accent"
                      onClick={() => { setSelectedCust(c); setShowCustDrop(false); setCustQuery(""); }}>
                      <div className="font-medium">{c.name}</div>
                      <div className="text-xs text-muted-foreground">{c.mobile}</div>
                    </button>
                  ))}
                </div>
              )}
            </div>
            {selectedCust && (
              <div className="mt-2 text-xs text-muted-foreground">
                📞 {selectedCust.mobile} · {isBn ? "বকেয়া" : "Due"}: ৳{Number(selectedCust.total_due || 0).toLocaleString()}
              </div>
            )}
          </div>

          <div className="rounded-xl border border-border bg-card p-5">
            <h3 className="text-sm font-semibold mb-3">{isBn ? "পণ্য" : "Items"}</h3>
            <div ref={prodRef} className="relative mb-4">
              <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
              <input
                className={`${inputCls} pl-9`}
                placeholder={isBn ? "পণ্য যোগ করুন" : "Add product"}
                value={prodQuery}
                onChange={(e) => setProdQuery(e.target.value)}
              />
              {showProdDrop && prodResults.length > 0 && (
                <div className="absolute z-30 mt-1 w-full rounded-lg border border-border bg-popover shadow-lg max-h-48 overflow-y-auto">
                  {prodResults.map((p: any) => (
                    <button key={p.id} className="w-full text-left px-4 py-2 text-sm hover:bg-accent"
                      onClick={() => addProduct(p)}>
                      <div className="font-medium">{p.name}</div>
                      <div className="text-xs text-muted-foreground">SKU: {p.sku} · {isBn ? "স্টক" : "Stock"}: {p.stock_quantity} · ৳{p.retail_price}</div>
                    </button>
                  ))}
                </div>
              )}
            </div>

            {items.length > 0 && (
              <div className="overflow-x-auto">
                <table className="w-full text-sm">
                  <thead>
                    <tr className="border-b border-border text-left">
                      <th className="pb-2 font-medium">{isBn ? "পণ্য" : "Product"}</th>
                      <th className="pb-2 font-medium w-24">{isBn ? "পরিমাণ" : "Qty"}</th>
                      <th className="pb-2 font-medium w-32">{isBn ? "মূল্য" : "Price"}</th>
                      <th className="pb-2 font-medium w-28 text-right">{isBn ? "মোট" : "Total"}</th>
                      <th className="pb-2 w-10"></th>
                    </tr>
                  </thead>
                  <tbody>
                    {items.map((it, idx) => (
                      <tr key={`${it.product_id}-${idx}`} className="border-b border-border/30">
                        <td className="py-2">
                          <div>{it.product_name}</div>
                          <div className="text-[11px] text-muted-foreground">
                            {isBn ? "স্টক" : "Stock"}: {it.stock} · {isBn ? "মূল" : "Original"}: {it.original_qty}
                          </div>
                        </td>
                        <td className="py-2">
                          <input type="number" min={1}
                            className="w-20 rounded border border-border bg-background px-2 py-1 text-sm"
                            value={it.quantity}
                            onChange={(e) => updateItem(idx, "quantity", Number(e.target.value) || 1)} />
                        </td>
                        <td className="py-2">
                          <input type="number" min={0}
                            className="w-28 rounded border border-border bg-background px-2 py-1 text-sm"
                            value={it.price}
                            onChange={(e) => updateItem(idx, "price", Number(e.target.value) || 0)} />
                        </td>
                        <td className="py-2 text-right font-medium">৳{it.total.toLocaleString()}</td>
                        <td className="py-2">
                          <button onClick={() => removeItem(idx)} className="text-red-500 hover:text-red-700">
                            <Trash2 className="h-4 w-4" />
                          </button>
                        </td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
            )}
          </div>
        </div>

        <div className="space-y-4">
          <div className="rounded-xl border border-border bg-card p-5 space-y-3">
            <div>
              <label className="text-xs font-medium text-muted-foreground">{isBn ? "অর্ডার তারিখ" : "Order Date"}</label>
              <input type="date" className={inputCls} value={orderDate} onChange={(e) => setOrderDate(e.target.value)} />
            </div>
            <div>
              <label className="text-xs font-medium text-muted-foreground">{isBn ? "ডেলিভারি তারিখ" : "Delivery Date"}</label>
              <input type="date" className={inputCls} value={deliveryDate} onChange={(e) => setDeliveryDate(e.target.value)} />
            </div>
            <div>
              <label className="text-xs font-medium text-muted-foreground">{isBn ? "শাখা" : "Branch"}</label>
              <select className={inputCls} value={branchId} onChange={(e) => setBranchId(e.target.value)}>
                <option value="">—</option>
                {branches.map((b: any) => <option key={b.id} value={b.id}>{b.name}</option>)}
              </select>
            </div>
            <div>
              <label className="text-xs font-medium text-muted-foreground">{isBn ? "নোট" : "Note"}</label>
              <textarea className={inputCls} rows={2} value={note} onChange={(e) => setNote(e.target.value)} />
            </div>
          </div>

          <div className="rounded-xl border border-border bg-card p-5 space-y-3">
            <div className="flex justify-between text-sm">
              <span className="text-muted-foreground">{isBn ? "সাবটোটাল" : "Subtotal"}</span>
              <span className="font-medium">৳{subtotal.toLocaleString()}</span>
            </div>
            <div>
              <label className="text-xs font-medium text-muted-foreground">{isBn ? "ছাড়" : "Discount"}</label>
              <input type="number" min={0} className={inputCls} value={discount} onChange={(e) => setDiscount(Number(e.target.value) || 0)} />
            </div>
            <div className="flex justify-between text-sm pt-2 border-t border-border">
              <span className="font-semibold">{isBn ? "মোট" : "Total"}</span>
              <span className="font-bold text-primary">৳{totalAmount.toLocaleString()}</span>
            </div>
            <div>
              <label className="text-xs font-medium text-muted-foreground">{isBn ? "পরিশোধিত" : "Paid"}</label>
              <input type="number" min={0} className={inputCls} value={paidAmount} onChange={(e) => setPaidAmount(Number(e.target.value) || 0)} />
            </div>
            <div>
              <label className="text-xs font-medium text-muted-foreground">{isBn ? "পেমেন্ট মাধ্যম" : "Payment Method"}</label>
              <select className={inputCls} value={paymentMethod} onChange={(e) => setPaymentMethod(e.target.value)}>
                <option value="cash">{isBn ? "নগদ" : "Cash"}</option>
                <option value="bkash">bKash</option>
                <option value="nagad">Nagad</option>
                <option value="bank">{isBn ? "ব্যাংক" : "Bank"}</option>
              </select>
            </div>
            <div className="flex justify-between text-sm pt-2 border-t border-border">
              <span className="text-muted-foreground">{isBn ? "বকেয়া" : "Due"}</span>
              <span className="font-semibold text-orange-600">৳{dueAmount.toLocaleString()}</span>
            </div>
          </div>
        </div>
      </div>
    </PageLayout>
  );
}
