import { createFileRoute, Link } 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 { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { Card } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import {
  Table, TableBody, TableCell, TableHead, TableHeader, TableRow,
} from "@/components/ui/table";
import {
  Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter,
} from "@/components/ui/dialog";
import {
  AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent,
  AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import {
  Select, SelectContent, SelectItem, SelectTrigger, SelectValue,
} from "@/components/ui/select";
import { Plus, Pencil, Trash2, Search, UserCheck, UserX, Wallet, Eye, Upload } from "lucide-react";
import { toast } from "sonner";
import { usePermissions } from "@/hooks/use-permissions";
import { useLanguage } from "@/hooks/use-language";
import { StaffSalaryDialog } from "@/components/StaffSalaryDialog";
import { useServerFn } from "@tanstack/react-start";
import { createUserFn } from "@/lib/users.functions";

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

type Staff = {
  id: string;
  staff_id: string | null;
  name: string;
  mobile: string;
  email: string;
  address: string;
  role: string;
  designation: string;
  nid: string;
  username: string | null;
  joining_date: string | null;
  salary: number;
  commission_rate: number;
  photo_url: string;
  status: string;
  note: string;
  branch_id: string | null;
  department_id: string | null;
  created_at: string;
};

const ROLES = [
  { value: "super_admin", label: "Super Admin" },
  { value: "admin", label: "Admin" },
  { value: "branch_manager", label: "Branch Manager" },
  { value: "accountant", label: "Accountant" },
  { value: "cashier", label: "Cashier" },
  { value: "sales", label: "Salesman" },
  { value: "sr", label: "SR (Sales Rep)" },
  { value: "dsr", label: "DSR (Dealer Sales Rep)" },
  { value: "store_manager", label: "Store Manager" },
  { value: "warehouse_manager", label: "Warehouse Manager" },
  { value: "purchase_manager", label: "Purchase Manager" },
  { value: "support", label: "Customer Support" },
  { value: "delivery", label: "Delivery Man" },
  { value: "technician", label: "Technician" },
  { value: "operator", label: "Operator" },
  { value: "data_entry", label: "Data Entry Operator" },
  { value: "marketing", label: "Marketing Executive" },
  { value: "security", label: "Security Guard" },
  { value: "driver", label: "Driver" },
  { value: "hr_manager", label: "HR Manager" },
  { value: "manager", label: "Manager" },
  { value: "stock_keeper", label: "Stock Keeper" },
  { value: "other", label: "Other / Custom" },
];

const emptyForm = {
  name: "", mobile: "", email: "", password: "", address: "", role: "sales",
  designation: "", nid: "", username: "", joining_date: "", salary: "0",
  commission_rate: "0", status: "active", note: "",
  branch_id: "none", department_id: "none", photo_url: "",
};

function StaffPage() {
  const qc = useQueryClient();
  const { isAdmin } = usePermissions();
  const { tr } = useLanguage();

  const roleLabel = (v: string) => ROLES.find((r) => r.value === v)?.label ?? v;

  const [search, setSearch] = useState("");
  const [roleFilter, setRoleFilter] = useState<string>("all");
  const [statusFilter, setStatusFilter] = useState<string>("all");
  const [branchFilter, setBranchFilter] = useState<string>("all");
  const [departmentFilter, setDepartmentFilter] = useState<string>("all");
  const [dialogOpen, setDialogOpen] = useState(false);
  const [editing, setEditing] = useState<Staff | null>(null);
  const [form, setForm] = useState(emptyForm);
  const [deleteId, setDeleteId] = useState<string | null>(null);
  const [salaryStaff, setSalaryStaff] = useState<Staff | null>(null);
  const [photoUploading, setPhotoUploading] = useState(false);

  const { data: staff = [], isLoading } = useQuery({
    queryKey: ["staff"],
    queryFn: async () => {
      const { data, error } = await supabase
        .from("staff")
        .select("*")
        .is("deleted_at", null)
        .order("created_at", { ascending: false });
      if (error) throw error;
      return data as Staff[];
    },
  });

  const { data: branches = [] } = useQuery({
    queryKey: ["branches-list"],
    queryFn: async () => {
      const { data } = await supabase.from("branches").select("id,name").is("deleted_at", null).order("name");
      return data ?? [];
    },
  });

  const { data: departments = [] } = useQuery({
    queryKey: ["departments-list"],
    queryFn: async () => {
      const { data } = await supabase.from("departments").select("id,name,name_bn").is("deleted_at", null).order("name");
      return data ?? [];
    },
  });

  const branchName = (id?: string | null) => branches.find((b) => b.id === id)?.name ?? "-";
  const departmentName = (id?: string | null) => departments.find((d) => d.id === id)?.name ?? "-";

  const filtered = staff.filter((s) => {
    const q = search.toLowerCase();
    const matchSearch = !q ||
      s.name.toLowerCase().includes(q) ||
      s.mobile.includes(q) ||
      s.email.toLowerCase().includes(q) ||
      (s.staff_id ?? "").toLowerCase().includes(q) ||
      s.designation.toLowerCase().includes(q);
    const matchRole = roleFilter === "all" || s.role === roleFilter;
    const matchStatus = statusFilter === "all" || s.status === statusFilter;
    const matchBranch = branchFilter === "all" || s.branch_id === branchFilter;
    const matchDept = departmentFilter === "all" || s.department_id === departmentFilter;
    return matchSearch && matchRole && matchStatus && matchBranch && matchDept;
  });

  const createUser = useServerFn(createUserFn);

  const uploadPhoto = async (file: File) => {
    setPhotoUploading(true);
    try {
      const ext = file.name.split(".").pop();
      const path = `${Date.now()}-${Math.random().toString(36).slice(2)}.${ext}`;
      const { error } = await supabase.storage.from("staff-photos").upload(path, file, { upsert: false });
      if (error) throw error;
      const { data } = supabase.storage.from("staff-photos").getPublicUrl(path);
      setForm((f) => ({ ...f, photo_url: data.publicUrl }));
      toast.success("Photo uploaded");
    } catch (e: any) {
      toast.error(e.message ?? "Upload failed");
    } finally {
      setPhotoUploading(false);
    }
  };

  const saveMutation = useMutation({
    mutationFn: async () => {
      if (!form.name.trim()) throw new Error("Name is required");
      if (!form.mobile.trim()) throw new Error("Mobile is required");
      const payload = {
        name: form.name.trim(),
        mobile: form.mobile.trim(),
        email: form.email.trim(),
        address: form.address.trim(),
        role: form.role,
        designation: form.designation.trim(),
        nid: form.nid.trim(),
        username: form.username.trim() || null,
        joining_date: form.joining_date || null,
        salary: Number(form.salary) || 0,
        commission_rate: Number(form.commission_rate) || 0,
        status: form.status,
        note: form.note.trim(),
        branch_id: form.branch_id === "none" ? null : form.branch_id,
        department_id: form.department_id === "none" ? null : form.department_id,
        photo_url: form.photo_url,
      };
      if (editing) {
        const { error } = await supabase.from("staff").update(payload).eq("id", editing.id);
        if (error) throw error;
      } else {
        if (!form.email.trim()) throw new Error("Email is required");
        if (!form.password || form.password.length < 6) throw new Error("Password must be at least 6 characters");
        await createUser({
          data: {
            email: form.email.trim(),
            password: form.password,
            full_name: form.name.trim(),
            mobile: form.mobile.trim(),
            username: form.username.trim(),
            branch_id: form.branch_id === "none" ? null : form.branch_id,
            system_role: "staff",
            staff_record: {
              ...payload,
              name: payload.name,
              mobile: payload.mobile,
              email: payload.email,
              username: payload.username,
            },
          },
        });
      }
    },
    onSuccess: () => {
      toast.success(editing ? "Staff updated" : "Staff added");
      qc.invalidateQueries({ queryKey: ["staff"] });
      qc.invalidateQueries({ queryKey: ["admin-users"] });
      qc.invalidateQueries({ queryKey: ["admin-user-roles"] });
      setDialogOpen(false);
      setEditing(null);
      setForm(emptyForm);
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const deleteMutation = useMutation({
    mutationFn: async (id: string) => {
      const { error } = await supabase
        .from("staff")
        .update({ deleted_at: new Date().toISOString(), status: "inactive" })
        .eq("id", id);
      if (error) throw error;
    },
    onSuccess: () => {
      toast.success("Staff deleted");
      qc.invalidateQueries({ queryKey: ["staff"] });
      setDeleteId(null);
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const toggleStatusMutation = useMutation({
    mutationFn: async (s: Staff) => {
      const { error } = await supabase
        .from("staff")
        .update({ status: s.status === "active" ? "inactive" : "active" })
        .eq("id", s.id);
      if (error) throw error;
    },
    onSuccess: () => {
      toast.success("Status updated");
      qc.invalidateQueries({ queryKey: ["staff"] });
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const openAdd = () => {
    setEditing(null);
    setForm(emptyForm);
    setDialogOpen(true);
  };

  const openEdit = (s: Staff) => {
    setEditing(s);
    setForm({
      name: s.name, mobile: s.mobile, email: s.email, password: "", address: s.address,
      role: s.role, designation: s.designation, nid: s.nid,
      username: s.username ?? "",
      joining_date: s.joining_date || "",
      salary: String(s.salary), commission_rate: String(s.commission_rate),
      status: s.status, note: s.note,
      branch_id: s.branch_id ?? "none",
      department_id: s.department_id ?? "none",
      photo_url: s.photo_url ?? "",
    });
    setDialogOpen(true);
  };

  const activeCount = staff.filter((s) => s.status === "active").length;
  const inactiveCount = staff.length - activeCount;

  return (
    <PageLayout title={tr("staffMgmtTitle")} subtitle="Manage all employees, roles, branches, and departments">
      <div className="grid grid-cols-1 md:grid-cols-3 gap-4 mb-6">
        <Card className="p-4">
          <div className="text-sm text-muted-foreground">Total Staff</div>
          <div className="text-2xl font-bold mt-1">{staff.length}</div>
        </Card>
        <Card className="p-4">
          <div className="text-sm text-muted-foreground">Active</div>
          <div className="text-2xl font-bold mt-1 text-green-600">{activeCount}</div>
        </Card>
        <Card className="p-4">
          <div className="text-sm text-muted-foreground">Inactive</div>
          <div className="text-2xl font-bold mt-1 text-muted-foreground">{inactiveCount}</div>
        </Card>
      </div>

      <Card className="p-4">
        <div className="flex flex-wrap items-center gap-3 mb-4">
          <div className="relative flex-1 min-w-[200px]">
            <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
            <Input
              placeholder="Search by name, mobile, email, staff ID..."
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              className="pl-9"
            />
          </div>
          <Select value={roleFilter} onValueChange={setRoleFilter}>
            <SelectTrigger className="w-[170px]"><SelectValue placeholder="Role" /></SelectTrigger>
            <SelectContent>
              <SelectItem value="all">All Roles</SelectItem>
              {ROLES.map((r) => <SelectItem key={r.value} value={r.value}>{r.label}</SelectItem>)}
            </SelectContent>
          </Select>
          <Select value={branchFilter} onValueChange={setBranchFilter}>
            <SelectTrigger className="w-[150px]"><SelectValue placeholder="Branch" /></SelectTrigger>
            <SelectContent>
              <SelectItem value="all">All Branches</SelectItem>
              {branches.map((b) => <SelectItem key={b.id} value={b.id}>{b.name}</SelectItem>)}
            </SelectContent>
          </Select>
          <Select value={departmentFilter} onValueChange={setDepartmentFilter}>
            <SelectTrigger className="w-[150px]"><SelectValue placeholder="Department" /></SelectTrigger>
            <SelectContent>
              <SelectItem value="all">All Depts</SelectItem>
              {departments.map((d) => <SelectItem key={d.id} value={d.id}>{d.name}</SelectItem>)}
            </SelectContent>
          </Select>
          <Select value={statusFilter} onValueChange={setStatusFilter}>
            <SelectTrigger className="w-[130px]"><SelectValue placeholder="Status" /></SelectTrigger>
            <SelectContent>
              <SelectItem value="all">All Status</SelectItem>
              <SelectItem value="active">Active</SelectItem>
              <SelectItem value="inactive">Inactive</SelectItem>
            </SelectContent>
          </Select>
          {isAdmin && (
            <Button onClick={openAdd}>
              <Plus className="h-4 w-4 mr-1" /> New Staff
            </Button>
          )}
        </div>

        <div className="border rounded-lg overflow-hidden">
          <Table>
            <TableHeader>
              <TableRow>
                <TableHead>Photo</TableHead>
                <TableHead>Staff ID</TableHead>
                <TableHead>Name</TableHead>
                <TableHead>Mobile</TableHead>
                <TableHead>Role</TableHead>
                <TableHead>Branch</TableHead>
                <TableHead>Department</TableHead>
                <TableHead className="text-right">Salary</TableHead>
                <TableHead>Status</TableHead>
                <TableHead className="text-right">Actions</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {isLoading ? (
                <TableRow><TableCell colSpan={10} className="text-center py-8 text-muted-foreground">Loading...</TableCell></TableRow>
              ) : filtered.length === 0 ? (
                <TableRow><TableCell colSpan={10} className="text-center py-8 text-muted-foreground">No staff found</TableCell></TableRow>
              ) : filtered.map((s) => (
                <TableRow key={s.id}>
                  <TableCell>
                    {s.photo_url ? (
                      <img src={s.photo_url} alt={s.name} className="h-10 w-10 rounded-full object-cover" />
                    ) : (
                      <div className="h-10 w-10 rounded-full bg-muted flex items-center justify-center text-xs font-semibold">
                        {s.name.slice(0, 2).toUpperCase()}
                      </div>
                    )}
                  </TableCell>
                  <TableCell className="font-mono text-xs">{s.staff_id ?? "-"}</TableCell>
                  <TableCell className="font-medium">
                    <div>{s.name}</div>
                    {s.email && <div className="text-xs text-muted-foreground">{s.email}</div>}
                  </TableCell>
                  <TableCell>{s.mobile}</TableCell>
                  <TableCell><Badge variant="secondary">{roleLabel(s.role)}</Badge></TableCell>
                  <TableCell>{branchName(s.branch_id)}</TableCell>
                  <TableCell>{departmentName(s.department_id)}</TableCell>
                  <TableCell className="text-right">৳{Number(s.salary).toLocaleString()}</TableCell>
                  <TableCell>
                    <Badge variant={s.status === "active" ? "default" : "outline"}>
                      {s.status === "active" ? "Active" : "Inactive"}
                    </Badge>
                  </TableCell>
                  <TableCell className="text-right">
                    <div className="flex justify-end gap-1">
                      <Link to="/staff/$staffId" params={{ staffId: s.id }}>
                        <Button size="icon" variant="ghost" title="View Profile">
                          <Eye className="h-4 w-4" />
                        </Button>
                      </Link>
                      <Button size="icon" variant="ghost" onClick={() => setSalaryStaff(s)} title="Salary">
                        <Wallet className="h-4 w-4 text-primary" />
                      </Button>
                      {isAdmin && (
                        <>
                          <Button size="icon" variant="ghost" onClick={() => toggleStatusMutation.mutate(s)} title={s.status === "active" ? "Set Inactive" : "Set Active"}>
                            {s.status === "active" ? <UserX className="h-4 w-4" /> : <UserCheck className="h-4 w-4" />}
                          </Button>
                          <Button size="icon" variant="ghost" onClick={() => openEdit(s)}><Pencil className="h-4 w-4" /></Button>
                          <Button size="icon" variant="ghost" onClick={() => setDeleteId(s.id)}>
                            <Trash2 className="h-4 w-4 text-destructive" />
                          </Button>
                        </>
                      )}
                    </div>
                  </TableCell>
                </TableRow>
              ))}
            </TableBody>
          </Table>
        </div>
      </Card>

      <Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
        <DialogContent className="max-w-3xl max-h-[90vh] overflow-y-auto">
          <DialogHeader>
            <DialogTitle>{editing ? "Edit Staff" : "Add New Staff"}</DialogTitle>
          </DialogHeader>
          <div className="grid grid-cols-1 md:grid-cols-2 gap-4 py-2">
            <div className="md:col-span-2 flex items-center gap-4">
              {form.photo_url ? (
                <img src={form.photo_url} alt="" className="h-20 w-20 rounded-full object-cover border" />
              ) : (
                <div className="h-20 w-20 rounded-full bg-muted flex items-center justify-center text-sm text-muted-foreground border">
                  No photo
                </div>
              )}
              <div>
                <Label htmlFor="photo-upload" className="cursor-pointer inline-flex items-center gap-2 px-3 py-2 border rounded-md text-sm hover:bg-accent">
                  <Upload className="h-4 w-4" />
                  {photoUploading ? "Uploading..." : "Upload Photo"}
                </Label>
                <input
                  id="photo-upload"
                  type="file"
                  accept="image/*"
                  className="hidden"
                  onChange={(e) => e.target.files?.[0] && uploadPhoto(e.target.files[0])}
                />
              </div>
            </div>
            <div>
              <Label>Full Name *</Label>
              <Input value={form.name} onChange={(e) => setForm({ ...form, name: e.target.value })} />
            </div>
            <div>
              <Label>Mobile *</Label>
              <Input value={form.mobile} onChange={(e) => setForm({ ...form, mobile: e.target.value })} />
            </div>
            <div>
              <Label>Email{!editing && " *"}</Label>
              <Input type="email" value={form.email} onChange={(e) => setForm({ ...form, email: e.target.value })} />
            </div>
            {!editing && (
              <div>
                <Label>Password *</Label>
                <Input type="password" value={form.password} onChange={(e) => setForm({ ...form, password: e.target.value })} placeholder="Min 6 characters" />
              </div>
            )}
            <div>
              <Label>Username</Label>
              <Input value={form.username} onChange={(e) => setForm({ ...form, username: e.target.value })} />
            </div>
            <div>
              <Label>NID Number</Label>
              <Input value={form.nid} onChange={(e) => setForm({ ...form, nid: e.target.value })} />
            </div>
            <div>
              <Label>Role</Label>
              <Select value={form.role} onValueChange={(v) => setForm({ ...form, role: v })}>
                <SelectTrigger><SelectValue /></SelectTrigger>
                <SelectContent>
                  {ROLES.map((r) => <SelectItem key={r.value} value={r.value}>{r.label}</SelectItem>)}
                </SelectContent>
              </Select>
            </div>
            <div>
              <Label>Designation</Label>
              <Input value={form.designation} onChange={(e) => setForm({ ...form, designation: e.target.value })} />
            </div>
            <div>
              <Label>Branch</Label>
              <Select value={form.branch_id} onValueChange={(v) => setForm({ ...form, branch_id: v })}>
                <SelectTrigger><SelectValue /></SelectTrigger>
                <SelectContent>
                  <SelectItem value="none">— None —</SelectItem>
                  {branches.map((b) => <SelectItem key={b.id} value={b.id}>{b.name}</SelectItem>)}
                </SelectContent>
              </Select>
            </div>
            <div>
              <Label>Department</Label>
              <Select value={form.department_id} onValueChange={(v) => setForm({ ...form, department_id: v })}>
                <SelectTrigger><SelectValue /></SelectTrigger>
                <SelectContent>
                  <SelectItem value="none">— None —</SelectItem>
                  {departments.map((d) => <SelectItem key={d.id} value={d.id}>{d.name}</SelectItem>)}
                </SelectContent>
              </Select>
            </div>
            <div>
              <Label>Joining Date</Label>
              <Input type="date" value={form.joining_date} onChange={(e) => setForm({ ...form, joining_date: e.target.value })} />
            </div>
            <div>
              <Label>Status</Label>
              <Select value={form.status} onValueChange={(v) => setForm({ ...form, status: v })}>
                <SelectTrigger><SelectValue /></SelectTrigger>
                <SelectContent>
                  <SelectItem value="active">Active</SelectItem>
                  <SelectItem value="inactive">Inactive</SelectItem>
                </SelectContent>
              </Select>
            </div>
            <div>
              <Label>Monthly Salary (৳)</Label>
              <Input type="number" min="0" value={form.salary} onChange={(e) => setForm({ ...form, salary: e.target.value })} />
            </div>
            <div>
              <Label>Commission Rate (%)</Label>
              <Input type="number" min="0" step="0.01" value={form.commission_rate} onChange={(e) => setForm({ ...form, commission_rate: e.target.value })} />
            </div>
            <div className="md:col-span-2">
              <Label>Address</Label>
              <Textarea rows={2} value={form.address} onChange={(e) => setForm({ ...form, address: e.target.value })} />
            </div>
            <div className="md:col-span-2">
              <Label>Note</Label>
              <Textarea rows={2} value={form.note} onChange={(e) => setForm({ ...form, note: e.target.value })} />
            </div>
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setDialogOpen(false)}>Cancel</Button>
            <Button onClick={() => saveMutation.mutate()} disabled={saveMutation.isPending}>
              {saveMutation.isPending ? "Saving..." : "Save"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      <AlertDialog open={!!deleteId} onOpenChange={(o) => !o && setDeleteId(null)}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>Delete this staff?</AlertDialogTitle>
            <AlertDialogDescription>This action cannot be undone.</AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel>Cancel</AlertDialogCancel>
            <AlertDialogAction onClick={() => deleteId && deleteMutation.mutate(deleteId)}>Delete</AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>

      <StaffSalaryDialog
        staff={salaryStaff}
        open={!!salaryStaff}
        onOpenChange={(o) => !o && setSalaryStaff(null)}
      />
    </PageLayout>
  );
}
