import React, { useState, useEffect } from "react";
import { base44 } from "@/api/base44Client";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Checkbox } from "@/components/ui/checkbox";
import { X, Plus, Users, CheckCircle2, XCircle, Clock, Bell, Mail } from "lucide-react";
import {
  Command,
  CommandEmpty,
  CommandGroup,
  CommandInput,
  CommandItem,
} from "@/components/ui/command";
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import {
  Alert,
  AlertDescription,
} from "@/components/ui/alert";
import { useToast } from "@/components/ui/use-toast";

export default function StaffAssignment({ assignedStaff = [], onChange, requestedCount = 0, eventId, eventName, isRapid = false, currentUser }) {
  const [open, setOpen] = useState(false);
  const [selectedStaff, setSelectedStaff] = useState([]);
  const [filterDepartment, setFilterDepartment] = useState("all");
  const [filterHub, setFilterHub] = useState("all");
  const { toast } = useToast();
  const queryClient = useQueryClient();

  const isVendor = currentUser?.user_role === 'vendor' || currentUser?.role === 'vendor';
  const canAssignStaff = isVendor;

  const { data: allStaff, isLoading } = useQuery({
    queryKey: ['staff'],
    queryFn: () => base44.entities.Staff.list(),
    initialData: [],
  });

  const sendNotificationMutation = useMutation({
    mutationFn: async ({ staffEmail, staffName, eventName }) => {
      // In a real scenario, fullStaffDetails.email or similar would be used.
      // For this example, we're using contact_number or phone as the email placeholder.
      if (!staffEmail) {
        throw new Error("Staff member does not have an email address on file.");
      }
      return await base44.integrations.Core.SendEmail({
        to: staffEmail,
        subject: `You've been assigned to: ${eventName}`,
        body: `Hi ${staffName},\n\nYou have been assigned to the event: ${eventName}.\n\nPlease confirm your availability as soon as possible.\n\nThank you!`
      });
    },
    onSuccess: (data, variables) => {
      toast({
        title: "Notification Sent",
        description: `${variables.staffName} has been notified via email`,
      });
    },
    onError: (error, variables) => {
      toast({
        title: "Notification Failed",
        description: `Failed to send notification to ${variables.staffName}. ${error.message}`,
        variant: "destructive"
      });
    }
  });

  const uniqueDepartments = [...new Set(allStaff.map(s => s.department).filter(Boolean))];
  const uniqueHubs = [...new Set(allStaff.map(s => s.hub_location).filter(Boolean))];

  const remainingSlots = requestedCount > 0 ? requestedCount - assignedStaff.length : Infinity;
  const isFull = requestedCount > 0 && assignedStaff.length >= requestedCount;

  // Get available (unassigned) staff
  const availableStaff = allStaff.filter(staff => 
    !assignedStaff.some(assigned => assigned.staff_id === staff.id)
  );

  // Apply filters to available staff
  const filteredAvailableStaff = availableStaff.filter(staff => {
    const matchesDepartment = filterDepartment === "all" || staff.department === filterDepartment;
    const matchesHub = filterHub === "all" || staff.hub_location === filterHub;
    return matchesDepartment && matchesHub;
  });

  const handleNotifyStaff = async (staffId) => {
    const staff = assignedStaff.find(s => s.staff_id === staffId);
    const fullStaffDetails = allStaff.find(s => s.id === staffId);
    
    if (!staff || !fullStaffDetails) {
      toast({
        title: "Staff Not Found",
        description: "Could not find staff details to send notification.",
        variant: "destructive"
      });
      return;
    }

    // Using contact_number or phone as email for demonstration as per outline
    const staffEmail = fullStaffDetails.contact_number || fullStaffDetails.phone;

    if (!staffEmail) {
      toast({
        title: "No Contact Information",
        description: `${staff.staff_name} doesn't have an email address on file.`,
        variant: "destructive"
      });
      return;
    }

    try {
      await sendNotificationMutation.mutateAsync({
        staffEmail: staffEmail,
        staffName: staff.staff_name,
        eventName: eventName || "the event"
      });

      // Update notification status in the assignedStaff list
      const updatedAssignments = assignedStaff.map(s => {
        if (s.staff_id === staffId) {
          return {
            ...s,
            notified: true,
            notified_at: new Date().toISOString()
          };
        }
        return s;
      });
      onChange(updatedAssignments);

    } catch (error) {
      // Error handled by onSuccess/onError in sendNotificationMutation directly
      // No need for a separate toast here unless for a specific re-throw
    }
  };

  const handleNotifyAll = async () => {
    const unnotifiedStaff = assignedStaff.filter(s => !s.notified);
    
    if (unnotifiedStaff.length === 0) {
      toast({
        title: "All Staff Notified",
        description: "All assigned staff have already been notified.",
      });
      return;
    }

    toast({
      title: "Sending Notifications",
      description: `Notifying ${unnotifiedStaff.length} staff member${unnotifiedStaff.length !== 1 ? 's' : ''}...`,
    });

    // Send notifications to all unnotified staff
    for (const staff of unnotifiedStaff) {
      // Use await to send notifications sequentially and update status
      await handleNotifyStaff(staff.staff_id);
    }
  };

  const handleSelectAll = () => {
    if (requestedCount > 0 && assignedStaff.length >= requestedCount) {
      toast({
        title: "Assignment Limit Reached",
        description: `All ${requestedCount} positions are filled. Cannot select more.`,
        variant: "destructive"
      });
      return;
    }

    // Only select the exact number needed to fill remaining slots
    const staffToSelect = filteredAvailableStaff
      .slice(0, remainingSlots > 0 ? remainingSlots : filteredAvailableStaff.length)
      .map(s => s.id);

    setSelectedStaff(staffToSelect);

    toast({
      title: "Staff Selected",
      description: `${staffToSelect.length} staff member${staffToSelect.length !== 1 ? 's' : ''} selected to fill remaining ${remainingSlots} slot${remainingSlots !== 1 ? 's' : ''}`,
    });
  };

  const handleAddStaff = async (staff) => {
    // Strictly enforce the requested count
    if (requestedCount > 0 && assignedStaff.length >= requestedCount) {
      toast({
        title: "Assignment Limit Reached",
        description: `This order requested exactly ${requestedCount} staff. Cannot assign more.`,
        variant: "destructive"
      });
      return;
    }

    const isAlreadyAssigned = assignedStaff.some(s => s.staff_id === staff.id);
    if (isAlreadyAssigned) {
      toast({
        title: "Already Assigned",
        description: `${staff.employee_name} is already assigned to this event`,
        variant: "destructive"
      });
      return;
    }

    const newStaff = {
      staff_id: staff.id,
      staff_name: staff.employee_name,
      position: staff.position || "",
      confirmed: false,
      notified: false,
      notified_at: null,
      confirmed_at: null
    };
    
    const updatedAssignments = [...assignedStaff, newStaff];
    onChange(updatedAssignments);

    toast({
      title: "Staff Assigned",
      description: `${staff.employee_name} has been assigned to the event`,
    });
  };

  const handleBulkAssign = () => {
    if (requestedCount > 0) {
      const availableSlots = requestedCount - assignedStaff.length;
      
      if (availableSlots <= 0) {
        toast({
          title: "Assignment Limit Reached",
          description: `All ${requestedCount} positions are filled. Cannot assign more.`,
          variant: "destructive"
        });
        return;
      }

      if (selectedStaff.length > availableSlots) {
        toast({
          title: "Assignment Limit",
          description: `Only ${availableSlots} slot${availableSlots !== 1 ? 's' : ''} remaining. Assigning first ${availableSlots} selected staff.`,
          variant: "destructive"
        });
      }

      const staffToAssign = selectedStaff.slice(0, availableSlots);

      if (staffToAssign.length === 0) {
        toast({
          title: "No Slots Available",
          description: "All positions are filled. Cannot assign more staff.",
          variant: "destructive"
        });
        return;
      }

      const newAssignments = staffToAssign
        .filter(staffId => !assignedStaff.some(s => s.staff_id === staffId))
        .map(staffId => {
          const staff = allStaff.find(s => s.id === staffId);
          return {
            staff_id: staff.id,
            staff_name: staff.employee_name,
            position: staff.position || "",
            confirmed: false,
            notified: false,
            notified_at: null,
            confirmed_at: null
          };
        });
      
      const updatedAssignments = [...assignedStaff, ...newAssignments];
      onChange(updatedAssignments);
      
      toast({
        title: "Staff Assigned",
        description: `${newAssignments.length} staff member${newAssignments.length !== 1 ? 's' : ''} assigned successfully`,
      });

      setSelectedStaff([]);
      setOpen(false);
    } else {
      // No limit set, allow unlimited assignments
      if (selectedStaff.length === 0) {
        toast({
          title: "No Staff Selected",
          description: "Please select staff members to assign",
          variant: "destructive"
        });
        return;
      }

      const newAssignments = selectedStaff
        .filter(staffId => !assignedStaff.some(s => s.staff_id === staffId))
        .map(staffId => {
          const staff = allStaff.find(s => s.id === staffId);
          return {
            staff_id: staff.id,
            staff_name: staff.employee_name,
            position: staff.position || "",
            confirmed: false,
            notified: false,
            notified_at: null,
            confirmed_at: null
          };
        });
      
      const updatedAssignments = [...assignedStaff, ...newAssignments];
      onChange(updatedAssignments);
      
      toast({
        title: "Staff Assigned",
        description: `${newAssignments.length} staff member${newAssignments.length !== 1 ? 's' : ''} assigned successfully`,
      });

      setSelectedStaff([]);
      setOpen(false);
    }
  };

  const handleRemoveStaff = (staffId) => {
    const updatedAssignments = assignedStaff.filter(s => s.staff_id !== staffId);
    onChange(updatedAssignments);
    
    toast({
      title: "Staff Removed",
      description: "Staff member has been removed from the event",
    });
  };

  const handleToggleConfirmation = (staffId) => {
    const updatedAssignments = assignedStaff.map(staff => {
      if (staff.staff_id === staffId) {
        return {
          ...staff,
          confirmed: !staff.confirmed,
          confirmed_at: !staff.confirmed ? new Date().toISOString() : null
        };
      }
      return staff;
    });
    onChange(updatedAssignments);

    const staff = assignedStaff.find(s => s.staff_id === staffId);
    toast({
      title: staff.confirmed ? "Confirmation Removed" : "Staff Confirmed",
      description: staff.confirmed 
        ? `${staff.staff_name}'s confirmation has been removed`
        : `${staff.staff_name} has been confirmed for this event`,
    });
  };

  const confirmedCount = assignedStaff.filter(s => s.confirmed).length;
  const allConfirmed = assignedStaff.length > 0 && confirmedCount === assignedStaff.length;

  return (
    <Card className="border-slate-200 shadow-lg">
      <CardHeader className="bg-gradient-to-br from-slate-50 to-white border-b border-slate-100">
        <div className="flex items-center justify-between">
          <CardTitle className="text-slate-900 flex items-center gap-2">
            <Users className="w-5 h-5 text-[#0A39DF]" />
            Staff Assignment
            {isRapid && requestedCount > 0 && (
              <Badge className="bg-red-600 text-white">
                RAPID: {requestedCount} {requestedCount === 1 ? 'position' : 'positions'}
              </Badge>
            )}
            {!isRapid && requestedCount > 0 && (
              <Badge variant={isFull ? "default" : "outline"} className={isFull ? "bg-green-600" : "border-amber-500 text-amber-700"}>
                {assignedStaff.length} / {requestedCount}
                {isFull && " ✓ Full"}
              </Badge>
            )}
          </CardTitle>
          <div className="flex items-center gap-2">
            {canAssignStaff && assignedStaff.length > 0 && (
              <Button
                variant="outline"
                size="sm"
                onClick={handleNotifyAll}
                disabled={sendNotificationMutation.isPending || assignedStaff.every(s => s.notified)}
                className="border-[#0A39DF] text-[#0A39DF] hover:bg-[#0A39DF]/10"
              >
                <Bell className="w-4 h-4 mr-2" />
                Notify All
              </Button>
            )}
            {canAssignStaff && (
              <Popover open={open} onOpenChange={setOpen}>
                <PopoverTrigger asChild>
                  <Button 
                    className="bg-[#0A39DF] hover:bg-[#0A39DF]/90 text-white"
                    disabled={isFull && requestedCount > 0}
                  >
                    <Plus className="w-4 h-4 mr-2" />
                    {isFull && requestedCount > 0 
                      ? "Event Fully Staffed" 
                      : remainingSlots > 0 
                        ? `Add Staff (${remainingSlots} needed)` 
                        : "Add Staff"
                    }
                  </Button>
                </PopoverTrigger>
              <PopoverContent className="w-[500px] p-0" align="end">
                <div className="p-4 border-b border-slate-200 space-y-3">
                  <div className="flex items-center justify-between">
                    <h3 className="font-semibold">Assign Staff Members</h3>
                    <Badge variant={isFull ? "default" : "outline"} className={isFull ? "bg-green-600" : ""}>
                      {assignedStaff.length} / {requestedCount || "∞"}
                    </Badge>
                  </div>

                  {remainingSlots > 0 && !isFull && (
                    <Alert className="bg-amber-50 border-amber-200">
                      <AlertDescription className="text-amber-800 text-xs">
                        <strong>{remainingSlots}</strong> more staff member{remainingSlots !== 1 ? 's' : ''} needed to fill all positions
                      </AlertDescription>
                    </Alert>
                  )}

                  {isFull && requestedCount > 0 && (
                    <Alert className="bg-green-50 border-green-200">
                      <AlertDescription className="text-green-800 text-xs flex items-center gap-2">
                        <CheckCircle2 className="w-4 h-4" />
                        Event fully staffed - all {requestedCount} positions filled
                      </AlertDescription>
                    </Alert>
                  )}

                  <div className="flex gap-2">
                    <Select value={filterDepartment} onValueChange={setFilterDepartment}>
                      <SelectTrigger className="flex-1">
                        <SelectValue placeholder="Department" />
                      </SelectTrigger>
                      <SelectContent>
                        <SelectItem value="all">All Departments</SelectItem>
                        {uniqueDepartments.map(dept => (
                          <SelectItem key={dept} value={dept}>{dept}</SelectItem>
                        ))}
                      </SelectContent>
                    </Select>

                    <Select value={filterHub} onValueChange={setFilterHub}>
                      <SelectTrigger className="flex-1">
                        <SelectValue placeholder="Hub" />
                      </SelectTrigger>
                      <SelectContent>
                        <SelectItem value="all">All Hubs</SelectItem>
                        {uniqueHubs.map(hub => (
                          <SelectItem key={hub} value={hub}>{hub}</SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                  </div>

                  <div className="flex gap-2">
                    <Button
                      onClick={handleSelectAll}
                      variant="outline"
                      size="sm"
                      className="flex-1"
                      disabled={isFull || filteredAvailableStaff.length === 0}
                    >
                      Select {remainingSlots > 0 ? `${Math.min(remainingSlots, filteredAvailableStaff.length)}` : 'All'} Available
                    </Button>
                    <Button
                      onClick={() => setSelectedStaff([])}
                      variant="outline"
                      size="sm"
                      className="flex-1"
                      disabled={selectedStaff.length === 0}
                    >
                      Clear Selection
                    </Button>
                  </div>

                  {selectedStaff.length > 0 && !isFull && (
                    <Button
                      onClick={handleBulkAssign}
                      className="w-full bg-[#0A39DF] hover:bg-[#0A39DF]/90"
                    >
                      <Plus className="w-4 h-4 mr-2" />
                      Assign {Math.min(selectedStaff.length, remainingSlots > 0 ? remainingSlots : selectedStaff.length)} Staff
                    </Button>
                  )}
                </div>

                <Command className="max-h-80 overflow-auto">
                  <CommandInput placeholder="Search staff..." />
                  <CommandEmpty>No available staff found.</CommandEmpty>
                  <CommandGroup>
                    {filteredAvailableStaff.length === 0 ? (
                      <div className="p-4 text-center text-sm text-slate-500">
                        {availableStaff.length === 0 
                          ? "All staff members are already assigned" 
                          : "No staff match the selected filters"}
                      </div>
                    ) : (
                      filteredAvailableStaff.map((staff) => {
                        const isSelected = selectedStaff.includes(staff.id);
                        const canSelect = !isFull || isSelected;

                        return (
                          <CommandItem
                            key={staff.id}
                            onSelect={() => {
                              if (!canSelect) return;
                              
                              if (isSelected) {
                                setSelectedStaff(prev => prev.filter(id => id !== staff.id));
                              } else {
                                if (requestedCount > 0 && selectedStaff.length >= remainingSlots) {
                                  toast({
                                    title: "Selection Limit",
                                    description: `You can only select ${remainingSlots} more staff member${remainingSlots !== 1 ? 's' : ''}`,
                                    variant: "destructive"
                                  });
                                  return;
                                }
                                setSelectedStaff(prev => [...prev, staff.id]);
                              }
                            }}
                            className={`cursor-pointer ${!canSelect ? 'opacity-50 cursor-not-allowed' : ''}`}
                            disabled={!canSelect}
                          >
                            <div className="flex items-center gap-3 w-full">
                              <Checkbox
                                checked={isSelected}
                                disabled={!canSelect}
                                onCheckedChange={() => {}}
                                onClick={(e) => e.stopPropagation()}
                              />
                              <div className="w-8 h-8 bg-gradient-to-br from-[#0A39DF] to-[#1C323E] rounded-lg flex items-center justify-center text-white text-xs font-bold">
                                {staff.initial || staff.employee_name?.charAt(0)}
                              </div>
                              <div className="flex-1 min-w-0">
                                <p className="font-medium text-slate-900 truncate text-sm">
                                  {staff.employee_name}
                                </p>
                                <div className="flex items-center gap-2 text-xs text-slate-500">
                                  {staff.position && <span>{staff.position}</span>}
                                  {staff.department && (
                                    <>
                                      <span>•</span>
                                      <span>{staff.department}</span>
                                    </>
                                  )}
                                </div>
                              </div>
                            </div>
                          </CommandItem>
                        );
                      })
                    )}
                  </CommandGroup>
                </Command>
              </PopoverContent>
            </Popover>
            )}
        </div>
      </CardHeader>

      <CardContent className="p-6">
        <div className="space-y-4">
          <div className="flex items-center justify-between">
            <div className="flex items-center gap-4">
              <div className="text-sm text-slate-600">
                <span className="font-semibold text-lg text-[#1C323E]">{assignedStaff.length}</span>
                <span className="text-slate-500"> / {requestedCount || "∞"} assigned</span>
              </div>
              {assignedStaff.length > 0 && (
                <div className="text-sm text-slate-600">
                  <span className="font-semibold text-lg text-green-600">{confirmedCount}</span>
                  <span className="text-slate-500"> confirmed</span>
                </div>
              )}
            </div>
            
            {allConfirmed && assignedStaff.length > 0 && (
              <Badge className="bg-green-50 text-green-700 border-green-200">
                <CheckCircle2 className="w-3 h-3 mr-1" />
                All Confirmed
              </Badge>
            )}
          </div>

          {assignedStaff.length === 0 ? (
            <div className="text-center py-12 bg-slate-50 rounded-lg border-2 border-dashed border-slate-200">
              <Users className="w-12 h-12 mx-auto text-slate-300 mb-3" />
              <p className="text-slate-600 font-medium mb-1">No staff assigned yet</p>
              <p className="text-sm text-slate-500">Click "Add Staff" to assign team members</p>
            </div>
          ) : (
            <div className="space-y-3">
              {assignedStaff.map((staff, index) => (
                <div
                  key={staff.staff_id}
                  className="flex items-center gap-4 p-4 bg-slate-50 rounded-lg border border-slate-200 hover:bg-slate-100 transition-colors"
                >
                  <div className="w-10 h-10 bg-gradient-to-br from-[#0A39DF] to-[#1C323E] rounded-lg flex items-center justify-center text-white font-bold shadow-sm">
                    {staff.staff_name?.charAt(0) || "?"}
                  </div>
                  
                  <div className="flex-1 min-w-0">
                    <p className="font-semibold text-slate-900">{staff.staff_name}</p>
                    <div className="flex items-center gap-2">
                      {staff.position && (
                        <p className="text-sm text-slate-500">{staff.position}</p>
                      )}
                      {staff.notified && (
                        <Badge variant="outline" className="text-xs border-[#0A39DF] text-[#0A39DF]">
                          <Bell className="w-3 h-3 mr-1" />
                          Notified
                        </Badge>
                      )}
                    </div>
                  </div>

                  <div className="flex items-center gap-2">
                    {canAssignStaff && !staff.notified && (
                      <Button
                        size="sm"
                        variant="outline"
                        onClick={() => handleNotifyStaff(staff.staff_id)}
                        disabled={sendNotificationMutation.isPending}
                        className="border-[#0A39DF] text-[#0A39DF] hover:bg-[#0A39DF]/10"
                      >
                        <Bell className="w-4 h-4 mr-1" />
                        Notify
                      </Button>
                    )}
                    {canAssignStaff && (
                      <Button
                        size="sm"
                        variant={staff.confirmed ? "default" : "outline"}
                        onClick={() => handleToggleConfirmation(staff.staff_id)}
                        className={staff.confirmed ? "bg-green-600 hover:bg-green-700" : ""}
                      >
                        {staff.confirmed ? (
                          <>
                            <CheckCircle2 className="w-4 h-4 mr-1" />
                            Confirmed
                          </>
                        ) : (
                          <>
                            <Clock className="w-4 h-4 mr-1" />
                            Pending
                          </>
                        )}
                      </Button>
                    )}
                    {!canAssignStaff && staff.confirmed && (
                      <Badge className="bg-green-600 text-white">
                        <CheckCircle2 className="w-3 h-3 mr-1" />
                        Confirmed
                      </Badge>
                    )}

                    {canAssignStaff && (
                      <Button
                        size="icon"
                        variant="ghost"
                        onClick={() => handleRemoveStaff(staff.staff_id)}
                        className="text-red-600 hover:text-red-700 hover:bg-red-50"
                      >
                        <X className="w-4 h-4" />
                      </Button>
                    )}
                  </div>
                </div>
              ))}
            </div>
          )}
        </div>
      </CardContent>
    </Card>
  );
}