'use client';

import { useState, useRef, useMemo, useEffect } from 'react';
import { Container, Box, Alert, Snackbar } from '@mui/material';
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { fr } from 'date-fns/locale';
import dayGridPlugin from '@fullcalendar/daygrid';
import timeGridPlugin from '@fullcalendar/timegrid';
import interactionPlugin from '@fullcalendar/interaction';
import { _employeeEvents, EmployeeEvent } from '@/shared/_mock/_employeeEvents';
import { ScheduleToolbar } from './schedule-toolbar';
import EventDetailsDialog from './event-details-dialog';
import AddEventDialog from './add-event-dialog';
import FullCalendar from '@fullcalendar/react';
import { StyledCalendarContainer } from '../styles/calendar-styles';
import { CALENDAR_VIEWS, TIME_SETTINGS, FILTER_COLUMNS, CALENDAR_CONFIG } from '../constants/event.constants';
import { CalendarViewType, FilterType, AgencyType, StatusType, CalendarEvent } from '../types/calendar-types';
import { type TableConfig, useTableManager } from "@/hooks/use-table-manager"
import { TableType } from "@/shared/types/common"
import { useCalendarStore } from '@/shared/api/stores/hr-service/calendarStore';
import { useSnackbar } from 'notistack';

// Define the calendar config
const calendarConfig: TableConfig<EmployeeEvent> = {
  type: "calendar",
  initialData: _employeeEvents,
  defaultTableHead: [
    { id: "type", label: "Type", type: "text" },
    { id: "agency", label: "Agence", type: "text" },
    { id: "driverStatus", label: "Statut", type: "text" },
    { id: "employeeName", label: "Employé", type: "text" },
    { id: "start", label: "Date de début", type: "date" },
    { id: "end", label: "Date de Fin", type: "date" },
    { id: "title", label: "Titre", type: "text" }
  ]
}

export default function RHCalendarView() {
  const { enqueueSnackbar } = useSnackbar();
  const { 
    events, 
    loading, 
    error, 
    fetchEvents 
  } = useCalendarStore();
  const [currentDate, setCurrentDate] = useState(new Date());
  const [view, setView] = useState<CalendarViewType>(CALENDAR_VIEWS.MONTH);
  const calendarRef = useRef<FullCalendar>(null);
  const [selectedEvent, setSelectedEvent] = useState<CalendarEvent | null>(null);
  const [openEventDialog, setOpenEventDialog] = useState(false);
  const [openAddDialog, setOpenAddDialog] = useState(false);
  const [showSuccess, setShowSuccess] = useState(false);
  const [isEventDialogOpen, setIsEventDialogOpen] = useState(false);
  const [zoom, setZoom] = useState<number>(CALENDAR_CONFIG.ZOOM_DEFAULT);

  // Replace individual filter states with useTableManager
  const { 
    filteredData: filteredEvents,
    tableHead,
    handleFilterChange,
    handleResetFilters
  } = useTableManager<EmployeeEvent>(calendarConfig)

  // Fetch events on component mount
  useEffect(() => {
    fetchEvents();
  }, [fetchEvents]);

  // Show error if any
  useEffect(() => {
    if (error) {
      enqueueSnackbar(error, { variant: 'error' });
    }
  }, [error, enqueueSnackbar]);

  const handleEventClick = (info: any) => {
    const employeeEvent = {
      ...info.event.extendedProps,
      start: info.event.start.toISOString(),
      end: info.event.end.toISOString(),
      allDay: info.event.allDay,
    };

    // Transform EmployeeEvent to CalendarEvent
    const calendarEvent: CalendarEvent = {
      id: employeeEvent.id,
      title: employeeEvent.title,
      start: employeeEvent.start,
      end: employeeEvent.end,
      allDay: employeeEvent.allDay,
      type: employeeEvent.type as FilterType,
      color: employeeEvent.color || '#B7B7B7',
      agency: employeeEvent.agency,
      driverStatus: employeeEvent.driverStatus,
      employeeType: 'chauffeur',
      employeeId: employeeEvent.employeeId,
      employeeName: employeeEvent.employeeName,
      date: employeeEvent.start,
      notes: employeeEvent.description,
      notifications: employeeEvent.notifications,
      files: employeeEvent.documents?.map((doc: { name: string; type: string }) => new File([], doc.name, { type: doc.type })) || [],
      description: employeeEvent.description,
      comments: Array.isArray(employeeEvent.comments) 
        ? employeeEvent.comments.map((c: { text: string }) => c.text).join('\n') 
        : '',
      status: employeeEvent.status
    };

    setSelectedEvent(calendarEvent);
    setOpenEventDialog(true);
  };

  const handleAddEvent = async (eventData: any) => {
    try {
      await fetchEvents(); // Refresh events after creation
      setOpenAddDialog(false);
      enqueueSnackbar('Événement créé avec succès', { variant: 'success' });
    } catch (error) {
      enqueueSnackbar('Erreur lors de la création de l\'événement', { variant: 'error' });
    }
  };

  const handleViewChange = (newView: CalendarViewType) => {
    setView(newView);
    if (calendarRef.current) {
      const calendarApi = calendarRef.current.getApi();
      calendarApi.changeView(newView);
    }
  };

  const handleDateChange = (newDate: Date) => {    
    if (calendarRef.current) {
      const calendarApi = calendarRef.current.getApi();
      calendarApi.gotoDate(newDate);
      setCurrentDate(newDate);
    }
  };

  const handlePrint = () => {
    window.print();
  };

  const handleCreateEvent = () => {
    setOpenAddDialog(true);
  };

  const handleCloseEventDialog = () => {
    setIsEventDialogOpen(false);
  };

  const handleZoomChange = (newZoom: number) => {
    setZoom(newZoom);
    window.dispatchEvent(new Event('resize'));
  };

  const handleEventUpdate = (updatedEvent: EmployeeEvent) => {    
    // Handle event update logic here
    setOpenEventDialog(false);
  };

  const handleUpdateEvent = (updatedEvent: CalendarEvent) => {
    // Handle event update logic here
    setOpenEventDialog(false);
  };

  return (
    <LocalizationProvider dateAdapter={AdapterDateFns} adapterLocale={fr}>
      <Container maxWidth={false} sx={{ '& .fc-day': { backgroundColor: '#fff' }, p: 3 }}>
        <Box sx={{ mb: 1 }}>
          <ScheduleToolbar
            date={currentDate}
            view={view}
            onViewChange={handleViewChange}
            onDateChange={handleDateChange}
            onZoomChange={handleZoomChange}
            onFilters={handleFilterChange}
            onResetFilters={handleResetFilters}
            onCreateEvent={handleCreateEvent}
            initialColumns={tableHead}
            type={TableType.Calendar}
            viewMode="calendar"
            onViewToggle={() => {}}
          />
        </Box>

        {/* Calendar component */}
        <StyledCalendarContainer zoom={zoom}>
          <FullCalendar
            ref={calendarRef}
            plugins={[dayGridPlugin, timeGridPlugin, interactionPlugin]}
            weekends
            editable
            selectable
            events={events}
            firstDay={1}
            locale="fr"
            initialView={view}
            headerToolbar={false}
            dayMaxEventRows={false}
            eventDisplay="block"
            height="100%"
            dayHeaderFormat={{ weekday: 'long' }}
            slotMinTime="08:00:00"
            slotMaxTime="19:00:00"
            slotDuration="01:00:00"
            views={{
              dayGridMonth: {
                dayMaxEventRows: false,
              },
              timeGridWeek: {
                dayMaxEventRows: false,
                dayHeaderFormat: { weekday: 'long' },
                slotDuration: '01:00:00',
                slotLabelFormat: {
                  hour: '2-digit',
                  minute: '2-digit',
                  hour12: false
                },
                allDaySlot: true,
                allDayText: 'Journée entière',
                headerToolbar: false,
                nowIndicator: true,
              },
              timeGridDay: {
                slotDuration: '01:00:00',
                displayEventEnd: true,
                nowIndicator: true,
                eventMaxStack: 2,
                slotEventOverlap: false,
                allDaySlot: true,
                allDayText: 'Journée entière',
                slotLabelFormat: {
                  hour: '2-digit',
                  minute: '2-digit',
                  hour12: false
                }
              },
            }}
            eventClick={handleEventClick}
            datesSet={(arg) => {
            }}
          />
        </StyledCalendarContainer>

        {/* Dialogs */}
        <EventDetailsDialog
          event={selectedEvent || {
            id: '',
            title: '',
            start: new Date().toISOString(),
            end: new Date().toISOString(),
            allDay: false,
            type: 'custom',
            color: '#B7B7B7',
            agency: 'all',
            driverStatus: 'all',
            employeeType: 'chauffeur',
            date: new Date().toISOString(),
            status: 'pending'
          }}
          open={openEventDialog}
          onClose={() => {
            setOpenEventDialog(false);
            setSelectedEvent(null);
          }}
          onEventUpdate={handleUpdateEvent}
        />

        <AddEventDialog
          open={openAddDialog}
          onClose={() => setOpenAddDialog(false)}
          onSubmit={handleAddEvent}
        />

        {/* Success Snackbar */}
        <Snackbar
          open={showSuccess}
          autoHideDuration={4000}
          onClose={() => setShowSuccess(false)}
          anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
        >
          <Alert 
            onClose={() => setShowSuccess(false)} 
            severity="success" 
            variant="filled"
            sx={{ width: '100%' }}
          >
            Événement créé avec succès
          </Alert>
        </Snackbar>
      </Container>
    </LocalizationProvider>
  );
} 