import {
  Dialog,
  DialogTitle,
  DialogContent,
  DialogActions,
  Button,
  Stack,
  TextField,
  MenuItem,
  Typography,
  Box,
  IconButton,
  Chip,
  FormControl,
  InputLabel,
  Select,
  Switch,
  FormControlLabel,
  SelectChangeEvent,
  Grid,
  InputAdornment
} from '@mui/material';
import { DateTimePicker, TimePicker } from '@mui/x-date-pickers';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { 
  faXmark, 
  faCloudUpload, 
  faBell,
  faTrash,
  faClock,
  faCalendar
} from '@fortawesome/free-solid-svg-icons';
import { useState, useEffect } from 'react';
import FormField from "@/shared/components/form/form-field";
import { ModeType } from "@/shared/types/common";
import { 
  NOTIFICATION_INTERVALS,
  EVENT_TYPES,
  EMPLOYEE_TYPES,
  DIALOG_CONSTANTS,
  EVENT_FORM_FIELDS,
  FILTER_COLUMNS
} from '../constants/event.constants';
import { format } from 'date-fns';
import FontAwesome from '@/shared/components/fontawesome';
import { CalendarEvent, FormField as IFormField } from '../types/calendar-types';
import { MOCK_DRIVERS, MOCK_AGENCIES } from '@/shared/_mock/_employeeEvents';
import { StyledDialog, StyledDialogTitle } from '../../styles';
import { Formik, Form } from 'formik';
import { eventSchema } from '../utils/event-schema';
import { useCalendarStore } from '@/shared/api/stores/hr-service/calendarStore';
import { IDriver } from '@/shared/types/driver';
import { IAgency } from '@/shared/types/infrastructure';
import { useSnackbar } from 'notistack';

const INITIAL_EVENT_DATA = {
  employeeType: 'chauffeur' as const,
  type: '',
  employeeId: '',
  agenceId: '',
  date: new Date(),
  notes: '',
  notifications: [] as string[],
  isAllDay: true,
  files: [] as File[],
  hour: ''
};

interface AddEventDialogProps {
  open: boolean;
  onClose: () => void;
  onSubmit: (eventData: any) => void;
  initialEvent?: any;
  isEditing?: boolean;
}

interface EventData {
  employeeType: 'chauffeur' | 'sedentaire';
  type: string;
  employeeId: string;
  agenceId: string;
  date: Date;
  notes: string;
  notifications: string[];
  isAllDay: boolean;
  files?: File[];
  hour: string;
}

export default function AddEventDialog({ 
  open, 
  onClose, 
  onSubmit, 
  initialEvent,
  isEditing = false 
}: AddEventDialogProps) {
  const { enqueueSnackbar } = useSnackbar();
  const { 
    createEvent, 
    updateEvent, 
    loading, 
    error,
    drivers,
    agencies,
    notificationIntervals,
    fetchDrivers,
    fetchAgencies,
    fetchNotificationIntervals
  } = useCalendarStore();

  // Fetch data when dialog opens
  useEffect(() => {
    if (open) {
      fetchDrivers();
      fetchAgencies();
      fetchNotificationIntervals();
    }
  }, [open, fetchDrivers, fetchAgencies, fetchNotificationIntervals]);

  const initialValues = {
    ...INITIAL_EVENT_DATA,
    employeeType: 'chauffeur',
    ...initialEvent && {
      type: initialEvent.type,
      employeeType: initialEvent.employeeType || 'chauffeur',
      employeeId: initialEvent.employeeId,
      agenceId: initialEvent.agenceId,
      date: initialEvent.start ? new Date(initialEvent.start) : new Date(),
      notes: initialEvent.notes,
      notifications: initialEvent.notifications || [],
      isAllDay: initialEvent.allDay ?? true,
      hour: initialEvent.hour,
    }
  };

  const handleSubmit = async (values: EventData) => {
    try {
      // Prepare the data for the API
      const eventData = {
        ...values,
        date: values.date.toISOString(),
        employeeId: values.employeeType === 'chauffeur' ? values.employeeId : undefined,
        agenceId: values.employeeType === 'sedentaire' ? values.agenceId : undefined,
      };

      if (isEditing && initialEvent?.id) {
        await updateEvent({
          id: initialEvent.id,
          ...eventData
        });
        enqueueSnackbar('Événement mis à jour avec succès', { variant: 'success' });
      } else {
        await createEvent(eventData);
        enqueueSnackbar('Événement créé avec succès', { variant: 'success' });
      }
      
      onSubmit(values);
      onClose();
    } catch (error: any) {
      enqueueSnackbar(
        error.response?.data?.message || 'Une erreur est survenue', 
        { variant: 'error' }
      );
    }
  };

  // Transform data for form options
  const driverOptions = drivers.length > 0 
    ? drivers.map(driver => ({
        value: driver.id,
        label: `${driver.firstName} ${driver.lastName}`.trim()
      }))
    : Array.from(MOCK_DRIVERS);

  const agencyOptions = agencies.length > 0 
    ? agencies.map(agency => ({
        value: agency.id,
        label: agency.name
      }))
    : Array.from(MOCK_AGENCIES);

  const notificationOptions = notificationIntervals.length > 0 
    ? notificationIntervals 
    : Array.from(NOTIFICATION_INTERVALS);

  return (
    <StyledDialog 
      open={open} 
      onClose={onClose}
      maxWidth="md"
      fullWidth
      PaperProps={{
        sx: {
          borderRadius: 2,
          backgroundImage: 'linear-gradient(135deg, rgba(255,255,255,0.95) 0%, rgba(240,242,245,0.95) 100%)',
          backdropFilter: 'blur(20px)',
        }
      }}
    >
      <StyledDialogTitle sx={{ pb: 3, display: 'flex', justifyContent: 'space-between', alignItems: 'center',color: 'primary.main' }}>
        <Typography variant="h6">
          {isEditing ? DIALOG_CONSTANTS.TITLES.EDIT : DIALOG_CONSTANTS.TITLES.CREATE}
        </Typography>
        <IconButton 
          onClick={onClose} 
          size="small"
          sx={{ 
            position: 'absolute',
            right: 8,
            top: 8
          }}
        >
          <FontAwesomeIcon icon={faXmark} />
        </IconButton>
      </StyledDialogTitle>

      <Formik
        initialValues={initialValues}
        validationSchema={eventSchema}
        onSubmit={handleSubmit}
        enableReinitialize
      >
        {({ values, setFieldValue, errors, touched }) => (
          <Form>
            <DialogContent sx={{ p: 3 }}>
              <Grid container spacing={4}>
                <Grid item xs={12} sm={6}>
                  <FormField
                    field={{
                      name: 'employeeType',
                      label: 'Type d\'employé',
                      type: 'select',
                      options: Array.from(EMPLOYEE_TYPES)
                    }}
                    value={values.employeeType}
                    onChange={(name, value) => {
                      setFieldValue(name, value);
                      setFieldValue('employeeId', '');
                      setFieldValue('agenceId', '');
                    }}
                    error={touched.employeeType ? (errors.employeeType as string | undefined) : undefined}
                    isReadOnly={false}
                  />
                </Grid>
                <Grid item xs={12} sm={6}>
                  <FormField
                    field={{
                      name: values.employeeType === 'chauffeur' ? 'employeeId' : 'agenceId',
                      label: values.employeeType === 'chauffeur' ? 'Chauffeur' : 'Agence',
                      type: 'select',
                      options: values.employeeType === 'chauffeur' ? driverOptions : agencyOptions
                    }}
                    value={values.employeeType === 'chauffeur' ? values.employeeId : values.agenceId}
                    onChange={(name, value) => setFieldValue(name, value)}
                    error={touched[values.employeeType === 'chauffeur' ? 'employeeId' : 'agenceId'] 
                      ? (errors[values.employeeType === 'chauffeur' ? 'employeeId' : 'agenceId'] as string | undefined) 
                      : undefined}
                    isReadOnly={false}
                  />
                </Grid>

                <Grid item xs={12} sm={6}>
                  <FormField
                    field={{
                      name: 'type',
                      label: 'Type d\'événement',
                      type: 'select',
                      options: Array.from(EVENT_TYPES)
                    }}
                    value={values.type}
                    onChange={(name, value) => setFieldValue(name, value)}
                    error={touched.type ? (errors.type as string | undefined) : undefined}
                    isReadOnly={false}
                  />
                </Grid>

                <Grid item xs={12} sm={6}>
                  <FormField
                    field={{
                      name: 'date',
                      label: 'Date',
                      type: 'date',
                      icon: faCalendar
                    }}
                    value={values.date}
                    onChange={(name, value) => setFieldValue(name, value)}
                    error={touched.date ? (errors.date as string | undefined) : undefined}
                    isReadOnly={false}
                  />
                </Grid>
                <Grid item xs={12} sm={6}>
                  <FormField
                    field={{
                      name: 'hour',
                      label: 'Heure',
                      type: 'time',
                      icon: faClock
                    }}
                    value={values.hour}
                    onChange={(name, value) => setFieldValue(name, value)}
                    error={touched.hour ? (errors.hour as string | undefined) : undefined}
                    isReadOnly={false}
                  />
                </Grid>
                <Grid item xs={12} sm={6}>
                  <FormField
                    field={{
                      name: 'notes',
                      label: 'Commentaires et notes',
                      type: 'textarea',
                      placeholder: 'Ajouter un commentaire...'
                    }}
                    value={values.notes}
                    onChange={(name, value) => setFieldValue(name, value)}
                    error={touched.notes ? (errors.notes as string | undefined) : undefined}
                    isReadOnly={false}
                  />
                </Grid>

                <Grid item xs={12}>
                  <FormField
                    field={{
                      name: 'notifications',
                      label: 'Notifications',
                      type: 'multiple',
                      placeholder: "Sélectionnez une ou plusieurs notifications",
                      options: notificationOptions
                    }}
                    value={values.notifications}
                    onChange={(name, value) => setFieldValue(name, value)}
                    error={touched.notifications ? (errors.notifications as string | undefined) : undefined}
                    isReadOnly={false}
                  />
                </Grid>

                <Grid item xs={12}>
                  <Box sx={{ border: '1px dashed', borderColor: 'divider', borderRadius: 1, p: 3 }}>
                    <Stack spacing={2} alignItems="center">
                      <input
                        type="file"
                        id="file-upload"
                        multiple
                        style={{ display: 'none' }}
                        onChange={(event) => {
                          if (event.target.files) {
                            const newFiles = Array.from(event.target.files);
                            setFieldValue('files', [...(values.files || []), ...newFiles]);
                          }
                        }}
                      />
                      <label htmlFor="file-upload">
                        <Button
                          component="span"
                          variant="outlined"
                          startIcon={<FontAwesomeIcon icon={faCloudUpload} />}
                        >
                          {DIALOG_CONSTANTS.BUTTONS.ADD_DOCUMENTS}
                        </Button>
                      </label>
                      <Box sx={{ width: '100%', textAlign: 'center' }}>
                        {(!values.files || values.files.length === 0) ? (
                          <Typography color="text.secondary" variant="body2">
                            Aucun document ajouté
                          </Typography>
                        ) : (
                          <Stack spacing={1} width="100%">
                            {values.files.map((file, index) => (
                              <Chip
                                key={index}
                                label={file.name}
                                onDelete={() => {
                                  const newFiles = values.files?.filter((_, i) => i !== index);
                                  setFieldValue('files', newFiles);
                                }}
                                sx={{ justifyContent: 'space-between' }}
                              />
                            ))}
                          </Stack>
                        )}
                      </Box>
                    </Stack>
                  </Box>
                </Grid>

                <Grid item xs={12}>
                  <FormControlLabel
                    control={
                      <Switch
                        checked={values.isAllDay}
                        onChange={(e) => setFieldValue('isAllDay', e.target.checked)}
                      />
                    }
                    label="Toute la journée"
                  />
                </Grid>
              </Grid>
            </DialogContent>

            <DialogActions sx={{ p: 3, pt: 0 }}>
              <Button onClick={onClose} variant="outlined" disabled={loading}>
                {DIALOG_CONSTANTS.BUTTONS.CANCEL}
              </Button>
              <Button 
                type="submit"
                variant="contained"
                disabled={loading || !values.type || !(values.employeeId || values.agenceId)}
              >
                {loading ? 'Chargement...' : (isEditing ? DIALOG_CONSTANTS.BUTTONS.SAVE : DIALOG_CONSTANTS.BUTTONS.CREATE)}
              </Button>
            </DialogActions>
          </Form>
        )}
      </Formik>
    </StyledDialog>
  );
} 