import { useQueryClient } from "@tanstack/react-query";
import { 
  addDays, 
  addWeeks, 
  addMonths, 
  format, 
  isSameDay, 
  isToday, 
  isValid, 
  parseISO, 
  startOfWeek, 
  startOfMonth, 
  endOfMonth, 
  endOfWeek, 
  eachDayOfInterval, 
  subWeeks, 
  subMonths, 
  subDays
} from "date-fns";
import { 
  Calendar as CalendarIcon, 
  ChevronLeft, 
  ChevronRight, 
  Clock, 
  DollarSign, 
  Plus,
  CalendarDays,
  Users,
  AlertTriangle
} from "lucide-react";
import { useState, useMemo } from "react";
import { useNavigate } from "react-router-dom";
import { Badge } from "@/common/components/ui/badge";
import { Button } from "@/common/components/ui/button";
import { Card, CardContent } from "@/common/components/ui/card";
import { 
  Dialog, 
  DialogContent, 
  DialogHeader, 
  DialogTitle, 
  DialogFooter,
  DialogDescription
} from "@/common/components/ui/dialog";
import { Alert, AlertDescription, AlertTitle } from "@/common/components/ui/alert";
import { Tabs, TabsList, TabsTrigger } from "@/common/components/ui/tabs";
import DashboardLayout from "@/features/layouts/DashboardLayout";
import { useListOrders, useUpdateOrder } from "@/dataconnect-generated/react";
import { dataConnect } from "@/features/auth/firebase";
import { OrderStatus } from "@/dataconnect-generated";
import { useToast } from "@/common/components/ui/use-toast";

/**
 * Maps OrderStatus to appropriate Tailwind color classes
 */
const getStatusColor = (status: OrderStatus | undefined) => {
  switch (status) {
    case OrderStatus.DRAFT:
    case OrderStatus.CANCELLED:
      return "bg-slate-100 text-slate-600 border-slate-200";
    case OrderStatus.FILLED:
    case OrderStatus.FULLY_STAFFED:
    case OrderStatus.COMPLETED:
      return "bg-emerald-50 text-emerald-700 border-emerald-200";
    case OrderStatus.POSTED:
    case OrderStatus.PENDING:
    case OrderStatus.PARTIAL_STAFFED:
      return "bg-blue-50 text-blue-700 border-blue-200";
    default:
      return "bg-slate-50 text-slate-600 border-slate-200";
  }
};

/**
 * Safely parses various date formats into a Date object
 */
const safeParseDate = (dateString: any) => {
  if (!dateString) return null;
  try {
    const date = typeof dateString === 'string' ? parseISO(dateString) : new Date(dateString);
    return isValid(date) ? date : null;
  } catch {
    return null;
  }
};

export default function Schedule() {
  const navigate = useNavigate();
  const { toast } = useToast();
  const queryClient = useQueryClient();
  const [currentDate, setCurrentDate] = useState(new Date());
  const [viewMode, setViewMode] = useState<'day' | 'week' | 'month'>('week');
  const [selectedOrder, setSelectedOrder] = useState<any>(null);
  const [isModalOpen, setIsModalOpen] = useState(false);
  
  // State for rescheduling confirmation
  const [rescheduleData, setRescheduleData] = useState<{ order: any; newDate: Date } | null>(null);
  const [isConfirmOpen, setIsConfirmOpen] = useState(false);

  // Fetch real data from Data Connect
  const { data, isLoading } = useListOrders(dataConnect);
  const orders = data?.orders || [];

  // Mutation for drag-and-drop rescheduling
  const updateOrderMutation = useUpdateOrder(dataConnect, {
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["listOrders"] });
      toast({
        title: "Order Rescheduled",
        description: "The order date has been updated successfully.",
      });
      setIsConfirmOpen(false);
      setRescheduleData(null);
    },
    onError: () => {
      toast({
        title: "Update Failed",
        description: "Could not reschedule the order. Please try again.",
        variant: "destructive",
      });
    }
  });

  // Calculate days to display based on current view mode
  const calendarDays = useMemo(() => {
    if (viewMode === 'month') {
      const start = startOfWeek(startOfMonth(currentDate));
      const end = endOfWeek(endOfMonth(currentDate));
      return eachDayOfInterval({ start, end });
    } else if (viewMode === 'week') {
      const start = startOfWeek(currentDate);
      const end = endOfWeek(currentDate);
      return eachDayOfInterval({ start, end });
    } else {
      return [currentDate];
    }
  }, [currentDate, viewMode]);

  const getOrdersForDay = (date: Date) => {
    return orders.filter((order) => {
      const orderDate = safeParseDate(order.date);
      return orderDate && isSameDay(orderDate, date);
    });
  };

  // Calculate metrics for the current visible range
  const metrics = useMemo(() => {
    const visibleOrders = orders.filter(order => {
      const orderDate = safeParseDate(order.date);
      if (!orderDate) return false;
      return orderDate >= calendarDays[0] && orderDate <= calendarDays[calendarDays.length - 1];
    });

    const totalHours = visibleOrders.reduce((sum, order) => {
      const shifts = Array.isArray(order.shifts) ? order.shifts : [];
      const orderHours = shifts.reduce((shiftSum: number, shift: any) => {
        const roles = Array.isArray(shift.roles) ? shift.roles : [];
        return shiftSum + roles.reduce((roleSum: number, role: any) => roleSum + (Number(role.hours) || 0), 0);
      }, 0);
      return sum + orderHours;
    }, 0);

    const totalCost = visibleOrders.reduce((sum, order) => sum + (order.total || 0), 0);
    const totalShifts = visibleOrders.reduce((sum, order) => sum + (Array.isArray(order.shifts) ? order.shifts.length : 0), 0);

    return { totalHours, totalCost, totalShifts };
  }, [orders, calendarDays]);

  // Navigation handlers
  const handlePrev = () => {
    if (viewMode === 'month') setCurrentDate(subMonths(currentDate, 1));
    else if (viewMode === 'week') setCurrentDate(subWeeks(currentDate, 1));
    else setCurrentDate(subDays(currentDate, 1));
  };

  const handleNext = () => {
    if (viewMode === 'month') setCurrentDate(addMonths(currentDate, 1));
    else if (viewMode === 'week') setCurrentDate(addWeeks(currentDate, 1));
    else setCurrentDate(addDays(currentDate, 1));
  };

  const handleToday = () => setCurrentDate(new Date());

  const handleEventClick = (order: any, e: React.MouseEvent) => {
    e.stopPropagation();
    setSelectedOrder(order);
    setIsModalOpen(true);
  };

  // Drag and Drop Logic
  const onDragStart = (e: React.DragEvent, order: any) => {
    e.dataTransfer.setData("orderId", order.id);
  };

  const onDrop = async (e: React.DragEvent, date: Date) => {
    e.preventDefault();
    const orderId = e.dataTransfer.getData("orderId");
    const order = orders.find(o => o.id === orderId);
    
    if (order && !isSameDay(safeParseDate(order.date)!, date)) {
      setRescheduleData({ order, newDate: date });
      setIsConfirmOpen(true);
    }
  };

  const confirmReschedule = () => {
    if (rescheduleData) {
      updateOrderMutation.mutate({
        id: rescheduleData.order.id,
        date: rescheduleData.newDate.toISOString()
      });
    }
  };

  if (isLoading) {
    return (
      <DashboardLayout title="Schedule" subtitle="Loading shifts...">
        <div className="flex items-center justify-center h-64">
          <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary"></div>
        </div>
      </DashboardLayout>
    );
  }

  return (
    <DashboardLayout
      title="Schedule"
      subtitle="Plan and manage staff shifts"
      actions={
        <Button onClick={() => navigate('/orders/new')}>
          <Plus className="w-4 h-4 mr-2" />
          New Order
        </Button>
      }
    >
      <div className="space-y-6">
        {/* Metrics Section */}
        <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
          <Card className="bg-white border-border/50 shadow-sm">
            <CardContent className="p-6 flex items-center justify-between">
              <div>
                <p className="text-secondary-text text-xs font-bold uppercase tracking-wider mb-1">Total Hours</p>
                <p className="text-2xl font-bold text-primary-text">{metrics.totalHours.toFixed(1)}</p>
              </div>
              <div className="p-3 bg-blue-50 rounded-xl text-blue-600">
                <Clock className="w-5 h-5" />
              </div>
            </CardContent>
          </Card>
          <Card className="bg-white border-border/50 shadow-sm">
            <CardContent className="p-6 flex items-center justify-between">
              <div>
                <p className="text-secondary-text text-xs font-bold uppercase tracking-wider mb-1">Labor Cost</p>
                <p className="text-2xl font-bold text-primary-text">${metrics.totalCost.toLocaleString()}</p>
              </div>
              <div className="p-3 bg-emerald-50 rounded-xl text-emerald-600">
                <DollarSign className="w-5 h-5" />
              </div>
            </CardContent>
          </Card>
          <Card className="bg-white border-border/50 shadow-sm">
            <CardContent className="p-6 flex items-center justify-between">
              <div>
                <p className="text-secondary-text text-xs font-bold uppercase tracking-wider mb-1">Total Shifts</p>
                <p className="text-2xl font-bold text-primary-text">{metrics.totalShifts}</p>
              </div>
              <div className="p-3 bg-teal-50 rounded-xl text-teal-600">
                <CalendarIcon className="w-5 h-5" />
              </div>
            </CardContent>
          </Card>
        </div>

        {/* Calendar Controls */}
        <div className="flex flex-col md:flex-row md:items-center justify-between gap-4 bg-white p-4 rounded-xl border border-border/50 shadow-sm">
          <div className="flex items-center gap-2">
            <Button variant="outline" size="icon" onClick={handlePrev} className="h-9 w-9">
              <ChevronLeft className="w-4 h-4" />
            </Button>
            <Button variant="outline" onClick={handleToday} className="h-9 px-4 text-xs font-bold uppercase tracking-wider">
              Today
            </Button>
            <Button variant="outline" size="icon" onClick={handleNext} className="h-9 w-9">
              <ChevronRight className="w-4 h-4" />
            </Button>
            <h2 className="ml-4 text-lg font-bold text-primary-text">
              {format(currentDate, viewMode === 'month' ? 'MMMM yyyy' : 'MMMM d, yyyy')}
            </h2>
          </div>

          <Tabs value={viewMode} onValueChange={(v) => setViewMode(v as any)} className="w-full md:w-auto">
            <TabsList className="grid grid-cols-3 w-full md:w-[240px]">
              <TabsTrigger value="day" className="text-xs font-bold uppercase tracking-wider">Day</TabsTrigger>
              <TabsTrigger value="week" className="text-xs font-bold uppercase tracking-wider">Week</TabsTrigger>
              <TabsTrigger value="month" className="text-xs font-bold uppercase tracking-wider">Month</TabsTrigger>
            </TabsList>
          </Tabs>
        </div>

        {/* Calendar Grid */}
        <div className={`grid gap-4 ${
          viewMode === 'month' ? 'grid-cols-7' : 
          viewMode === 'week' ? 'grid-cols-1 md:grid-cols-7' : 
          'grid-cols-1'
        }`}>
          {/* Day Names */}
          {(viewMode === 'month' || (viewMode === 'week' && window.innerWidth > 768)) && 
            ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'].map(day => (
              <div key={day} className="text-center py-2 text-[10px] font-bold uppercase tracking-widest text-secondary-text">
                {day}
              </div>
            ))
          }

          {calendarDays.map((day) => {
            const dayOrders = getOrdersForDay(day);
            const isTodayDay = isToday(day);
            const isDifferentMonth = viewMode === 'month' && day.getMonth() !== currentDate.getMonth();

            return (
              <div
                key={day.toISOString()}
                onDragOver={(e) => e.preventDefault()}
                onDrop={(e) => onDrop(e, day)}
                className={`min-h-[140px] flex flex-col p-2 rounded-xl border transition-all ${
                  isTodayDay ? 'bg-primary/5 border-primary ring-1 ring-primary/20' : 
                  isDifferentMonth ? 'bg-slate-50/50 border-border/30 opacity-60' :
                  'bg-white border-border/50 hover:border-border hover:shadow-sm'
                } ${viewMode === 'day' ? 'min-h-[500px]' : ''}`}
              >
                <div className="flex items-center justify-between mb-2 px-1">
                  <span className={`text-sm font-bold ${isTodayDay ? 'text-primary' : 'text-primary-text'}`}>
                    {format(day, viewMode === 'day' ? 'EEEE, MMMM d' : 'd')}
                  </span>
                  {dayOrders.length > 0 && (
                    <span className="text-[10px] font-bold text-secondary-text bg-slate-100 px-1.5 py-0.5 rounded">
                      {dayOrders.length}
                    </span>
                  )}
                </div>

                <div className="flex-1 space-y-1 overflow-y-auto max-h-[300px] scrollbar-hide">
                  {dayOrders.map((order: any) => (
                    <div
                      key={order.id}
                      draggable
                      onDragStart={(e) => onDragStart(e, order)}
                      onClick={(e) => handleEventClick(order, e)}
                      className={`p-2 rounded-lg border text-left cursor-pointer transition-all hover:scale-[1.02] active:scale-95 shadow-sm ${getStatusColor(order.status)}`}
                    >
                      <p className="text-[11px] font-bold truncate leading-tight mb-1">
                        {order.eventName || "Unnamed Order"}
                      </p>
                      <div className="flex items-center gap-1 opacity-80">
                        <Clock className="w-3 h-3" />
                        <span className="text-[9px] font-medium">
                          {order.shifts?.[0]?.roles?.[0]?.start_time || "00:00"}
                        </span>
                      </div>
                    </div>
                  ))}
                  
                  {dayOrders.length === 0 && viewMode !== 'month' && (
                    <div className="flex-1 flex items-center justify-center opacity-30 border border-dashed rounded-lg py-8">
                       <p className="text-[10px] font-bold uppercase tracking-wider">No Orders</p>
                    </div>
                  )}
                </div>
              </div>
            );
          })}
        </div>
      </div>

      {/* Order Detail Modal */}
      <Dialog open={isModalOpen} onOpenChange={setIsModalOpen}>
        <DialogContent className="sm:max-w-[500px]">
          <DialogHeader>
            <div className="flex items-center justify-between pr-8">
              <DialogTitle className="text-xl font-bold">{selectedOrder?.eventName || "Order Details"}</DialogTitle>
              <Badge className={getStatusColor(selectedOrder?.status)}>
                {selectedOrder?.status}
              </Badge>
            </div>
          </DialogHeader>
          
          {selectedOrder && (
            <div className="space-y-6 py-4">
              <div className="grid grid-cols-2 gap-4">
                <div className="space-y-1">
                  <p className="text-[10px] font-bold text-secondary-text uppercase tracking-wider">Date</p>
                  <div className="flex items-center gap-2">
                    <CalendarDays className="w-4 h-4 text-primary" />
                    <span className="text-sm font-medium">{format(safeParseDate(selectedOrder.date)!, 'PPPP')}</span>
                  </div>
                </div>
                <div className="space-y-1">
                  <p className="text-[10px] font-bold text-secondary-text uppercase tracking-wider">Total Value</p>
                  <div className="flex items-center gap-2">
                    <DollarSign className="w-4 h-4 text-emerald-600" />
                    <span className="text-sm font-bold text-emerald-700">${selectedOrder.total?.toLocaleString() || '0.00'}</span>
                  </div>
                </div>
              </div>

              <div className="space-y-1">
                <p className="text-[10px] font-bold text-secondary-text uppercase tracking-wider">Business</p>
                <div className="flex items-center gap-2 bg-slate-50 p-2 rounded-lg border border-slate-100">
                  <Users className="w-4 h-4 text-blue-600" />
                  <span className="text-sm font-medium">{selectedOrder.business?.businessName || "Krow Workforce"}</span>
                </div>
              </div>

              <div className="space-y-3">
                <p className="text-[10px] font-bold text-secondary-text uppercase tracking-wider">Shifts & Staffing</p>
                <div className="space-y-2">
                  {Array.isArray(selectedOrder.shifts) && selectedOrder.shifts.map((shift: any, i: number) => (
                    <div key={i} className="p-3 rounded-lg border border-border/60 bg-white shadow-sm flex items-center justify-between">
                      <div className="flex items-center gap-3">
                        <div className="w-8 h-8 rounded-full bg-slate-100 flex items-center justify-center text-xs font-bold">
                          {i + 1}
                        </div>
                        <div>
                          <p className="text-xs font-bold text-primary-text">{shift.shiftName || `Shift ${i+1}`}</p>
                          <p className="text-[10px] text-secondary-text font-medium">
                            {shift.roles?.[0]?.start_time} - {shift.roles?.[0]?.end_time}
                          </p>
                        </div>
                      </div>
                      <Badge variant="outline" className="text-[9px] font-bold uppercase tracking-wider">
                        {Array.isArray(shift.assignedStaff) ? shift.assignedStaff.length : 0} Assigned
                      </Badge>
                    </div>
                  ))}
                </div>
              </div>
            </div>
          )}

          <DialogFooter className="gap-2 sm:gap-0">
            <Button variant="outline" onClick={() => navigate(`/orders/${selectedOrder?.id}`)} className="w-full sm:w-auto">
              View Full Details
            </Button>
            <Button onClick={() => navigate(`/orders/${selectedOrder?.id}/edit`)} className="w-full sm:w-auto">
              Edit Order
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Reschedule Confirmation Dialog */}
      <Dialog open={isConfirmOpen} onOpenChange={setIsConfirmOpen}>
        <DialogContent className="sm:max-w-[425px]">
          <DialogHeader>
            <DialogTitle>Confirm Reschedule</DialogTitle>
            <DialogDescription>
              Are you sure you want to move this order to a different date?
            </DialogDescription>
          </DialogHeader>

          {rescheduleData && (
            <div className="py-4">
              <Alert variant="default" className="bg-amber-50 border-amber-200">
                <AlertTriangle className="h-4 w-4 text-amber-600" />
                <AlertTitle className="text-amber-800">Confirm Date Change</AlertTitle>
                <AlertDescription className="text-amber-700">
                  Moving <strong>{rescheduleData.order.eventName}</strong> to <strong>{format(rescheduleData.newDate, 'PPPP')}</strong>.
                </AlertDescription>
              </Alert>
            </div>
          )}

          <DialogFooter>
            <Button variant="outline" onClick={() => setIsConfirmOpen(false)}>
              Cancel
            </Button>
            <Button 
              onClick={confirmReschedule}
              disabled={updateOrderMutation.isPending}
            >
              {updateOrderMutation.isPending ? "Updating..." : "Confirm Move"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </DashboardLayout>
  );
}
