import React, { useState, useMemo, useEffect } from "react";
import { base44 } from "@/api/base44Client";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogFooter,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Badge } from "@/components/ui/badge";
import { Avatar, AvatarFallback } from "@/components/ui/avatar";
import { useToast } from "@/components/ui/use-toast";
import {
  Search,
  Users,
  AlertTriangle,
  Star,
  MapPin,
  Sparkles,
  Check,
  Calendar,
  Sliders,
  Clock,
  TrendingUp,
  Shield,
  DollarSign,
  Zap,
  Bell,
} from "lucide-react";
import { format } from "date-fns";
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs";
import { Slider } from "@/components/ui/slider";
import { calculateOrderStatus } from "../orders/OrderStatusUtils";
import { calculateOTStatus, getOTBadgeProps } from "../scheduling/OvertimeCalculator";

// Helper to check time overlap with buffer
function hasTimeOverlap(start1, end1, start2, end2, bufferMinutes = 30) {
  const s1 = new Date(start1).getTime();
  const e1 = new Date(end1).getTime() + bufferMinutes * 60 * 1000;
  const s2 = new Date(start2).getTime();
  const e2 = new Date(end2).getTime() + bufferMinutes * 60 * 1000;
  
  return s1 < e2 && s2 < e1;
}

export default function SmartAssignModal({ open, onClose, event, shift, role }) {
  const { toast } = useToast();
  const queryClient = useQueryClient();
  const [searchQuery, setSearchQuery] = useState("");
  const [assignments, setAssignments] = useState({}); // { roleKey: Set([staffIds]) }
  const [sortMode, setSortMode] = useState("smart");
  const [otWarning, setOtWarning] = useState(null); // OT warning dialog state
  
  // Smart assignment priorities
  const [priorities, setPriorities] = useState({
    skill: 100, // Skill is implied by position match, not a slider
    reliability: 80,
    fatigue: 60,
    compliance: 70,
    proximity: 50,
    cost: 40,
  });

  useEffect(() => {
    if (open) {
      setAssignments({});
      setSearchQuery("");
    }
  }, [open]);

  const { data: allStaff = [] } = useQuery({
    queryKey: ['staff-for-assignment'],
    queryFn: () => base44.entities.Staff.list(),
    enabled: open,
  });

  const { data: allEvents = [] } = useQuery({
    queryKey: ['events-for-conflict-check'],
    queryFn: () => base44.entities.Event.list(),
    enabled: open,
  });

  const { data: vendorRates = [] } = useQuery({
    queryKey: ['vendor-rates-assignment'],
    queryFn: () => base44.entities.VendorRate.list(),
    enabled: open,
    initialData: [],
  });

  // Get all roles that need assignment
  const allRoles = useMemo(() => {
    if (!event) return [];
    const roles = [];
    (event.shifts || []).forEach(s => {
      (s.roles || []).forEach(r => {
        const currentAssignedCount = event.assigned_staff?.filter(staff => 
          staff.role === r.role && staff.shift_name === s.shift_name
        )?.length || 0;
        const remaining = Math.max((r.count || 0) - currentAssignedCount, 0);
        if (remaining > 0) {
          roles.push({
            shift: s,
            role: r,
            currentAssigned: currentAssignedCount,
            remaining,
            key: `${s.shift_name}-${r.role}`,
            label: `${r.role}`
          });
        }
      });
    });
    return roles;
  }, [event]);

  const totalNeeded = allRoles.reduce((sum, r) => sum + r.remaining, 0);
  const totalSelected = Object.values(assignments).reduce((sum, set) => sum + set.size, 0);

  // Get all staff with their matching roles
  const staffByRole = useMemo(() => {
    if (!event || allRoles.length === 0) return {};

    const roleMap = {};
    
    allRoles.forEach(roleItem => {
      const matchingStaff = allStaff
        .filter(staff => {
          const positionMatch = staff.position === roleItem.role.role || 
                              staff.position_2 === roleItem.role.role;
          
          if (!positionMatch) return false;

          if (searchQuery) {
            const query = searchQuery.toLowerCase();
            return staff.employee_name?.toLowerCase().includes(query) ||
                   staff.hub_location?.toLowerCase().includes(query);
          }

          return true;
        })
        .map(staff => {
          const conflicts = allEvents.filter(e => {
            if (e.id === event.id || e.status === "Canceled" || e.status === "Completed") return false;
            const isAssigned = e.assigned_staff?.some(s => s.staff_id === staff.id);
            if (!isAssigned) return false;

            return (e.shifts || []).some(eventShift => {
              return (eventShift.roles || []).some(eventRole => {
                const isStaffInRole = e.assigned_staff?.some(
                  s => s.staff_id === staff.id && s.role === eventRole.role
                );
                if (!isStaffInRole) return false;

                const shiftStart = `${e.date}T${eventRole.start_time || '00:00'}`;
                const shiftEnd = `${e.date}T${eventRole.end_time || '23:59'}`;
                const currentStart = `${event.date}T${roleItem.role.start_time || '00:00'}`;
                const currentEnd = `${event.date}T${roleItem.role.end_time || '23:59'}`;
                
                return hasTimeOverlap(shiftStart, shiftEnd, currentStart, currentEnd);
              });
            });
          });

          const hasConflict = conflicts.length > 0;
          const reliability = staff.reliability_score || 85;
          
          // Calculate OT status
          const otAnalysis = calculateOTStatus(
            { ...staff, state: event.state || 'CA' },
            { 
              ...roleItem.role, 
              date: event.date,
              state: event.state || 'CA'
            },
            allEvents
          );
          
          const smartScore = reliability - (hasConflict ? 50 : 0) - (otAnalysis.status === 'RED' ? 30 : otAnalysis.status === 'AMBER' ? 10 : 0);

          return { ...staff, hasConflict, reliability, smartScore, otAnalysis };
        })
        .sort((a, b) => {
          if (a.hasConflict !== b.hasConflict) return a.hasConflict ? 1 : -1;
          return b.smartScore - a.smartScore;
        });

      roleMap[roleItem.key] = matchingStaff;
    });

    return roleMap;
  }, [allStaff, allEvents, allRoles, event, searchQuery]);

  const handleAutoAssignAll = () => {
    const newAssignments = {};
    
    allRoles.forEach(roleItem => {
      const available = (staffByRole[roleItem.key] || []).filter(s => !s.hasConflict);
      const best = available.slice(0, roleItem.remaining);
      newAssignments[roleItem.key] = new Set(best.map(s => s.id));
    });
    
    setAssignments(newAssignments);
  };

  const toggleStaffForRole = (roleKey, staffId, maxCount, staffMember) => {
    // Check for OT warning
    if (staffMember?.otAnalysis?.requiresApproval && !assignments[roleKey]?.has(staffId)) {
      setOtWarning({
        staff: staffMember,
        roleKey,
        maxCount,
      });
      return;
    }
    
    setAssignments(prev => {
      const current = prev[roleKey] || new Set();
      const newSet = new Set(current);
      
      if (newSet.has(staffId)) {
        newSet.delete(staffId);
      } else {
        if (newSet.size >= maxCount) {
          toast({
            title: "Limit Reached",
            description: `Only ${maxCount} staff needed for this role`,
            variant: "destructive",
          });
          return prev;
        }
        newSet.add(staffId);
      }
      
      return { ...prev, [roleKey]: newSet };
    });
  };
  
  const confirmOTAssignment = () => {
    if (!otWarning) return;
    
    const { roleKey, staff, maxCount } = otWarning;
    setAssignments(prev => {
      const current = prev[roleKey] || new Set();
      const newSet = new Set(current);
      
      if (newSet.size < maxCount) {
        newSet.add(staff.id);
      }
      
      return { ...prev, [roleKey]: newSet };
    });
    
    setOtWarning(null);
  };

  const assignMutation = useMutation({
    mutationFn: async () => {
      const allNewStaff = [];
      
      // Collect all assignments
      allRoles.forEach(roleItem => {
        const selectedIds = assignments[roleItem.key] || new Set();
        const staff = (staffByRole[roleItem.key] || []).filter(s => selectedIds.has(s.id));
        
        staff.forEach(s => {
          allNewStaff.push({
            staff_id: s.id,
            staff_name: s.employee_name,
            email: s.email,
            role: roleItem.role.role,
            department: roleItem.role.department,
            shift_name: roleItem.shift.shift_name,
          });
        });
      });

      const updatedAssignedStaff = [...(event.assigned_staff || []), ...allNewStaff];

      const updatedShifts = (event.shifts || []).map(shift => {
        const updatedRoles = (shift.roles || []).map(role => {
          const roleKey = `${shift.shift_name}-${role.role}`;
          const selectedCount = (assignments[roleKey] || new Set()).size;
          
          if (selectedCount > 0) {
            return {
              ...role,
              assigned: (role.assigned || 0) + selectedCount,
            };
          }
          return role;
        });
        return { ...shift, roles: updatedRoles };
      });

      const updatedEvent = {
        assigned_staff: updatedAssignedStaff,
        shifts: updatedShifts,
      };
      
      updatedEvent.status = calculateOrderStatus({
        ...event,
        ...updatedEvent
      });
      
      await base44.entities.Event.update(event.id, updatedEvent);
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['events'] });
      toast({
        title: "✅ Staff Assigned",
        description: `Successfully assigned ${totalSelected} staff members`,
      });
      onClose();
    },
    onError: (error) => {
      toast({
        title: "❌ Assignment Failed",
        description: error.message,
        variant: "destructive",
      });
    },
  });

  const handleAssign = () => {
    if (totalSelected === 0) {
      toast({
        title: "No Selection",
        description: "Please select staff members to assign",
        variant: "destructive",
      });
      return;
    }
    assignMutation.mutate();
  };

  if (!event || allRoles.length === 0) {
    return (
      <Dialog open={open} onOpenChange={onClose}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>No Roles to Assign</DialogTitle>
          </DialogHeader>
          <p className="text-slate-600">All positions are fully staffed.</p>
          <DialogFooter>
            <Button onClick={onClose}>Close</Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    );
  }

  return (
    <Dialog open={open} onOpenChange={onClose}>
      <DialogContent className="max-w-7xl max-h-[90vh] overflow-hidden flex flex-col">
        <DialogHeader className="border-b pb-4">
          <div className="flex items-center justify-between">
            <div>
              <DialogTitle className="text-2xl font-bold text-slate-900 flex items-center gap-2">
                <Users className="w-6 h-6 text-[#0A39DF]" />
                Assign Staff
              </DialogTitle>
              <div className="flex items-center gap-3 mt-2 text-sm text-slate-600">
                <span>{event.event_name}</span>
                <span>•</span>
                <span>{event.date ? format(new Date(event.date), 'MMM d, yyyy') : 'Date TBD'}</span>
                <span>•</span>
                <span className="font-semibold text-[#0A39DF]">{totalNeeded} positions to fill</span>
              </div>
            </div>
            <div className="flex items-center gap-3">
              <Button
                onClick={handleAutoAssignAll}
                className="bg-gradient-to-r from-[#0A39DF] to-blue-600 hover:from-blue-700 hover:to-blue-800 text-white font-semibold"
              >
                <Sparkles className="w-4 h-4 mr-2" />
                Auto-Assign All
              </Button>
              <Badge className="bg-blue-100 text-blue-700 border-2 border-blue-300 text-lg px-4 py-2 font-bold">
                {totalSelected} / {totalNeeded}
              </Badge>
            </div>
          </div>
        </DialogHeader>

        <div className="flex-1 overflow-hidden flex flex-col">
          <div className="mb-4">
            <div className="relative">
              <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-slate-400" />
              <Input
                placeholder="Search staff by name or location..."
                value={searchQuery}
                onChange={(e) => setSearchQuery(e.target.value)}
                className="pl-10 border-2"
              />
            </div>
          </div>

          <div className="flex-1 overflow-y-auto space-y-4">
            {allRoles.map((roleItem) => {
              const staff = staffByRole[roleItem.key] || [];
              const selectedSet = assignments[roleItem.key] || new Set();
              const available = staff.filter(s => !s.hasConflict);
              
              return (
                <div key={roleItem.key} className="border-2 border-slate-200 rounded-lg overflow-hidden">
                  <div className="bg-gradient-to-r from-slate-50 to-slate-100 px-4 py-3 border-b-2 border-slate-200">
                    <div className="flex items-center justify-between">
                      <div>
                        <h3 className="font-bold text-lg text-slate-900">{roleItem.label}</h3>
                        <p className="text-sm text-slate-600">{available.length} available staff</p>
                      </div>
                      <Badge className={`${
                        selectedSet.size >= roleItem.remaining
                          ? 'bg-green-100 text-green-700 border-green-300'
                          : selectedSet.size > 0
                          ? 'bg-blue-100 text-blue-700 border-blue-300'
                          : 'bg-slate-100 text-slate-600 border-slate-300'
                      } border-2 px-4 py-2 text-lg font-bold`}>
                        {selectedSet.size} / {roleItem.remaining}
                      </Badge>
                    </div>
                  </div>
                  
                  <div className="max-h-60 overflow-y-auto">
                    {staff.length === 0 ? (
                      <div className="text-center py-8 text-slate-500">
                        <Users className="w-8 h-8 mx-auto mb-2 opacity-50" />
                        <p className="text-sm">No {roleItem.role.role}s found</p>
                      </div>
                    ) : (
                      <div className="divide-y divide-slate-100">
                        {staff.map((person) => {
                          const isSelected = selectedSet.has(person.id);
                          
                          return (
                            <div
                              key={person.id}
                              className={`p-3 flex items-center gap-3 cursor-pointer transition-all ${
                                isSelected ? 'bg-blue-50 border-l-4 border-[#0A39DF]' : 'hover:bg-slate-50'
                              }`}
                              onClick={() => toggleStaffForRole(roleItem.key, person.id, roleItem.remaining, person)}
                            >
                              <input
                                type="checkbox"
                                checked={isSelected}
                                onChange={() => toggleStaffForRole(roleItem.key, person.id, roleItem.remaining, person)}
                                className="w-4 h-4 rounded border-2 text-[#0A39DF]"
                                onClick={(e) => e.stopPropagation()}
                              />
                              
                              <Avatar className="w-10 h-10">
                                <img 
                                  src={person.profile_picture || `https://ui-avatars.com/api/?name=${encodeURIComponent(person.employee_name)}&background=0A39DF&color=fff&size=128`} 
                                  alt={person.employee_name}
                                  className="w-full h-full object-cover rounded-full"
                                />
                              </Avatar>
                              
                              <div className="flex-1 min-w-0">
                                <p className="font-semibold text-slate-900 text-sm">{person.employee_name}</p>
                                <div className="flex items-center gap-2 text-xs text-slate-600">
                                  {person.hub_location && (
                                    <span className="flex items-center gap-1">
                                      <MapPin className="w-3 h-3" />
                                      {person.hub_location}
                                    </span>
                                  )}
                                  <span className="flex items-center gap-1">
                                    <Star className="w-3 h-3 text-amber-500" />
                                    {person.reliability}%
                                  </span>
                                  {person.otAnalysis && (
                                    <span className="text-xs text-slate-500">
                                      {person.otAnalysis.projectedWeekHours.toFixed(0)}h week
                                    </span>
                                  )}
                                </div>
                              </div>
                              
                              <div className="flex flex-col gap-1 items-end">
                                {person.hasConflict ? (
                                  <Badge className="bg-orange-100 text-orange-700 border border-orange-300 text-xs">
                                    <AlertTriangle className="w-3 h-3 mr-1" />
                                    Conflict
                                  </Badge>
                                ) : person.otAnalysis?.status === 'RED' ? (
                                  <Badge className="bg-red-100 text-red-700 border border-red-300 text-xs">
                                    <Clock className="w-3 h-3 mr-1" />
                                    OT Risk
                                  </Badge>
                                ) : person.otAnalysis?.status === 'AMBER' ? (
                                  <Badge className="bg-amber-100 text-amber-700 border border-amber-300 text-xs">
                                    Near OT
                                  </Badge>
                                ) : (
                                  <Badge className="bg-green-100 text-green-700 border border-green-300 text-xs">
                                    Available
                                  </Badge>
                                )}
                                {person.otAnalysis?.summary && (
                                  <span className="text-[10px] text-slate-500 text-right max-w-[120px] line-clamp-1">
                                    {person.otAnalysis.summary}
                                  </span>
                                )}
                              </div>
                            </div>
                          );
                        })}
                      </div>
                    )}
                  </div>
                </div>
              );
            })}
          </div>
        </div>

        <DialogFooter className="border-t pt-4 flex items-center justify-between">
          <div className="text-sm text-slate-600">
            {totalSelected > 0 && (
              <span className="font-semibold text-[#0A39DF]">
                {totalSelected} of {totalNeeded} positions filled
              </span>
            )}
          </div>
          <div className="flex gap-2">
            <Button variant="outline" onClick={onClose} className="border-2">
              Cancel
            </Button>
            <Button
              onClick={handleAssign}
              disabled={totalSelected === 0 || assignMutation.isPending}
              className="bg-[#0A39DF] hover:bg-blue-700 font-semibold px-8"
            >
              {assignMutation.isPending ? (
                "Assigning..."
              ) : (
                <>
                  <Check className="w-5 h-5 mr-2" />
                  Assign All ({totalSelected})
                </>
              )}
            </Button>
          </div>
        </DialogFooter>
      </DialogContent>
      
      {/* OT Warning Dialog */}
      {otWarning && (
        <Dialog open={!!otWarning} onOpenChange={() => setOtWarning(null)}>
          <DialogContent className="max-w-md">
            <DialogHeader>
              <DialogTitle className="flex items-center gap-2 text-red-700">
                <AlertTriangle className="w-5 h-5" />
                Overtime Alert
              </DialogTitle>
            </DialogHeader>
            
            <div className="space-y-4">
              <div className="bg-red-50 border border-red-200 rounded-lg p-4">
                <p className="text-sm font-semibold text-red-900 mb-2">
                  Assigning {otWarning.staff?.employee_name} will trigger overtime:
                </p>
                <div className="text-xs text-red-800 space-y-1">
                  <p>• Current week: {otWarning.staff?.otAnalysis?.currentWeekHours?.toFixed(1)}h → {otWarning.staff?.otAnalysis?.projectedWeekHours?.toFixed(1)}h</p>
                  <p>• Current day: {otWarning.staff?.otAnalysis?.currentDayHours?.toFixed(1)}h → {otWarning.staff?.otAnalysis?.projectedDayHours?.toFixed(1)}h</p>
                  <p className="font-semibold mt-2">⚠️ {otWarning.staff?.otAnalysis?.summary}</p>
                </div>
              </div>
              
              <div className="bg-slate-50 border border-slate-200 rounded-lg p-4">
                <p className="text-sm font-semibold text-slate-900 mb-2">Cost Impact:</p>
                <div className="text-xs text-slate-700 space-y-1">
                  <div className="flex justify-between">
                    <span>Base cost:</span>
                    <span className="font-mono">${otWarning.staff?.otAnalysis?.baseCost?.toFixed(2)}</span>
                  </div>
                  <div className="flex justify-between text-red-700 font-semibold">
                    <span>OT premium:</span>
                    <span className="font-mono">+${otWarning.staff?.otAnalysis?.costImpact?.toFixed(2)}</span>
                  </div>
                  <div className="flex justify-between border-t pt-1 font-bold">
                    <span>Total:</span>
                    <span className="font-mono">${otWarning.staff?.otAnalysis?.totalCost?.toFixed(2)}</span>
                  </div>
                </div>
              </div>
              
              <p className="text-xs text-slate-600">
                This assignment requires manager approval. Overtime will be documented for compliance audits.
              </p>
            </div>
            
            <DialogFooter className="gap-2">
              <Button variant="outline" onClick={() => setOtWarning(null)}>
                Cancel
              </Button>
              <Button 
                onClick={confirmOTAssignment}
                className="bg-red-600 hover:bg-red-700"
              >
                Approve OT & Assign
              </Button>
            </DialogFooter>
          </DialogContent>
        </Dialog>
      )}
    </Dialog>
  );
}