"use client";

import React, { useState, useRef, useEffect, useMemo } from "react";
import {
  Box,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  Typography,
  styled,
} from "@mui/material";
import { format, parseISO, startOfMonth, endOfMonth, addDays } from "date-fns";
import { fr } from "date-fns/locale";
import FontAwesome from "@/shared/components/fontawesome";
import {
  faCar,
  faIdCardAlt,
  faIdCard,
  faGripVertical,
} from "@fortawesome/free-solid-svg-icons";
import {
  DndContext,
  closestCenter,
  DragEndEvent,
  DragStartEvent,
  useSensors,
  useSensor,
  MouseSensor,
  TouchSensor,
} from "@dnd-kit/core";
import { DragOverlay } from "@dnd-kit/core";
import { TimeSlotBlock } from "./components/draggable-time-slot";
import { DroppableCell } from "./components/droppable-cell";
import { DraggableTimeSlot } from "./components/draggable-time-slot";
import { DriverDetailsPopover } from "./components/vehicule-details-popover";

import { Location_TABLE_COLUMNS, vehicleToDriverData } from "@/shared/_mock/_driveShedule";
import { Driver, ScheduleData, TimeSlot } from "./types";
import { TableConfig, useTableManager } from "@/hooks/use-table-manager";
import CustomDrawer from "@/shared/components/drawer/custom-drawer";
import { ScheduleToolbar } from "@/shared/components/schedule/schedule-toolbar";
import { TableType, TimeUnit } from "@/shared/types/common";
import { Dayjs } from "dayjs";
import VehicleRentalForm from "./components/location-rental-form";
import { IRental } from "@/shared/types/rental";
import { TrajetDetailsPopover } from "./components/trajet-details.popover";
import { VehicleScheduleToolbar } from './components/location-schedule-toolbar';
import { StatusColor } from "./utils/schedule-utils";

// Styled components
const StyledTableContainer = styled(TableContainer)(({ theme }) => ({
  position: "relative",
  maxHeight: "calc(100vh - 200px)",
  overflowY: "auto",
  overflowX: "auto",
  borderRadius: 16,
  "& .MuiTableCell-root": {
    padding: theme.spacing(1),
    borderBottom: `1px solid ${theme.palette.divider}`,
  },
}));

const HeaderCell = styled(TableCell)(({ theme }) => ({
  backgroundColor: theme.palette.primary.lighter,
  color: theme.palette.primary.main,
  fontWeight: 600,
  textAlign: "center",
  padding: theme.spacing(1),
  height: 56,
}));

// Configuration constants
const SLOT_HEIGHT = 60;
const LEFT_COLUMN_WIDTH = 150;
const DRAWER_WIDTH = 500;

// Table configuration
const contractConfig: TableConfig<Driver> = {
  type: "schedule",
  initialData: vehicleToDriverData.drivers,
  defaultTableHead: Location_TABLE_COLUMNS,
};

interface DriverScheduleProps {
  data?: ScheduleData;
}

const adaptToLocationScheduleData = (inputData: any): ScheduleData => {

  if (inputData?.drivers?.[0]?.immatricule !== undefined) {
    return inputData as ScheduleData;
  }


  return {
    drivers: (inputData?.drivers || []).map((driver: any) => ({
      ...driver,
      immatricule: driver.immatricule || driver.vehicleId || 'Unknown'
    })),
    timeSlots: inputData?.timeSlots || []
  };
};

export default function DriverSchedule({ data }: DriverScheduleProps) {

  const {
    filteredData,
    tableHead,
    handleFilterChange,
    handleResetFilters,
  } = useTableManager<Driver>(contractConfig);

  // State
  const [selectedDate, setSelectedDate] = useState(new Date(2025, 3, 1));
  const [zoomLevel, setZoomLevel] = useState(50);
  const [scheduleData, setScheduleData] = useState<ScheduleData>(
    adaptToLocationScheduleData(data || vehicleToDriverData)
  );
  const [activeId, setActiveId] = useState<string | null>(null);
  const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);
  const [hoveredDriver, setHoveredDriver] = useState<any>(null);
  const [anchorElT, setAnchorElT] = useState<HTMLElement | null>(null);
  const [hoveredSlot, setHoveredSlot] = useState<TimeSlot | null>(null);
  const [isDrawerOpen, setIsDrawerOpen] = useState(false);
  const [selectedRental, setSelectedRental] = useState<IRental | null>(null);


  const cellWidth = useMemo(() => {
    return 120 * (zoomLevel / 100);
  }, [zoomLevel]);


  const sensors = useSensors(
    useSensor(MouseSensor, {
      activationConstraint: {
        distance: 10,
      },
    }),
    useSensor(TouchSensor, {
      activationConstraint: {
        delay: 250,
        tolerance: 5,
      },
    })
  );


  const getDaysInMonth = () => {
    const monthStart = startOfMonth(selectedDate);
    const monthEnd = endOfMonth(selectedDate);

    const days = [];
    let currentDay = monthStart;

    while (currentDay <= monthEnd) {
      days.push({
        date: format(currentDay, 'yyyy-MM-dd'),
        dayName: format(currentDay, 'EEE', { locale: fr }).toLowerCase(),
        dayNumber: format(currentDay, 'dd'),
        isToday: format(currentDay, 'yyyy-MM-dd') === format(new Date(), 'yyyy-MM-dd'),
      });
      currentDay = addDays(currentDay, 1);
    }

    return days;
  };


  const handleTimeSlotDoubleClick = () => {
    setIsDrawerOpen(true);
  };

  const handlePopoverOpenT = (event: React.MouseEvent<HTMLElement>, slot: TimeSlot) => {
    setHoveredSlot(slot);
    setAnchorElT(event.currentTarget);
  };

  const handlePopoverCloseT = () => {
    setAnchorElT(null);
    setHoveredSlot(null);
  };

  const handleDateChange = (date: Dayjs | Date) => {
    setSelectedDate(date instanceof Date ? date : date.toDate());
  };

  const handleZoomChange = (zoom: number) => {
    setZoomLevel(zoom);
  };

  const handleDragStart = (event: DragStartEvent) => {
    setActiveId(event.active.id as string);
  };

  const handleDragEnd = (event: DragEndEvent) => {
    const { active, over } = event;

    if (over && active.data.current) {
      const timeSlot = active.data.current as TimeSlot;
      const targetDriverId = over.id as string;

      if (timeSlot.driverId !== targetDriverId) {
        setScheduleData((prev) => ({
          ...prev,
          timeSlots: prev.timeSlots.map((ts) =>
            ts.id === timeSlot.id ? { ...ts, driverId: targetDriverId } : ts
          ),
        }));
      }
    }

    setActiveId(null);
  };

  const handlePopoverOpen = (event: React.MouseEvent<HTMLElement>, driver: any) => {
    setAnchorEl(event.currentTarget);
    setHoveredDriver(driver);
  };

  const handlePopoverClose = () => {
    setAnchorEl(null);
    setHoveredDriver(null);
  };

  const handleDoubleClick = (event: React.MouseEvent<HTMLElement>, slot: TimeSlot) => {
    const vehicle = scheduleData.drivers.find(d => d.id === slot.driverId);

    const rental: IRental = {
      vehicle: vehicle?.name || 'Véhicule',
      vehicleName: vehicle?.name || 'Non spécifié',
      immatriculation: vehicle?.immatricule || 'Non spécifié',
      vehicleType: vehicle?.company || 'Type non spécifié',
      supplier: vehicle?.vehicleId || 'Fournisseur non spécifié',
      startDate: slot.startDate,
      endDate: slot.endDate,
      status: slot.status || 'en_cours',
      notes: 'Aucune observation'
    };

    setSelectedRental(rental);
    setIsDrawerOpen(true);
  };

  const activeTimeSlot = activeId
    ? scheduleData.timeSlots.find((slot) => slot.id === activeId)
    : null;


  const renderTimeSlotForDay = (driverId: string, date: string) => {
    const slot = scheduleData.timeSlots.find(
      s => s.driverId === driverId &&
        s.startDate <= date &&
        s.endDate >= date
    );

    if (!slot) return null;


    if (slot.startDate !== date) return null;


    const allDays = getDaysInMonth();
    const startDayIndex = allDays.findIndex(d => d.date === slot.startDate);
    const endDayIndex = allDays.findIndex(d => d.date === slot.endDate);

    if (startDayIndex === -1) return null;


    const daySpan = endDayIndex - startDayIndex + 1;


    const width = daySpan * cellWidth - 5;


    const statusColor = slot.color || '#4CAF50'; // Default to green if no color specified

    return (
      <Box
        sx={{
          position: 'absolute',
          left: 0,
          top: 0,
          width: `${width}px`,
          height: '100%',
          zIndex: 10,
          display: 'flex',
          borderRadius: "5px",
          cursor: 'pointer',
          transition: 'all 0.3s cubic-bezier(.25,.8,.25,1)',
          '&:hover': {
            filter: 'brightness(1.1)'
          }
        }}
        onMouseEnter={(e) => handlePopoverOpenT(e, slot)}
        onMouseLeave={handlePopoverCloseT}
        onDoubleClick={(e) => handleDoubleClick(e, slot)}
      >
        {/* Left border accent */}
        <Box sx={{
          width: '4px',
          height: '100%',
          backgroundColor: statusColor,
          flexShrink: 0,
          borderTopLeftRadius: "5px",
          borderBottomLeftRadius: "5px"
        }} />

        {/* Main content area */}
        <Box sx={{
          flex: 1,
          backgroundColor: `${statusColor}20`, // 20% opacity of the status color
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'space-between',
          padding: '0 8px',
          borderTopRightRadius: "5px",
          borderBottomRightRadius: "5px"
        }}>
          <Box sx={{ display: 'flex', alignItems: 'center' }}>
            <FontAwesome
              icon={faCar}
              width={12}
              sx={{
                mr: 1,
                color: statusColor
              }}
            />
            <Typography
              variant="caption"
              sx={{
                fontWeight: 500,
                color: 'text.primary'
              }}
            >
              {format(parseISO(slot.startDate), 'dd MMM', { locale: fr })} - {format(parseISO(slot.endDate), 'dd MMM', { locale: fr })}
            </Typography>
          </Box>
          <FontAwesome
            icon={faGripVertical}
            width={12}
            className="grip-icon"
            sx={{
              color: statusColor,
              opacity: 0.5,
              transition: 'opacity 0.2s ease',
              '&:hover': {
                opacity: 1
              }
            }}
          />
        </Box>
      </Box>
    );
  };

  return (
    <DndContext
      onDragStart={handleDragStart}
      onDragEnd={handleDragEnd}
      collisionDetection={closestCenter}
      sensors={sensors}
    >
      <Box sx={{ width: isDrawerOpen ? `calc(100% - ${DRAWER_WIDTH}px)` : undefined }}>
        <Box sx={{ ml: `${LEFT_COLUMN_WIDTH}px` }}>
          <VehicleScheduleToolbar
            date={selectedDate}
            onDateChange={handleDateChange}
            onZoomChange={handleZoomChange}
            onFilters={handleFilterChange}
            onResetFilters={handleResetFilters}
            initialColumns={Location_TABLE_COLUMNS}
            type={TableType.Vehicle}

          />
        </Box>
        <Box
          sx={{
            mt: 2,
            ml: `${LEFT_COLUMN_WIDTH}px`,
            py: 1,
            borderTopLeftRadius: 16,
            borderTopRightRadius: 16,
            display: 'flex',
            fontWeight: 500,
            justifyContent: 'center',
            backgroundColor: 'white',
          }}
        >
          {format(selectedDate, 'MMMM yyyy', { locale: fr })}
        </Box>
        <StyledTableContainer>
          <Table stickyHeader size="small">
            <TableHead>
              <TableRow>
                <HeaderCell
                  sx={{
                    position: 'sticky',
                    zIndex: 3,
                    left: 0,
                    backgroundColor: 'primary.lighter',
                    border: 'none',
                    width: LEFT_COLUMN_WIDTH,
                    minWidth: LEFT_COLUMN_WIDTH,
                  }}
                />
                {getDaysInMonth().map((day) => (
                  <HeaderCell
                    key={day.date}
                    data-date={day.date}
                    sx={{
                      position: 'sticky',
                      backgroundColor: day.date === format(new Date(), 'yyyy-MM-dd')
                        ? 'primary.lighter'
                        : '#F5F4FC',
                      top: 0,
                      zIndex: 2,
                      border: 'none',
                      width: `${cellWidth}px`,
                      minWidth: `${cellWidth}px`,
                      transition: 'width 0.2s ease, min-width 0.2s ease',
                    }}
                  >
                    <Box>
                      <Typography variant="caption" display="block">
                        {day.dayName}
                      </Typography>
                      <Typography variant="body2">
                        {day.dayNumber}
                      </Typography>
                    </Box>
                  </HeaderCell>
                ))}
              </TableRow>
            </TableHead>
            <TableBody>
              {filteredData.map((driver) => (
                <TableRow key={driver.id}>
                  <TableCell
                    sx={{
                      position: 'sticky',
                      left: 0,
                      backgroundColor: 'white',
                      zIndex: 1,
                      width: LEFT_COLUMN_WIDTH,
                      minWidth: LEFT_COLUMN_WIDTH,
                    }}
                    onMouseEnter={(e) => handlePopoverOpen(e, driver)}
                    onMouseLeave={handlePopoverClose}
                  >
                    <Box sx={{ whiteSpace: 'nowrap' }} display="flex" alignItems="center">
                      <FontAwesome
                        icon={faCar}
                        color="primary.main"
                        width={12}
                        sx={{ mr: 1 }}
                      />
                      <Typography sx={{ fontWeight: 500 }} variant="caption">
                        {driver.name}
                      </Typography>
                    </Box>
                    {driver.company && (
                      <Box sx={{ whiteSpace: 'nowrap' }} display="flex" alignItems="center">
                        <FontAwesome
                          icon={faIdCardAlt}
                          color="primary.main"
                          width={12}
                          sx={{ mr: 1 }}
                        />
                        <Typography sx={{ fontWeight: 500 }} variant="caption" display="block">
                          {driver.company}
                        </Typography>
                      </Box>
                    )}
                    {driver.immatricule && (
                      <Box sx={{ whiteSpace: 'nowrap' }} display="flex" alignItems="center">
                        <FontAwesome icon={faIdCard} color="primary.main" width={12} sx={{ mr: 1 }} />
                        <Typography sx={{ fontWeight: 500 }} variant="caption" display="block">
                          {driver.immatricule}
                        </Typography>
                      </Box>
                    )}
                  </TableCell>
                  {getDaysInMonth().map((day) => (
                    <DroppableCell
                      key={`${driver.id}-${day.date}`}
                      driverId={driver.id}
                      height={SLOT_HEIGHT}
                      sx={{
                        width: `${cellWidth}px`,
                        minWidth: `${cellWidth}px`,
                        position: 'relative',
                        transition: 'width 0.2s ease, min-width 0.2s ease',
                      }}
                    >
                      {renderTimeSlotForDay(driver.id, day.date)}
                    </DroppableCell>
                  ))}
                </TableRow>
              ))}
            </TableBody>
          </Table>
        </StyledTableContainer>

        <DragOverlay>
          {activeTimeSlot ? (
            <TimeSlotBlock>
              {(() => {
                try {
                  return `${format(parseISO(activeTimeSlot.startDate), 'dd MMM', { locale: fr })} - 
                         ${format(parseISO(activeTimeSlot.endDate), 'dd MMM', { locale: fr })}`;
                } catch (error) {
                  console.error("Error formatting dates in DragOverlay:", error, { activeTimeSlot });
                  return "Date invalide";
                }
              })()}
            </TimeSlotBlock>
          ) : null}
        </DragOverlay>

        <DriverDetailsPopover
          anchorEl={anchorEl}
          driver={hoveredDriver}
          onClose={handlePopoverClose}
        />

        {hoveredSlot ? (
          <TrajetDetailsPopover
            anchorEl={anchorElT}
            color={hoveredSlot.color as StatusColor}
            onClose={handlePopoverCloseT}
            data={{
              vehicle: scheduleData.drivers.find(d => d.id === hoveredSlot.driverId)?.name || 'Véhicule',
              vehicleName: scheduleData.drivers.find(d => d.id === hoveredSlot.driverId)?.name || 'Non spécifié',
              immatriculation: scheduleData.drivers.find(d => d.id === hoveredSlot.driverId)?.immatricule || 'Non spécifié',
              vehicleType: scheduleData.drivers.find(d => d.id === hoveredSlot.driverId)?.company || 'Type non spécifié',
              supplier: scheduleData.drivers.find(d => d.id === hoveredSlot.driverId)?.vehicleId || 'Fournisseur non spécifié',
              period: (() => {
                try {
                  return `${format(parseISO(hoveredSlot.startDate), 'dd MMM', { locale: fr })} - ${format(parseISO(hoveredSlot.endDate), 'dd MMM', { locale: fr })}`
                } catch (error) {
                  console.error("Error formatting period:", error, { hoveredSlot });
                  return "Période non spécifiée";
                }
              })(),
              status: hoveredSlot.status || 'en_cours',
              notes: 'Aucune observation'
            }}
          />
        ) : null}
      </Box>

      <CustomDrawer drawerWidth={DRAWER_WIDTH} open={isDrawerOpen} onClose={() => setIsDrawerOpen(false)}>
        {selectedRental && (
          <VehicleRentalForm
            isDrawerElement
            rental={selectedRental}
            mode="view"
            onClose={() => setIsDrawerOpen(false)}
          />
        )}
      </CustomDrawer>
    </DndContext>
  );
}
