'use client';

import React, { useEffect, useState, useCallback } from 'react';
import {
  Typography,
  Grid,
  Box,
  Dialog,
  DialogTitle,
  DialogContent,
  DialogActions,
  Button,
  Snackbar,
  Alert,
  IconButton,
} from '@mui/material';
import { useFormik } from 'formik';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
import { fr } from 'date-fns/locale';
import FormField from '@/shared/components/form/form-field';
import { FormFieldType, ModeType } from '@/shared/types/common';
import FormContainer from '@/layouts/form/form-container';
import EditExportButtons from '@/shared/components/form/edit-export-buttons';
import ActionButtons from '@/shared/components/form/buttons-action';
import { AddButton } from '@/shared/components/table/styles';
import FontAwesome from '@/shared/components/fontawesome';
import { faFileArrowUp, faTimes } from '@fortawesome/free-solid-svg-icons';
import { IDemandeAbsence } from '@/shared/types/leave';
import { leaveFormFields } from '../utils/form-fields-conge';
import { congeSchema } from '../utils/conge-schema';
import ConditionalComponent from "@/shared/components/table/ConditionalComponent";
import { differenceInDays } from 'date-fns';
import { useAbsenceStore } from '@/shared/api/stores/absenceStore';
import { useRHAbsenceStore } from '@/shared/api/stores/hr-service/rhAbsence';
import { enqueueSnackbar } from 'notistack';
import Upload from '@/shared/components/upload/upload';

interface CongeFormProps {
  conge: IDemandeAbsence;
  mode: ModeType;
  onSave: (updatedConge: IDemandeAbsence, file?: File) => void;
  onEdit: (updatedConge: IDemandeAbsence) => void;
  onClose: (forceClose: boolean) => void;
  updateTabContent: (tabId: string, newContent: IDemandeAbsence) => void;
  tabId: string;
}

export default function CongeForm({
  conge,
  mode,
  onSave,
  onClose,
  onEdit,
  updateTabContent,
  tabId,
}: CongeFormProps) {
  const isReadOnly = mode === 'view';
  const [selectedFile, setSelectedFile] = useState<File | null>(null);
  const [selectedFileName, setSelectedFileName] = useState<string>('');
  const [uploadDialogOpen, setUploadDialogOpen] = useState(false);
  const { exportLeaves, downloadLeaveExport, loading: exportLoading } = useAbsenceStore();
  const { collaborators, fetchCollaborators } = useRHAbsenceStore();
  const [snackbar, setSnackbar] = useState<{ open: boolean; message: string; severity: 'success' | 'error' }>({
    open: false,
    message: '',
    severity: 'success'
  });

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

  // Transform collaborators data for the dropdown
  const employeeOptions = collaborators.map(collab => ({
    value: collab.id.toString(),
    label: `${collab.firstName} ${collab.lastName}`
  }));

  const formik = useFormik<IDemandeAbsence>({
    initialValues: conge,
    validationSchema: congeSchema,
    enableReinitialize: true,
    onSubmit: async (values) => {
      try {
        const selectedCollaborator = collaborators.find(c => c.id.toString() === values.employeeId);
        if (selectedCollaborator) {
          values.employeeName = `${selectedCollaborator.firstName} ${selectedCollaborator.lastName}`;
        }
        
        await onSave(values, selectedFile || undefined);
        setSnackbar({
          open: true,
          message: 'Demande de congé enregistrée avec succès',
          severity: 'success'
        });
        setSelectedFile(null);
        setSelectedFileName('');
        formik.resetForm({ values });
      } catch (error: any) {
        setSnackbar({
          open: true,
          message: error.message || 'Erreur lors de la sauvegarde',
          severity: 'error'
        });
      }
    },
  });

  const handleExport = async () => {
    try {
      const exportFilters = {
        startDate: formik.values.startDate,
        endDate: formik.values.endDate,
        states: formik.values.status ? [formik.values.status] : undefined,
      };

      const result = await exportLeaves(exportFilters);
      
      if (result.success && result.filePath) {
        enqueueSnackbar('Export en cours...', { variant: 'info' });
        const downloadResult = await downloadLeaveExport(result.filePath);
        
        if (downloadResult.success) {
          enqueueSnackbar('Export du congé terminé avec succès', { variant: 'success' });
        } else {
          enqueueSnackbar(downloadResult.message, { variant: 'error' });
        }
      } else {
        enqueueSnackbar(result.message, { variant: 'error' });
      }
    } catch (error) {
      enqueueSnackbar('Erreur lors de l\'export du congé', { variant: 'error' });
    }
  };

  // Auto-calculate days count when start/end dates change
  useEffect(() => {
    if (isReadOnly) return;

    const calculateDays = () => {
      if (formik.values.startDate && formik.values.endDate) {
        const startDate = new Date(formik.values.startDate);
        const endDate = new Date(formik.values.endDate);
        
        if (endDate >= startDate) {
          const daysDiff = differenceInDays(endDate, startDate) + 1;
          
          if (daysDiff > 0 && 
              daysDiff !== formik.values.daysCount && 
              !Number.isNaN(daysDiff)) {
            formik.setFieldValue('daysCount', daysDiff, false);
          }
        }
      }
    };

    const timeoutId = setTimeout(calculateDays, 100);
    return () => clearTimeout(timeoutId);
  }, [formik.values.startDate, formik.values.endDate, isReadOnly]);

  useEffect(() => {
    if (updateTabContent && tabId && mode !== "view" && formik.dirty && !formik.isSubmitting) {
      updateTabContent(tabId, formik.values);
    }
  }, [formik.values, updateTabContent, tabId, mode, formik.dirty, formik.isSubmitting]);

  const handleFileUpload = (file: File) => {
    // Validate file type and size
    const allowedTypes = ['.pdf', '.doc', '.docx', '.jpg', '.jpeg', '.png'];
    const maxSize = 5 * 1024 * 1024; // 5MB
    
    const fileExtension = '.' + file.name.split('.').pop()?.toLowerCase();
    if (!allowedTypes.includes(fileExtension)) {
      setSnackbar({
        open: true,
        message: 'Type de fichier non autorisé. Veuillez sélectionner un fichier PDF, DOC, DOCX, JPG ou PNG.',
        severity: 'error'
      });
      return;
    }
    
    if (file.size > maxSize) {
      setSnackbar({
        open: true,
        message: 'Le fichier est trop volumineux. La taille maximale est de 5MB.',
        severity: 'error'
      });
      return;
    }
    
    setSelectedFile(file);
    setSelectedFileName(file.name);
    setUploadDialogOpen(false);
    setSnackbar({
      open: true,
      message: 'Document ajouté avec succès',
      severity: 'success'
    });
  };

  const handleRemoveFile = () => {
    setSelectedFile(null);
    setSelectedFileName('');
  };

  const renderField = useCallback((field: FormFieldType<IDemandeAbsence>) => {
    if (field.name === 'employeeId') {
      return (
        <FormField
          key={field.name}
          field={{
            ...field,
            options: employeeOptions,
            type: 'select',
          }}
          value={formik.values[field.name]}
          onChange={(name, value) => {
            formik.setFieldValue(name, value);
            const selectedCollaborator = collaborators.find(c => c.id.toString() === value);
            if (selectedCollaborator) {
              formik.setFieldValue('employeeName', `${selectedCollaborator.firstName} ${selectedCollaborator.lastName}`);
            }
          }}
          onBlur={formik.handleBlur}
          isReadOnly={isReadOnly}
          error={
            formik.touched[field.name] && formik.errors[field.name]
              ? (formik.errors[field.name] as string | undefined)
              : undefined
          }
        />
      );
    }

    const fieldProps = field.name === 'daysCount' 
      ? { 
          ...field, 
          disabled: true,
          readOnly: true
        }
      : field;

    return (
      <FormField
        key={field.name}
        field={fieldProps}
        value={formik.values[field.name]}
        onChange={(name, value) => {
          if (name === 'daysCount') return;
          formik.setFieldValue(name, value);
        }}
        onBlur={formik.handleBlur}
        isReadOnly={isReadOnly || field.name === 'daysCount'}
        error={
          formik.touched[field.name] && formik.errors[field.name]
            ? (formik.errors[field.name] as string | undefined)
            : undefined
        }
      />
    );
  }, [formik.values, formik.touched, formik.errors, isReadOnly, employeeOptions, collaborators]);

  return (
    <LocalizationProvider dateAdapter={AdapterDateFns} adapterLocale={fr}>
      <FormContainer titre="Demande de congé">
        <ConditionalComponent isValid={isReadOnly}>
          <EditExportButtons
            onEdit={() => onEdit(formik.values)}
            onExport={handleExport}
            tooltipTitle="le congé"
          />
        </ConditionalComponent>
        
        <form onSubmit={formik.handleSubmit}>
          <Grid container spacing={4}>
            {leaveFormFields.map((field: FormFieldType<IDemandeAbsence>, index: number) => (
              <Grid 
                item 
                xs={12} 
                sm={4}
                key={field.name}
              >
                {renderField(field)}
              </Grid>
            ))}

            <Grid item xs={12}>
              <Box display="flex" alignItems="center" gap={4}>
                <Typography sx={{ color: 'primary.main' }}>
                  Pièce justificative
                </Typography>
                <AddButton
                  variant="contained"
                  sx={{ minHeight: '43px' }}
                  endIcon={<FontAwesome icon={faFileArrowUp} width={18} />}
                  disabled={isReadOnly}
                  onClick={() => setUploadDialogOpen(true)}
                >
                  Importez un document
                </AddButton>
                {selectedFileName && (
                  <Box display="flex" alignItems="center" gap={2}>
                    <Typography variant="body2" color="text.secondary">
                      {selectedFileName}
                    </Typography>
                    {!isReadOnly && (
                      <IconButton size="small" onClick={handleRemoveFile}>
                        <FontAwesome icon={faTimes} width={14} />
                      </IconButton>
                    )}
                  </Box>
                )}
              </Box>
            </Grid>

            <Grid item xs={12}>
              <ConditionalComponent isValid={!isReadOnly}>
                <ActionButtons 
                  onSave={() => formik.handleSubmit()}
                  onCancel={() => onClose(false)}
                  mode={mode}
                />
              </ConditionalComponent>
            </Grid>
          </Grid>
        </form>

        <Dialog open={uploadDialogOpen} onClose={() => setUploadDialogOpen(false)} maxWidth="sm" fullWidth>
          <DialogTitle>Importer un document justificatif</DialogTitle>
          <DialogContent>
            <Box sx={{ mt: 2 }}>
              <Upload
                multiple={false}
                onDrop={(acceptedFiles) => {
                  if (acceptedFiles.length > 0) {
                    handleFileUpload(acceptedFiles[0]);
                  }
                }}
                accept={{
                  'application/pdf': ['.pdf'],
                  'application/msword': ['.doc'],
                  'application/vnd.openxmlformats-officedocument.wordprocessingml.document': ['.docx'],
                  'image/*': ['.png', '.jpg', '.jpeg'],
                }}
              />
            </Box>
          </DialogContent>
          <DialogActions>
            <Button onClick={() => setUploadDialogOpen(false)}>Annuler</Button>
          </DialogActions>
        </Dialog>

        <Snackbar
          open={snackbar.open}
          autoHideDuration={2000}
          onClose={() => setSnackbar(prev => ({ ...prev, open: false }))}
          anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
          sx={{
            zIndex: 9999,
            '& .MuiAlert-root': {
              width: '100%',
              minWidth: '300px'
            }
          }}
        >
          <Alert
            onClose={() => setSnackbar(prev => ({ ...prev, open: false }))}
            severity={snackbar.severity}
            elevation={6}
            variant="filled"
          >
            {snackbar.message}
          </Alert>
        </Snackbar>
      </FormContainer>
    </LocalizationProvider>
  );
}