'use client';

import React, { useEffect, useState } from 'react';
import {
  Typography,
  Grid,
  Box,
  Dialog,
  DialogTitle,
  DialogContent,
  DialogActions,
  Button,
  Snackbar,
  Alert,
  IconButton,
} from '@mui/material';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
import { fr } from 'date-fns/locale';
import { useFormik } from 'formik';
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 { absenceFormFields } from '../utils/form-fields-absence';
import { absenceSchema } from '../utils/absence-schema';
import ConditionalComponent from '@/shared/components/table/ConditionalComponent';
import Upload from '@/shared/components/upload/upload';
import { UnsavedChangesDialog } from '@/shared/components/dialog/UnsavedChangesDialog';
import { useAbsenceStoree } from '@/shared/api/stores/absenceStore';

interface AbsenceFormProps {
  absence: IDemandeAbsence;
  mode: ModeType;
  onSave: (updatedAbsence: IDemandeAbsence, file: File | null) => Promise<{ success: boolean; message: string }>;
  onEdit: (updatedAbsence: IDemandeAbsence) => void;
  onClose: (forceClose: boolean) => void;
  updateTabContent: (tabId: string, newContent: IDemandeAbsence) => void;
  tabId: string;
}

const INITIAL_VALUES: IDemandeAbsence = {
  id: '',
  isActive: true,
  requestNumber: '',
  submissionDate: new Date().toISOString().split('T')[0],
  requestType: 'Congé',
  leaveType: '',
  absenceType: '',
  startDate: new Date().toISOString().split('T')[0],
  endDate: new Date().toISOString().split('T')[0],
  status: 'En attente' as const,
  processDate: '',
  reason: '',
  daysCount: 0,
  employeeId: '',
  dateDebut: new Date().toISOString().split('T')[0],
  dateFin: new Date().toISOString().split('T')[0],
  dateSubmission: new Date().toISOString().split('T')[0],
  dateTraitement: ''
};

export default function AbsenceForm({
  absence,
  mode,
  onSave,
  onClose,
  onEdit,
  updateTabContent,
  tabId,
}: AbsenceFormProps) {
  const { exportAbsences, downloadExport } = useAbsenceStoree();
  const [uploadDialogOpen, setUploadDialogOpen] = useState(false);
  const [selectedFile, setSelectedFile] = useState<File | null>(null);
  const [selectedFileName, setSelectedFileName] = useState<string>('');
  const [employeeId, setEmployeeId] = useState('');
  const [snackbar, setSnackbar] = useState<{ open: boolean; message: string; severity: 'success' | 'error' }>({
    open: false,
    message: '',
    severity: 'success'
  });
  const isReadOnly = mode === 'view';

  useEffect(() => {
    const storedId = typeof window !== 'undefined' ? window.localStorage.getItem("userId") : '';
    setEmployeeId(storedId || '');
  }, []);

  const handleSubmitSuccess = (message: string) => {
    setSnackbar({
      open: true,
      message,
      severity: 'success'
    });
    setTimeout(() => {
      onClose(true);
    }, 2000);
  };

  const formik = useFormik<IDemandeAbsence>({
    initialValues: mode === 'add' ? { ...INITIAL_VALUES, employeeId } : {
      ...absence,
      requestType: absence?.requestType || 'Congé',
      absenceType: absence?.absenceType || '',
      leaveType: absence?.leaveType || '',
      employeeId: absence?.employeeId || employeeId,
      status: 'En attente' as const
    },
    enableReinitialize: true,
    validationSchema: absenceSchema,
    onSubmit: async (values) => {
      try {
        const start = new Date(values.startDate);
        const end = new Date(values.endDate);
        const daysDiff = Math.ceil((end.getTime() - start.getTime()) / (1000 * 60 * 60 * 24)) + 1;

        const submissionData: IDemandeAbsence = {
          ...values,
          daysCount: daysDiff,
          status: 'En attente' as const,
        };

        const result = await onSave(submissionData, selectedFile);
        
        if (result?.success) {
          setSnackbar({
            open: true,
            message: result.message,
            severity: 'success'
          });
          formik.resetForm();
          setSelectedFile(null);
          setSelectedFileName('');
        } else {
          setSnackbar({
            open: true,
            message: result?.message || 'Erreur lors de la création',
            severity: 'error'
          });
        }
      } catch (error: any) {
        setSnackbar({
          open: true,
          message: error.message || 'Erreur lors de la soumission',
          severity: 'error'
        });
      }
    },
  });

  useEffect(() => {
    if (updateTabContent && tabId && mode === "edit") {
      const debouncedUpdate = setTimeout(() => {
        const title = `REQ-${formik.values.id || tabId} - ${formik.values.requestType} (${formik.values.requestType === 'Congé'
            ? formik.values.leaveType || 'LEAVE_PAID'
            : formik.values.absenceType || 'EXTERNAL_ASSIGNMENT'
          })`;

        updateTabContent(tabId, {
          ...formik.values,
          title
        });
      }, 300);
      return () => clearTimeout(debouncedUpdate);
    }
  }, [formik.values, updateTabContent, tabId, mode]);

  useEffect(() => {
    if (mode === 'add' && updateTabContent && tabId) {
      const initialTitle = `REQ-${tabId} - ${formik.values.requestType} (${formik.values.requestType === 'Congé'
          ? formik.values.leaveType || 'LEAVE_PAID'
          : formik.values.absenceType || 'EXTERNAL_ASSIGNMENT'
        })`;

      updateTabContent(tabId, {
        ...formik.values,
        title: initialTitle
      });
    }
  }, [mode, tabId, updateTabContent, formik.values.requestType]);

  const handleTypeChange = (name: string, value: string) => {
    formik.setFieldValue(name, value);
    if (name === 'requestType') {
      if (value === 'Absence') {
        formik.setFieldValue('leaveType', '');
        formik.setFieldValue('absenceType', 'EXTERNAL_ASSIGNMENT');
        formik.setFieldTouched('absenceType', true, false);
      } else {
        formik.setFieldValue('absenceType', '');
        formik.setFieldValue('leaveType', 'LEAVE_PAID');
        formik.setFieldTouched('leaveType', true, false);
      }

      if (updateTabContent && tabId) {
        const newTitle = `REQ-${formik.values.id || tabId} - ${value} (${value === 'Congé' ? 'LEAVE_PAID' : 'EXTERNAL_ASSIGNMENT'
          })`;
        updateTabContent(tabId, {
          ...formik.values,
          title: newTitle
        });
      }
    }
  };

  useEffect(() => {
    if (formik.values.startDate && formik.values.endDate) {
      const start = new Date(formik.values.startDate);
      const end = new Date(formik.values.endDate);
      if (end >= start) {
        const diffTime = Math.abs(end.getTime() - start.getTime());
        const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)) + 1;
        if (diffDays !== formik.values.daysCount) {
          formik.setFieldValue('daysCount', diffDays, false);
        }
      }
    }
  }, [formik.values.startDate, formik.values.endDate]);

  const handleFileUpload = (file: File) => {
    setSelectedFile(file);
    setSelectedFileName(file.name);
    setUploadDialogOpen(false);
  };

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

  const getFormTitle = () => {
    switch (mode) {
      case 'view':
        return 'Fiche de Demande';
      case 'edit':
        return 'Modification Demande';
      case 'add':
        return 'Nouvelle Demande';
      default:
        return 'Demande';
    }
  };

  const renderField = (field: FormFieldType<IDemandeAbsence>) => {
    if (field.name === 'status') {
      return (
        <FormField
          field={field}
          value={'En attente'}
          onChange={() => { }}
          error={undefined}
          onBlur={formik.handleBlur}
          isReadOnly={true}
          disabled={true}
        />
      );
    }

    // Disable daysCount field since it's automatically calculated
    if (field.name === 'daysCount') {
      return (
        <FormField
          field={field}
          value={formik.values[field.name as keyof IDemandeAbsence]}
          onChange={() => { }} // No onChange since it's calculated automatically
          error={
            formik.touched[field.name as keyof IDemandeAbsence]
              ? (formik.errors[field.name as keyof IDemandeAbsence] as string | undefined)
              : undefined
          }
          onBlur={formik.handleBlur}
          isReadOnly={true}
          disabled={true}
        />
      );
    }

    return (
      <FormField
        field={field}
        value={formik.values[field.name as keyof IDemandeAbsence]}
        onChange={(name, value) => {
          handleTypeChange(name, value);
        }}
        error={
          formik.touched[field.name as keyof IDemandeAbsence]
            ? (formik.errors[field.name as keyof IDemandeAbsence] as string | undefined)
            : undefined
        }
        onBlur={formik.handleBlur}
        isReadOnly={isReadOnly}
      />
    );
  };

  const isFormValid = () => {
    const errors = formik.errors;
    const touched = formik.touched;
    const values = formik.values;

    return formik.isValid;
  };

  const renderActionButtons = () => (
    <ConditionalComponent isValid={!isReadOnly}>
      <ActionButtons
        onSave={() => {
          isFormValid();
          formik.handleSubmit();
        }}
        onCancel={() => onClose(false)}
        mode={mode}
      />
    </ConditionalComponent>
  );

  const handleExportSingle = async () => {
    try {
      if (!absence || !absence.id) {
        setSnackbar({
          open: true,
          message: 'Aucune absence à exporter',
          severity: 'error'
        });
        return;
      }

      // Create CSV data for the single absence
      const csvHeaders = [
        'ID',
        'Numéro de demande',
        'Type de demande',
        'Type de congé/absence', 
        'Date de début',
        'Date de fin',
        'Nombre de jours',
        'Statut',
        'Motif',
        'Date de soumission',
        'Date de traitement'
      ];

      const csvRow = [
        absence.id,
        absence.requestNumber || `REQ-${absence.id}`,
        absence.requestType,
        absence.requestType === 'Congé' ? absence.leaveType : absence.absenceType,
        absence.startDate,
        absence.endDate,
        absence.daysCount.toString(),
        absence.status,
        absence.reason || '',
        absence.submissionDate || absence.dateSubmission,
        absence.processDate || absence.dateTraitement || ''
      ];

      // Convert to CSV format
      const csvContent = [
        csvHeaders.join(','),
        csvRow.map(cell => `"${cell}"`).join(',')
      ].join('\n');

      // Create and download the file
      const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
      const url = window.URL.createObjectURL(blob);
      const link = document.createElement('a');
      link.href = url;
      link.download = `absence_${absence.id}_${new Date().toISOString().split('T')[0]}.csv`;
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      window.URL.revokeObjectURL(url);

      setSnackbar({
        open: true,
        message: 'Export de l\'absence terminé avec succès',
        severity: 'success'
      });

    } catch (error: any) {
      setSnackbar({
        open: true,
        message: error.message || 'Erreur lors de l\'export',
        severity: 'error'
      });
    }
  };

  return (
    <LocalizationProvider dateAdapter={AdapterDateFns} adapterLocale={fr}>
      <FormContainer titre={getFormTitle()}>
        <ConditionalComponent isValid={isReadOnly}>
          <EditExportButtons
            onEdit={() => onEdit(formik.values)}
            onExport={mode === 'view' && absence?.id ? handleExportSingle : undefined}
            tooltipTitle="l'absence"
          />
        </ConditionalComponent>

        <form onSubmit={formik.handleSubmit}>
          <Grid container spacing={4}>
            <Grid item xs={12} md={4}>
              {renderField(absenceFormFields.find(f => f.name === 'requestType')!)}
            </Grid>
            <ConditionalComponent isValid={formik.values.requestType === 'Absence'}
              defaultComponent={
                <Grid item xs={12} md={8}>
                  {renderField(absenceFormFields.find(f => f.name === 'leaveType')!)}
                </Grid>
              }
            >
              <Grid item xs={12} md={8}>
                {renderField(absenceFormFields.find(f => f.name === 'absenceType')!)}
              </Grid>
            </ConditionalComponent>

            <Grid item xs={12} md={4}>
              {renderField(absenceFormFields.find(f => f.name === 'startDate')!)}
            </Grid>
            <Grid item xs={12} md={4}>
              {renderField(absenceFormFields.find(f => f.name === 'endDate')!)}
            </Grid>
            <Grid item xs={12} md={4}>
              {renderField(absenceFormFields.find(f => f.name === 'daysCount')!)}
            </Grid>
            <Grid item xs={12} md={4}>
              {renderField(absenceFormFields.find(f => f.name === 'status')!)}
            </Grid>
            <Grid item xs={12} md={8}>
              {renderField(absenceFormFields.find(f => f.name === 'reason')!)}
            </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}>
              {renderActionButtons()}
            </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'],
                  '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>
  );
}
