import { createFileRoute } from "@tanstack/react-router";
import { PageLayout } from "@/components/PageLayout";
import { useLanguage } from "@/hooks/use-language";
import { useAuth } from "@/hooks/use-auth";
import { useState } from "react";
import { supabase } from "@/integrations/supabase/client";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";
import { Wallet, Search, Plus, Pencil, Trash2, History, ShieldAlert, Users, FileSpreadsheet, FileText, Download, AlertTriangle, CheckCircle2 } from "lucide-react";
import { exportCSV, exportXLSX, exportPDF } from "@/lib/export-utils";

export const Route = createFileRoute("/_authenticated/wallet-management")({
  head: () => ({ meta: [{ title: "Wallet Management — Niyamah ERP" }] }),
  component: WalletManagementPage,
});

type Customer = { id: string; name: string; name_bn: string; mobile: string };
type Tx = {
  id: string;
  customer_id: string;
  type: string;
  amount: number;
  note: string | null;
  reference_id: string | null;
  balance_after: number;
  transaction_date: string;
  created_at: string;
  deleted_at: string | null;
};

const TX_TYPES = [
  { v: "commission_credit", l_bn: "রেফারেল ক্রেডিট", l_en: "Referral Credit", sign: 1 },
  { v: "withdrawal_debit", l_bn: "ক্যাশ আউট ডেবিট", l_en: "Cash Out Debit", sign: -1 },
  { v: "due_adjustment_debit", l_bn: "ডিউ সমন্বয়", l_en: "Due Adjustment", sign: -1 },
  { v: "manual_adjustment", l_bn: "ম্যানুয়াল সমন্বয় (+/-)", l_en: "Manual Adjustment (+/-)", sign: 0 },
];

function WalletManagementPage() {
  const { lang } = useLanguage();
  const isBn = lang === "bn";
  const qc = useQueryClient();
  const { user } = useAuth();

  const { data: isAdmin = false } = useQuery({
    queryKey: ["is-admin", user?.id],
    enabled: !!user?.id,
    queryFn: async () => {
      const { data } = await supabase.from("user_roles").select("role").eq("user_id", user!.id).eq("role", "admin").maybeSingle();
      return !!data;
    },
  });

  const [search, setSearch] = useState("");
  const [results, setResults] = useState<Customer[]>([]);
  const [selected, setSelected] = useState<Customer | null>(null);

  const [showAdd, setShowAdd] = useState(false);
  const [editTx, setEditTx] = useState<Tx | null>(null);
  const [deleteTx, setDeleteTx] = useState<Tx | null>(null);
  const [showAudit, setShowAudit] = useState(false);
  const [showBulk, setShowBulk] = useState(false);
  const [showRecon, setShowRecon] = useState(false);
  const [showExport, setShowExport] = useState(false);

  const handleSearch = async (q: string) => {
    setSearch(q);
    if (q.length < 2) { setResults([]); return; }
    const { data } = await supabase
      .from("customers")
      .select("id, name, name_bn, mobile")
      .or(`name.ilike.%${q}%,name_bn.ilike.%${q}%,mobile.ilike.%${q}%`)
      .limit(8);
    setResults(data || []);
  };

  const { data: wallet } = useQuery({
    queryKey: ["wm-wallet", selected?.id],
    enabled: !!selected,
    queryFn: async () => {
      const { data } = await supabase.from("referral_wallets").select("*").eq("customer_id", selected!.id).maybeSingle();
      return data;
    },
  });

  const { data: transactions = [], refetch: refetchTx } = useQuery({
    queryKey: ["wm-tx", selected?.id],
    enabled: !!selected,
    queryFn: async () => {
      const { data } = await supabase
        .from("wallet_transactions")
        .select("*")
        .eq("customer_id", selected!.id)
        .is("deleted_at", null)
        .order("transaction_date", { ascending: false });
      return (data || []) as Tx[];
    },
  });

  const { data: deletedTx = [] } = useQuery({
    queryKey: ["wm-tx-deleted", selected?.id],
    enabled: !!selected && showAudit,
    queryFn: async () => {
      const { data } = await supabase
        .from("wallet_transactions")
        .select("*")
        .eq("customer_id", selected!.id)
        .not("deleted_at", "is", null)
        .order("deleted_at", { ascending: false });
      return (data || []) as Tx[];
    },
  });

  const { data: audit = [] } = useQuery({
    queryKey: ["wm-audit", selected?.id],
    enabled: !!selected && showAudit,
    queryFn: async () => {
      const { data } = await supabase
        .from("wallet_transaction_audit")
        .select("*")
        .eq("customer_id", selected!.id)
        .order("created_at", { ascending: false })
        .limit(100);
      return data || [];
    },
  });

  // Client-side recalc — sums non-deleted transactions and updates referral_wallets + balance_after for ordering
  const recalc = async (customerId: string) => {
    const { data: rows } = await supabase
      .from("wallet_transactions")
      .select("id, type, amount, transaction_date, created_at")
      .eq("customer_id", customerId)
      .is("deleted_at", null)
      .order("transaction_date", { ascending: true })
      .order("created_at", { ascending: true });
    let bal = 0, credit = 0, paid = 0, adjusted = 0;
    for (const r of rows || []) {
      const a = Number(r.amount);
      if (r.type === "commission_credit") { bal += a; credit += a; }
      else if (r.type === "withdrawal_debit") { bal -= a; paid += a; }
      else if (r.type === "due_adjustment_debit") { bal -= a; adjusted += a; }
      else if (r.type === "manual_adjustment") { bal += a; }
      await supabase.from("wallet_transactions").update({ balance_after: bal }).eq("id", r.id);
    }
    await supabase.from("referral_wallets").upsert({
      customer_id: customerId,
      total_commission: credit,
      paid_amount: paid,
      adjusted_amount: adjusted,
      balance: bal,
      updated_at: new Date().toISOString(),
    }, { onConflict: "customer_id" });
  };

  const refreshAll = () => {
    qc.invalidateQueries({ queryKey: ["wm-wallet"] });
    qc.invalidateQueries({ queryKey: ["wm-tx"] });
    qc.invalidateQueries({ queryKey: ["wm-tx-deleted"] });
    qc.invalidateQueries({ queryKey: ["wm-audit"] });
    qc.invalidateQueries({ queryKey: ["wallet"] });
    qc.invalidateQueries({ queryKey: ["wallet-tx"] });
  };

  const addMut = useMutation({
    mutationFn: async (form: { type: string; amount: number; note: string; reference_id: string; transaction_date: string }) => {
      if (!selected) throw new Error("Select customer");
      if (!form.amount) throw new Error("Amount required");
      const { data: ins, error } = await supabase.from("wallet_transactions").insert({
        customer_id: selected.id,
        type: form.type,
        amount: form.amount,
        balance_after: 0,
        note: form.note,
        reference_id: form.reference_id,
        transaction_date: form.transaction_date,
        created_by: user?.id,
      }).select("id").single();
      if (error) throw error;
      await recalc(selected.id);
      await supabase.from("wallet_transaction_audit").insert({
        transaction_id: ins.id, customer_id: selected.id, action: "create",
        new_data: form, performed_by: user?.id,
      });
    },
    onSuccess: () => { toast.success(isBn ? "ট্রানজ্যাকশন যোগ হয়েছে" : "Transaction added"); setShowAdd(false); refreshAll(); refetchTx(); },
    onError: (e: any) => toast.error(e.message),
  });

  const editMut = useMutation({
    mutationFn: async (form: { type: string; amount: number; note: string; transaction_date: string }) => {
      if (!editTx || !selected) throw new Error("No transaction");
      const prev = { type: editTx.type, amount: editTx.amount, note: editTx.note, transaction_date: editTx.transaction_date };
      const { error } = await supabase.from("wallet_transactions").update({
        type: form.type, amount: form.amount, note: form.note,
        transaction_date: form.transaction_date,
        updated_at: new Date().toISOString(), updated_by: user?.id,
      }).eq("id", editTx.id);
      if (error) throw error;
      await recalc(selected.id);
      await supabase.from("wallet_transaction_audit").insert({
        transaction_id: editTx.id, customer_id: selected.id, action: "update",
        previous_data: prev, new_data: form, performed_by: user?.id,
      });
    },
    onSuccess: () => { toast.success(isBn ? "আপডেট হয়েছে" : "Updated"); setEditTx(null); refreshAll(); },
    onError: (e: any) => toast.error(e.message),
  });

  const delMut = useMutation({
    mutationFn: async () => {
      if (!deleteTx || !selected) throw new Error("No transaction");
      const { error } = await supabase.from("wallet_transactions").update({
        deleted_at: new Date().toISOString(), deleted_by: user?.id,
      }).eq("id", deleteTx.id);
      if (error) throw error;
      await recalc(selected.id);
      await supabase.from("wallet_transaction_audit").insert({
        transaction_id: deleteTx.id, customer_id: selected.id, action: "delete",
        previous_data: { type: deleteTx.type, amount: deleteTx.amount, note: deleteTx.note },
        performed_by: user?.id,
      });
    },
    onSuccess: () => { toast.success(isBn ? "মুছে ফেলা হয়েছে" : "Deleted"); setDeleteTx(null); refreshAll(); },
    onError: (e: any) => toast.error(e.message),
  });

  const restoreMut = useMutation({
    mutationFn: async (tx: Tx) => {
      if (!selected) return;
      await supabase.from("wallet_transactions").update({ deleted_at: null, deleted_by: null }).eq("id", tx.id);
      await recalc(selected.id);
      await supabase.from("wallet_transaction_audit").insert({
        transaction_id: tx.id, customer_id: selected.id, action: "restore", performed_by: user?.id,
      });
    },
    onSuccess: () => { toast.success(isBn ? "পুনরুদ্ধার হয়েছে" : "Restored"); refreshAll(); },
    onError: (e: any) => toast.error(e.message),
  });

  if (!isAdmin) {
    return (
      <PageLayout>
        <div className="rounded-2xl border border-destructive/30 bg-destructive/5 p-8 text-center">
          <ShieldAlert className="h-10 w-10 mx-auto text-destructive mb-2" />
          <h1 className="text-xl font-bold">{isBn ? "অনুমতি নেই" : "Permission denied"}</h1>
          <p className="text-sm text-muted-foreground mt-1">{isBn ? "শুধু অ্যাডমিন এই পেজ ব্যবহার করতে পারবেন" : "Only admins can access this page"}</p>
        </div>
      </PageLayout>
    );
  }

  return (
    <PageLayout>
      <div className="mb-6 flex items-center justify-between flex-wrap gap-3">
        <div>
          <h1 className="text-2xl font-bold flex items-center gap-2"><Wallet className="h-6 w-6 text-primary" />{isBn ? "ওয়ালেট ম্যানেজমেন্ট" : "Wallet Management"}</h1>
          <p className="text-sm text-muted-foreground">{isBn ? "ওয়ালেট ট্রানজ্যাকশন যোগ, এডিট ও ডিলিট করুন" : "Add, edit and delete wallet transactions"}</p>
        </div>
        <div className="flex gap-2 flex-wrap">
          <button onClick={() => setShowBulk(true)} className="rounded-lg border border-border bg-background px-3 py-2 text-sm flex items-center gap-1"><Users className="h-4 w-4" />{isBn ? "বাল্ক সমন্বয়" : "Bulk Adjust"}</button>
          <button onClick={() => setShowRecon(true)} className="rounded-lg border border-border bg-background px-3 py-2 text-sm flex items-center gap-1"><CheckCircle2 className="h-4 w-4" />{isBn ? "রিকনসিলিয়েশন" : "Reconcile"}</button>
          {selected && (
            <>
              <button onClick={() => setShowExport(true)} className="rounded-lg border border-border bg-background px-3 py-2 text-sm flex items-center gap-1"><Download className="h-4 w-4" />{isBn ? "এক্সপোর্ট" : "Export"}</button>
              <button onClick={() => setShowAudit((s) => !s)} className="rounded-lg border border-border bg-background px-3 py-2 text-sm flex items-center gap-1"><History className="h-4 w-4" />{isBn ? "অডিট লগ" : "Audit Log"}</button>
              <button onClick={() => setShowAdd(true)} className="rounded-lg bg-primary text-primary-foreground px-3 py-2 text-sm flex items-center gap-1"><Plus className="h-4 w-4" />{isBn ? "নতুন" : "Add"}</button>
            </>
          )}
        </div>
      </div>

      <div className="rounded-2xl border border-border bg-card p-5 mb-6">
        <label className="text-xs font-medium text-muted-foreground">{isBn ? "কাস্টমার সার্চ" : "Search customer"}</label>
        <div className="relative mt-1">
          <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
          <input value={search} onChange={(e) => handleSearch(e.target.value)} className="w-full rounded-lg border border-input bg-background pl-9 pr-3 py-2 text-sm" placeholder={isBn ? "নাম বা মোবাইল" : "Name or mobile"} />
          {results.length > 0 && !selected && (
            <div className="absolute z-10 mt-1 w-full rounded-lg border border-border bg-popover shadow-lg">
              {results.map((c) => (
                <button key={c.id} onClick={() => { setSelected(c); setSearch(""); setResults([]); }} className="block w-full text-left px-3 py-2 text-sm hover:bg-accent">
                  {isBn ? c.name_bn || c.name : c.name} <span className="text-muted-foreground">({c.mobile})</span>
                </button>
              ))}
            </div>
          )}
        </div>
        {selected && (
          <div className="mt-3 flex items-center justify-between bg-muted/30 rounded-lg p-3">
            <div className="text-sm font-medium">{isBn ? selected.name_bn || selected.name : selected.name} <span className="text-muted-foreground">({selected.mobile})</span></div>
            <button onClick={() => setSelected(null)} className="text-xs text-destructive">{isBn ? "পরিবর্তন" : "Change"}</button>
          </div>
        )}
      </div>

      {selected && (
        <>
          <div className="grid grid-cols-2 md:grid-cols-4 gap-3 mb-6">
            <Stat label={isBn ? "মোট কমিশন" : "Total Earned"} value={Number(wallet?.total_commission || 0)} color="text-primary" />
            <Stat label={isBn ? "পরিশোধিত" : "Paid"} value={Number(wallet?.paid_amount || 0)} color="text-muted-foreground" />
            <Stat label={isBn ? "সমন্বয়" : "Adjusted"} value={Number(wallet?.adjusted_amount || 0)} color="text-amber-600" />
            <Stat label={isBn ? "ব্যালেন্স" : "Balance"} value={Number(wallet?.balance || 0)} color="text-green-600" />
          </div>

          <div className="rounded-2xl border border-border bg-card overflow-hidden mb-6">
            <div className="overflow-x-auto">
              <table className="w-full text-sm">
                <thead className="bg-muted/40 text-xs">
                  <tr className="text-left">
                    <th className="px-3 py-2">{isBn ? "তারিখ" : "Date"}</th>
                    <th className="px-3 py-2">{isBn ? "ধরন" : "Type"}</th>
                    <th className="px-3 py-2">{isBn ? "নোট / রেফ" : "Note / Ref"}</th>
                    <th className="px-3 py-2 text-right">{isBn ? "পরিমাণ" : "Amount"}</th>
                    <th className="px-3 py-2 text-right">{isBn ? "ব্যালেন্স" : "Balance After"}</th>
                    <th className="px-3 py-2 text-right">{isBn ? "অ্যাকশন" : "Action"}</th>
                  </tr>
                </thead>
                <tbody>
                  {transactions.length === 0 && (
                    <tr><td colSpan={6} className="px-3 py-6 text-center text-xs text-muted-foreground">{isBn ? "কোনো ট্রানজ্যাকশন নেই" : "No transactions"}</td></tr>
                  )}
                  {transactions.map((t) => (
                    <tr key={t.id} className="border-t border-border">
                      <td className="px-3 py-2 text-xs">{new Date(t.transaction_date).toLocaleString()}</td>
                      <td className="px-3 py-2 text-xs">{TX_TYPES.find(x => x.v === t.type)?.[isBn ? "l_bn" : "l_en"] || t.type}</td>
                      <td className="px-3 py-2 text-xs">{t.note}{t.reference_id ? <span className="text-muted-foreground"> · {t.reference_id}</span> : null}</td>
                      <td className="px-3 py-2 text-right font-semibold">৳{Number(t.amount).toFixed(2)}</td>
                      <td className="px-3 py-2 text-right text-xs">৳{Number(t.balance_after).toFixed(2)}</td>
                      <td className="px-3 py-2 text-right">
                        <div className="inline-flex gap-1">
                          <button onClick={() => setEditTx(t)} className="p-1.5 rounded hover:bg-accent" title="Edit"><Pencil className="h-3.5 w-3.5" /></button>
                          <button onClick={() => setDeleteTx(t)} className="p-1.5 rounded hover:bg-destructive/10 text-destructive" title="Delete"><Trash2 className="h-3.5 w-3.5" /></button>
                        </div>
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          </div>

          {showAudit && (
            <div className="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-6">
              <div className="rounded-2xl border border-border bg-card p-5">
                <h2 className="font-semibold mb-3">{isBn ? "ডিলিটেড ট্রানজ্যাকশন" : "Deleted Transactions"}</h2>
                <div className="space-y-2 max-h-80 overflow-y-auto">
                  {deletedTx.length === 0 && <p className="text-xs text-muted-foreground">{isBn ? "নেই" : "None"}</p>}
                  {deletedTx.map((t) => (
                    <div key={t.id} className="flex items-center justify-between text-sm border-b border-border pb-2">
                      <div>
                        <p className="font-medium">৳{Number(t.amount).toFixed(2)} <span className="text-xs text-muted-foreground">{t.type}</span></p>
                        <p className="text-xs text-muted-foreground">{new Date(t.deleted_at!).toLocaleString()}</p>
                      </div>
                      <button onClick={() => restoreMut.mutate(t)} className="text-xs text-primary">{isBn ? "পুনরুদ্ধার" : "Restore"}</button>
                    </div>
                  ))}
                </div>
              </div>
              <div className="rounded-2xl border border-border bg-card p-5">
                <h2 className="font-semibold mb-3">{isBn ? "অডিট লগ" : "Audit Log"}</h2>
                <div className="space-y-2 max-h-80 overflow-y-auto">
                  {audit.length === 0 && <p className="text-xs text-muted-foreground">{isBn ? "নেই" : "None"}</p>}
                  {audit.map((a: any) => (
                    <div key={a.id} className="text-xs border-b border-border pb-2">
                      <p className="font-medium uppercase">{a.action}</p>
                      <p className="text-muted-foreground">{new Date(a.created_at).toLocaleString()}</p>
                      {a.previous_data && Object.keys(a.previous_data).length > 0 && (
                        <p className="text-muted-foreground">prev: {JSON.stringify(a.previous_data)}</p>
                      )}
                      {a.new_data && Object.keys(a.new_data).length > 0 && (
                        <p>new: {JSON.stringify(a.new_data)}</p>
                      )}
                    </div>
                  ))}
                </div>
              </div>
            </div>
          )}
        </>
      )}

      {showAdd && selected && <TxModal isBn={isBn} title={isBn ? "নতুন ট্রানজ্যাকশন" : "New Transaction"} onClose={() => setShowAdd(false)} onSubmit={(f) => addMut.mutate(f)} pending={addMut.isPending} />}
      {editTx && <TxModal isBn={isBn} title={isBn ? "এডিট" : "Edit"} initial={editTx} onClose={() => setEditTx(null)} onSubmit={(f) => editMut.mutate(f)} pending={editMut.isPending} />}
      {deleteTx && (
        <Modal onClose={() => setDeleteTx(null)}>
          <h2 className="text-lg font-semibold mb-2">{isBn ? "নিশ্চিত করুন" : "Confirm Delete"}</h2>
          <p className="text-sm text-muted-foreground mb-4">{isBn ? "এই ট্রানজ্যাকশন সফট-ডিলিট হবে এবং ব্যালেন্স পুনঃগণনা হবে।" : "This transaction will be soft-deleted and the balance will be recalculated."}</p>
          <div className="flex justify-end gap-2">
            <button onClick={() => setDeleteTx(null)} className="rounded-lg border border-border px-3 py-2 text-sm">{isBn ? "বাতিল" : "Cancel"}</button>
            <button onClick={() => delMut.mutate()} disabled={delMut.isPending} className="rounded-lg bg-destructive text-destructive-foreground px-3 py-2 text-sm">{delMut.isPending ? "..." : isBn ? "ডিলিট" : "Delete"}</button>
          </div>
        </Modal>
      )}

      {showExport && selected && (
        <ExportModal
          isBn={isBn}
          customerName={isBn ? selected.name_bn || selected.name : selected.name}
          rows={transactions.map((t) => ({
            Date: new Date(t.transaction_date).toLocaleString(),
            Type: t.type,
            Amount: Number(t.amount).toFixed(2),
            "Balance After": Number(t.balance_after).toFixed(2),
            Note: t.note || "",
            Reference: t.reference_id || "",
          }))}
          filename={`wallet-${selected.mobile}-${new Date().toISOString().slice(0, 10)}`}
          title={`Wallet Transactions — ${selected.name} (${selected.mobile})`}
          onClose={() => setShowExport(false)}
        />
      )}

      {showBulk && <BulkAdjustModal isBn={isBn} userId={user?.id} onClose={() => setShowBulk(false)} onDone={refreshAll} recalc={recalc} />}
      {showRecon && <ReconcileModal isBn={isBn} onClose={() => setShowRecon(false)} />}
    </PageLayout>
  );
}

function Stat({ label, value, color }: { label: string; value: number; color: string }) {
  return (
    <div className="rounded-2xl border border-border bg-card p-5">
      <p className="text-xs text-muted-foreground">{label}</p>
      <p className={`text-2xl font-bold mt-1 ${color}`}>৳{value.toFixed(2)}</p>
    </div>
  );
}

function Modal({ children, onClose }: { children: React.ReactNode; onClose: () => void }) {
  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4" onClick={onClose}>
      <div className="w-full max-w-md rounded-2xl bg-card border border-border p-6 shadow-xl" onClick={(e) => e.stopPropagation()}>
        {children}
      </div>
    </div>
  );
}

function TxModal({ isBn, title, initial, onClose, onSubmit, pending }: {
  isBn: boolean;
  title: string;
  initial?: Tx;
  onClose: () => void;
  onSubmit: (f: { type: string; amount: number; note: string; reference_id: string; transaction_date: string }) => void;
  pending: boolean;
}) {
  const [type, setType] = useState(initial?.type || "manual_adjustment");
  const [amount, setAmount] = useState<number>(initial?.amount ? Number(initial.amount) : 0);
  const [note, setNote] = useState(initial?.note || "");
  const [refId, setRefId] = useState(initial?.reference_id || "");
  const [date, setDate] = useState((initial?.transaction_date || new Date().toISOString()).slice(0, 16));

  return (
    <Modal onClose={onClose}>
      <h2 className="text-lg font-semibold mb-4">{title}</h2>
      <div className="space-y-3">
        <div>
          <label className="text-xs text-muted-foreground">{isBn ? "ধরন" : "Type"}</label>
          <select value={type} onChange={(e) => setType(e.target.value)} className="w-full rounded-lg border border-input bg-background px-3 py-2 text-sm">
            {TX_TYPES.map((t) => <option key={t.v} value={t.v}>{isBn ? t.l_bn : t.l_en}</option>)}
          </select>
          {type === "manual_adjustment" && <p className="text-[10px] text-muted-foreground mt-1">{isBn ? "ক্রেডিটের জন্য পজিটিভ, ডেবিটের জন্য নেগেটিভ" : "Positive for credit, negative for debit"}</p>}
        </div>
        <div>
          <label className="text-xs text-muted-foreground">{isBn ? "পরিমাণ (৳)" : "Amount (৳)"}</label>
          <input type="number" step="0.01" value={amount || ""} onChange={(e) => setAmount(parseFloat(e.target.value) || 0)} className="w-full rounded-lg border border-input bg-background px-3 py-2 text-sm" />
        </div>
        <div>
          <label className="text-xs text-muted-foreground">{isBn ? "তারিখ" : "Date"}</label>
          <input type="datetime-local" value={date} onChange={(e) => setDate(e.target.value)} className="w-full rounded-lg border border-input bg-background px-3 py-2 text-sm" />
        </div>
        <div>
          <label className="text-xs text-muted-foreground">{isBn ? "নোট" : "Note"}</label>
          <input value={note} onChange={(e) => setNote(e.target.value)} className="w-full rounded-lg border border-input bg-background px-3 py-2 text-sm" />
        </div>
        {!initial && (
          <div>
            <label className="text-xs text-muted-foreground">{isBn ? "রেফারেন্স আইডি" : "Reference ID"}</label>
            <input value={refId} onChange={(e) => setRefId(e.target.value)} className="w-full rounded-lg border border-input bg-background px-3 py-2 text-sm" />
          </div>
        )}
        <div className="flex justify-end gap-2 pt-2">
          <button onClick={onClose} className="rounded-lg border border-border px-3 py-2 text-sm">{isBn ? "বাতিল" : "Cancel"}</button>
          <button onClick={() => onSubmit({ type, amount, note, reference_id: refId, transaction_date: new Date(date).toISOString() })} disabled={pending || !amount} className="rounded-lg bg-primary text-primary-foreground px-3 py-2 text-sm disabled:opacity-50">
            {pending ? "..." : isBn ? "সংরক্ষণ" : "Save"}
          </button>
        </div>
      </div>
    </Modal>
  );
}

function ExportModal({ isBn, customerName, rows, filename, title, onClose }: {
  isBn: boolean; customerName: string; rows: Record<string, string | number>[]; filename: string; title: string; onClose: () => void;
}) {
  const empty = rows.length === 0;
  return (
    <Modal onClose={onClose}>
      <h2 className="text-lg font-semibold mb-1">{isBn ? "এক্সপোর্ট" : "Export"}</h2>
      <p className="text-xs text-muted-foreground mb-4">{customerName} · {rows.length} {isBn ? "ট্রানজ্যাকশন" : "transactions"}</p>
      <div className="grid grid-cols-3 gap-2">
        <button disabled={empty} onClick={() => { exportXLSX(filename, rows, "Wallet"); onClose(); }} className="rounded-lg border border-border p-3 text-xs flex flex-col items-center gap-1 hover:bg-accent disabled:opacity-50">
          <FileSpreadsheet className="h-5 w-5 text-green-600" />Excel
        </button>
        <button disabled={empty} onClick={() => { exportCSV(filename, rows); onClose(); }} className="rounded-lg border border-border p-3 text-xs flex flex-col items-center gap-1 hover:bg-accent disabled:opacity-50">
          <FileText className="h-5 w-5 text-blue-600" />CSV
        </button>
        <button disabled={empty} onClick={() => { exportPDF(filename, title, rows); onClose(); }} className="rounded-lg border border-border p-3 text-xs flex flex-col items-center gap-1 hover:bg-accent disabled:opacity-50">
          <FileText className="h-5 w-5 text-red-600" />PDF
        </button>
      </div>
      {empty && <p className="text-xs text-destructive mt-3">{isBn ? "এক্সপোর্ট করার মতো কিছু নেই" : "Nothing to export"}</p>}
    </Modal>
  );
}

function BulkAdjustModal({ isBn, userId, onClose, onDone, recalc }: {
  isBn: boolean; userId: string | undefined; onClose: () => void; onDone: () => void; recalc: (id: string) => Promise<void>;
}) {
  const [q, setQ] = useState("");
  const [results, setResults] = useState<Customer[]>([]);
  const [picked, setPicked] = useState<Customer[]>([]);
  const [type, setType] = useState("manual_adjustment");
  const [amount, setAmount] = useState<number>(0);
  const [note, setNote] = useState("");
  const [running, setRunning] = useState(false);

  const search = async (v: string) => {
    setQ(v);
    if (v.length < 2) { setResults([]); return; }
    const { data } = await supabase.from("customers").select("id, name, name_bn, mobile").or(`name.ilike.%${v}%,name_bn.ilike.%${v}%,mobile.ilike.%${v}%`).limit(10);
    setResults((data || []).filter((c) => !picked.find((p) => p.id === c.id)));
  };

  const add = (c: Customer) => { setPicked((p) => [...p, c]); setResults((r) => r.filter((x) => x.id !== c.id)); setQ(""); };
  const remove = (id: string) => setPicked((p) => p.filter((x) => x.id !== id));

  const apply = async () => {
    if (!picked.length || !amount) { toast.error(isBn ? "কাস্টমার ও পরিমাণ দরকার" : "Customers & amount required"); return; }
    setRunning(true);
    let ok = 0, fail = 0;
    for (const c of picked) {
      try {
        const { data: ins } = await supabase.from("wallet_transactions").insert({
          customer_id: c.id, type, amount, balance_after: 0, note,
          transaction_date: new Date().toISOString(), created_by: userId,
        }).select("id").single();
        await recalc(c.id);
        if (ins) await supabase.from("wallet_transaction_audit").insert({
          transaction_id: ins.id, customer_id: c.id, action: "create",
          new_data: { type, amount, note, bulk: true }, performed_by: userId,
        });
        ok++;
      } catch { fail++; }
    }
    setRunning(false);
    toast.success(`${ok} ${isBn ? "সফল" : "applied"}${fail ? `, ${fail} ${isBn ? "ব্যর্থ" : "failed"}` : ""}`);
    onDone(); onClose();
  };

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4" onClick={onClose}>
      <div className="w-full max-w-2xl rounded-2xl bg-card border border-border p-6 shadow-xl max-h-[90vh] overflow-y-auto" onClick={(e) => e.stopPropagation()}>
        <h2 className="text-lg font-semibold mb-1 flex items-center gap-2"><Users className="h-5 w-5" />{isBn ? "বাল্ক ওয়ালেট সমন্বয়" : "Bulk Wallet Adjustment"}</h2>
        <p className="text-xs text-muted-foreground mb-4">{isBn ? "একসাথে অনেক কাস্টমারের ওয়ালেটে একই ট্রানজ্যাকশন প্রয়োগ করুন" : "Apply the same transaction to many customers at once"}</p>

        <div className="relative mb-3">
          <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
          <input value={q} onChange={(e) => search(e.target.value)} placeholder={isBn ? "কাস্টমার সার্চ" : "Search customer"} className="w-full rounded-lg border border-input bg-background pl-9 pr-3 py-2 text-sm" />
          {results.length > 0 && (
            <div className="absolute z-10 mt-1 w-full rounded-lg border border-border bg-popover shadow-lg max-h-48 overflow-y-auto">
              {results.map((c) => (
                <button key={c.id} onClick={() => add(c)} className="block w-full text-left px-3 py-2 text-sm hover:bg-accent">
                  {isBn ? c.name_bn || c.name : c.name} <span className="text-muted-foreground">({c.mobile})</span>
                </button>
              ))}
            </div>
          )}
        </div>

        <div className="rounded-lg border border-border p-3 mb-4 min-h-[60px]">
          {picked.length === 0 ? (
            <p className="text-xs text-muted-foreground">{isBn ? "কোনো কাস্টমার নির্বাচিত নয়" : "No customers selected"}</p>
          ) : (
            <div className="flex flex-wrap gap-1.5">
              {picked.map((c) => (
                <span key={c.id} className="inline-flex items-center gap-1 rounded-full bg-primary/10 text-primary text-xs px-2 py-1">
                  {isBn ? c.name_bn || c.name : c.name}
                  <button onClick={() => remove(c.id)} className="hover:text-destructive">×</button>
                </span>
              ))}
            </div>
          )}
          <p className="text-[10px] text-muted-foreground mt-2">{picked.length} {isBn ? "জন নির্বাচিত" : "selected"}</p>
        </div>

        <div className="grid grid-cols-2 gap-3 mb-3">
          <div>
            <label className="text-xs text-muted-foreground">{isBn ? "ধরন" : "Type"}</label>
            <select value={type} onChange={(e) => setType(e.target.value)} className="w-full rounded-lg border border-input bg-background px-3 py-2 text-sm">
              {TX_TYPES.map((t) => <option key={t.v} value={t.v}>{isBn ? t.l_bn : t.l_en}</option>)}
            </select>
          </div>
          <div>
            <label className="text-xs text-muted-foreground">{isBn ? "পরিমাণ (৳)" : "Amount (৳)"}</label>
            <input type="number" step="0.01" value={amount || ""} onChange={(e) => setAmount(parseFloat(e.target.value) || 0)} className="w-full rounded-lg border border-input bg-background px-3 py-2 text-sm" />
          </div>
        </div>
        <div className="mb-4">
          <label className="text-xs text-muted-foreground">{isBn ? "নোট" : "Note"}</label>
          <input value={note} onChange={(e) => setNote(e.target.value)} className="w-full rounded-lg border border-input bg-background px-3 py-2 text-sm" />
        </div>

        <div className="flex justify-end gap-2">
          <button onClick={onClose} className="rounded-lg border border-border px-3 py-2 text-sm">{isBn ? "বাতিল" : "Cancel"}</button>
          <button onClick={apply} disabled={running || !picked.length || !amount} className="rounded-lg bg-primary text-primary-foreground px-3 py-2 text-sm disabled:opacity-50">
            {running ? "..." : `${isBn ? "প্রয়োগ" : "Apply"} (${picked.length})`}
          </button>
        </div>
      </div>
    </div>
  );
}

type ReconRow = { customer_id: string; name: string; mobile: string; commissions_total: number; wallet_credits: number; diff: number };

function ReconcileModal({ isBn, onClose }: { isBn: boolean; onClose: () => void }) {
  const { data: rows = [], isLoading } = useQuery({
    queryKey: ["wallet-reconcile"],
    queryFn: async (): Promise<ReconRow[]> => {
      const [{ data: comms }, { data: txs }, { data: custs }] = await Promise.all([
        supabase.from("commissions").select("customer_id, amount, status"),
        supabase.from("wallet_transactions").select("customer_id, amount, type").is("deleted_at", null).eq("type", "commission_credit"),
        supabase.from("customers").select("id, name, name_bn, mobile"),
      ]);
      const cMap = new Map<string, number>();
      (comms || []).filter((c: any) => c.status !== "cancelled").forEach((c: any) => {
        cMap.set(c.customer_id, (cMap.get(c.customer_id) || 0) + Number(c.amount));
      });
      const wMap = new Map<string, number>();
      (txs || []).forEach((t: any) => wMap.set(t.customer_id, (wMap.get(t.customer_id) || 0) + Number(t.amount)));
      const ids = new Set<string>([...cMap.keys(), ...wMap.keys()]);
      const cust = new Map((custs || []).map((c: any) => [c.id, c]));
      return Array.from(ids).map((id) => {
        const c: any = cust.get(id);
        const ct = cMap.get(id) || 0;
        const wt = wMap.get(id) || 0;
        return {
          customer_id: id,
          name: c ? (isBn ? c.name_bn || c.name : c.name) : id.slice(0, 8),
          mobile: c?.mobile || "",
          commissions_total: ct,
          wallet_credits: wt,
          diff: +(ct - wt).toFixed(2),
        };
      }).sort((a, b) => Math.abs(b.diff) - Math.abs(a.diff));
    },
  });

  const mismatched = rows.filter((r) => Math.abs(r.diff) > 0.01);

  const exportData = () => {
    const data = rows.map((r) => ({
      Customer: r.name, Mobile: r.mobile,
      "Commissions (৳)": r.commissions_total.toFixed(2),
      "Wallet Credits (৳)": r.wallet_credits.toFixed(2),
      "Diff (৳)": r.diff.toFixed(2),
      Status: Math.abs(r.diff) <= 0.01 ? "OK" : "Mismatch",
    }));
    return data;
  };

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4" onClick={onClose}>
      <div className="w-full max-w-3xl rounded-2xl bg-card border border-border p-6 shadow-xl max-h-[90vh] overflow-y-auto" onClick={(e) => e.stopPropagation()}>
        <div className="flex items-center justify-between mb-4">
          <div>
            <h2 className="text-lg font-semibold flex items-center gap-2"><CheckCircle2 className="h-5 w-5" />{isBn ? "অটো রিকনসিলিয়েশন" : "Auto Reconciliation"}</h2>
            <p className="text-xs text-muted-foreground">{isBn ? "Commissions vs Wallet Credits তুলনা" : "Compare Commissions vs Wallet Credits"}</p>
          </div>
          <div className="flex gap-1">
            <button onClick={() => exportXLSX("reconciliation", exportData(), "Reconcile")} className="p-2 rounded hover:bg-accent" title="Excel"><FileSpreadsheet className="h-4 w-4 text-green-600" /></button>
            <button onClick={() => exportCSV("reconciliation", exportData())} className="p-2 rounded hover:bg-accent" title="CSV"><FileText className="h-4 w-4 text-blue-600" /></button>
            <button onClick={() => exportPDF("reconciliation", "Wallet Reconciliation", exportData())} className="p-2 rounded hover:bg-accent" title="PDF"><FileText className="h-4 w-4 text-red-600" /></button>
          </div>
        </div>

        <div className="grid grid-cols-3 gap-3 mb-4">
          <div className="rounded-lg border border-border p-3"><p className="text-xs text-muted-foreground">{isBn ? "মোট" : "Total"}</p><p className="text-xl font-bold">{rows.length}</p></div>
          <div className="rounded-lg border border-border p-3"><p className="text-xs text-muted-foreground">{isBn ? "মিল" : "Matched"}</p><p className="text-xl font-bold text-green-600">{rows.length - mismatched.length}</p></div>
          <div className="rounded-lg border border-border p-3"><p className="text-xs text-muted-foreground">{isBn ? "অমিল" : "Mismatch"}</p><p className="text-xl font-bold text-destructive">{mismatched.length}</p></div>
        </div>

        {isLoading ? (
          <p className="text-sm text-muted-foreground text-center py-8">Loading…</p>
        ) : (
          <div className="overflow-x-auto rounded-lg border border-border">
            <table className="w-full text-sm">
              <thead className="bg-muted/40 text-xs">
                <tr className="text-left">
                  <th className="px-3 py-2">{isBn ? "কাস্টমার" : "Customer"}</th>
                  <th className="px-3 py-2 text-right">{isBn ? "কমিশন" : "Commissions"}</th>
                  <th className="px-3 py-2 text-right">{isBn ? "ওয়ালেট ক্রেডিট" : "Wallet Credits"}</th>
                  <th className="px-3 py-2 text-right">{isBn ? "পার্থক্য" : "Diff"}</th>
                  <th className="px-3 py-2 text-center">{isBn ? "স্ট্যাটাস" : "Status"}</th>
                </tr>
              </thead>
              <tbody>
                {rows.length === 0 && <tr><td colSpan={5} className="px-3 py-6 text-center text-xs text-muted-foreground">{isBn ? "কোনো ডাটা নেই" : "No data"}</td></tr>}
                {rows.map((r) => {
                  const ok = Math.abs(r.diff) <= 0.01;
                  return (
                    <tr key={r.customer_id} className="border-t border-border">
                      <td className="px-3 py-2"><p className="font-medium">{r.name}</p><p className="text-xs text-muted-foreground">{r.mobile}</p></td>
                      <td className="px-3 py-2 text-right">৳{r.commissions_total.toFixed(2)}</td>
                      <td className="px-3 py-2 text-right">৳{r.wallet_credits.toFixed(2)}</td>
                      <td className={`px-3 py-2 text-right font-semibold ${ok ? "" : "text-destructive"}`}>৳{r.diff.toFixed(2)}</td>
                      <td className="px-3 py-2 text-center">
                        {ok ? <span className="inline-flex items-center gap-1 rounded-full bg-green-500/15 text-green-700 text-[10px] px-2 py-0.5"><CheckCircle2 className="h-3 w-3" />OK</span>
                            : <span className="inline-flex items-center gap-1 rounded-full bg-destructive/15 text-destructive text-[10px] px-2 py-0.5"><AlertTriangle className="h-3 w-3" />{isBn ? "অমিল" : "Mismatch"}</span>}
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        )}

        <div className="flex justify-end mt-4">
          <button onClick={onClose} className="rounded-lg border border-border px-3 py-2 text-sm">{isBn ? "বন্ধ" : "Close"}</button>
        </div>
      </div>
    </div>
  );
}
