'use client';

import React, { useRef, useEffect, useState } from 'react';
import { Grid, IconButton, InputAdornment } from '@mui/material';
import { useFormik } from 'formik';
import { useResponsive } from '@/hooks';
import { enqueueSnackbar } from 'notistack';

import { TableColumn, type ModeType } from '@/shared/types/common';
import { IRHAbsence, CreateAbsenceDto, UserOption } from '@/shared/types/absence-rh';
import FormContainer from '@/layouts/form/form-container';
import ActionButtons from '@/shared/components/form/buttons-action';
import EditExportButtons from '@/shared/components/form/edit-export-buttons';
import FormField from '@/shared/components/form/form-field';
import ConditionalComponent from '@/shared/components/table/ConditionalComponent';
import { createFormFieldsRHAbsence } from '../utils/form-fields-rh-absence';
import { absenceSchema } from '../utils/absence-schema';
import { useRHAbsenceStore } from '@/shared/api/stores/hr-service/rhAbsence';
import { StyledTextField } from '@/shared/theme/css';
import FontAwesome from '@/shared/components/fontawesome';
import CustomTooltip from '@/shared/components/tooltips/tooltip-custom';
import { faPaperclip } from '@fortawesome/free-solid-svg-icons';

interface RHAbsenceFormProps {
  absence: IRHAbsence;
  mode: ModeType;
  onSave: (updatedAbsence: IRHAbsence) => void;
  onEdit: (updatedAbsence: IRHAbsence) => void;
  onClose: (forceClose: boolean) => void;
  isTraiteAbsence?: boolean;
  updateTabContent?: (tabId: string, content: IRHAbsence) => void;
  tabId?: string;
}

export default function AbsenceForm({
  absence,
  mode,
  onSave,
  onClose,
  onEdit,
  isTraiteAbsence,
  updateTabContent,
  tabId,
}: RHAbsenceFormProps) {
  const isBetweenSmAndLg = useResponsive('between', 'sm', 'lg');
  const fileInputRef = useRef<HTMLInputElement>(null);
  
  // Add state to store the actual file object
  const [selectedFile, setSelectedFile] = useState<File | null>(null);

  const isReadOnly = mode === 'view';
  const isEditing = mode === 'edit';

  // Get store methods and user data from RH absence store
  const {
    createAbsence,
    updateAbsence,
    allUsers,
    getCollaboratorsForAuthorization,
    usersLoading,
    fetchAllUsers,
    // Export functionality
    exportLoading,
    startExport,
    downloadExport,
  } = useRHAbsenceStore();

  const collaborators = getCollaboratorsForAuthorization();

  // Initialize users data if not already loaded
  useEffect(() => {
    if (allUsers.length === 0 && !usersLoading) {
      fetchAllUsers();
    }
  }, [allUsers.length, usersLoading, fetchAllUsers]);

  const formik = useFormik<IRHAbsence>({
    initialValues: absence,
    validationSchema: absenceSchema,
    enableReinitialize: true,
    onSubmit: async (values) => {
      try {
        // Map form values to backend DTO format - only include fields the backend expects
        const createDto = {
          userId: Number(values.userId),
          absenceType: values.typeAbsence || '',
          startDate: values.dateDebut || values.startDate,
          endDate: values.dateFin || values.endDate,
          numberOfDays: calculateDays(values.dateDebut || values.startDate, values.dateFin || values.endDate),
          justificationFileUrl: values.justificatif || null,
          authorizedBy: values.autorisePar || values.authorizedBy || '',
          validatedBy: values.validerPar || values.validatedBy || '',
          hoursCount: Number(values.nbrHeures) || values.numberOfDays * 8,
          receivingMethod: values.modeReception || values.receivingMethod || 'APPLICATION',
          state: 'Unprocessed',
          observations: values.observations || null,
          comment: values.comment || null,
          requestType: 'ABSENCE',
          affectedToTrip: false,
          tripsIds: []
        };

        console.log('Sending absence request:', createDto); // Debug log

        if (isEditing && absence.id) {
          await updateAbsence(Number(absence.id), createDto);
        } else {
          await createAbsence(createDto, selectedFile);
        }

        onSave(values);
        onClose(true);
        enqueueSnackbar('Absence créée avec succès', { variant: 'success' });
      } catch (error) {
        console.error('Form submission error:', error);
        enqueueSnackbar('Erreur lors de la création de l\'absence', { variant: 'error' });
      }
    },
  });

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

  const handleIconClick = () => {
    if (fileInputRef.current) {
      fileInputRef.current.click();
    }
  };

  const handleFileUpload = (event: React.ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0];
    if (file) {
      // Update both fields to keep them in sync
      formik.setFieldValue('justificationFileUrl', file.name);
      formik.setFieldValue('justificatif', file.name);
      setSelectedFile(file);
    }
  };

  const renderField = (field: any) => {
    // Skip fields that shouldn't be shown based on current form values
    if (field.showWhen && !field.showWhen(formik.values)) {
      return null;
    }

    if (field.name === "justificatif") {
      const fieldName = field.name as keyof IRHAbsence;
      const error = formik.touched[fieldName] && formik.errors[fieldName];
      
      // Get the value from justificationFileUrl
      const value = formik.values.justificationFileUrl || "";
      
      // Only show file icon if it's an actual file URL
      const isFileUrl = typeof value === 'string' && value.toLowerCase().startsWith('http');

      return (
        <StyledTextField
          isSmallScreen={isBetweenSmAndLg}
          fullWidth
          name={field.name}
          InputLabelProps={{
            shrink: true,
          }}
          value={value}
          onChange={(e) => {
            // Update both fields to keep them in sync
            formik.setFieldValue('justificationFileUrl', e.target.value);
            formik.setFieldValue(fieldName, e.target.value);
          }}
          onBlur={formik.handleBlur}
          error={!!error}
          helperText={error ? String(formik.errors[fieldName]) : undefined}
          label={field.label}
          placeholder={field.placeholder}
          sx={{
            ...(isReadOnly && {
              '& .MuiInputBase-root': {
                backgroundColor: '#f5f5f5',
                cursor: 'not-allowed',
              },
              '& .MuiInputBase-input': {
                cursor: 'not-allowed',
                color: 'text.disabled',
              }
            })
          }}
          InputProps={{
            readOnly: isReadOnly,
            endAdornment: isFileUrl ? (
              <InputAdornment position="end" >
                <CustomTooltip title="Importer la justification" arrow>
                  <IconButton onClick={handleIconClick} disabled={isReadOnly}>
                    <FontAwesome
                      icon={faPaperclip}
                      sx={{
                        color: isReadOnly ? 'text.disabled' : "primary.main",
                        width: isBetweenSmAndLg ? 16 : 18,
                      }}
                    />
                  </IconButton>
                </CustomTooltip>
              </InputAdornment>
            ) : null,
          }}
        />
      );
    }

    const fieldName = field.name as keyof IRHAbsence;
    
    // Special handling for user selection field
    if (field.name === 'nomChauffeur') {
      return (
        <FormField
          field={field}
          value={formik.values[fieldName]}
          onChange={(name, value) => {
            // Set the selected user name
            formik.setFieldValue(name, value);
            
            // Auto-update related fields when user is selected
            if (value && allUsers.length > 0) {
              const selectedUser = allUsers.find(user => user.label === value);
              if (selectedUser) {
                // Set userId, type, and department automatically
                formik.setFieldValue('userId', Number(selectedUser.id));
                
                const userType = selectedUser.type === 'CHAUFFEUR' ? 'chauffeur' : 'sédentaire';
                formik.setFieldValue('type', userType);
                
                if (selectedUser.departmentName) {
                  formik.setFieldValue('departement', selectedUser.departmentName);
                }
              }
            }
          }}
          error={
            formik.touched[fieldName]
              ? (formik.errors[fieldName] as string | undefined)
              : undefined
          }
          onBlur={formik.handleBlur}
          isReadOnly={field.disabled || isReadOnly}
        />
      );
    }
    
    return (
      <FormField
        field={field}
        value={formik.values[fieldName]}
        onChange={(name, value) => formik.setFieldValue(name, value)}
        error={
          formik.touched[fieldName]
            ? (formik.errors[fieldName] as string | undefined)
            : undefined
        }
        onBlur={formik.handleBlur}
        isReadOnly={field.disabled || isReadOnly}
      />
    );
  };

  // Helper function to calculate number of days
  const calculateDays = (startDate: string, endDate: string): number => {
    if (!startDate || !endDate) return 1;
    const start = new Date(startDate);
    const end = new Date(endDate);
    const diffTime = Math.abs(end.getTime() - start.getTime());
    const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
    return diffDays > 0 ? diffDays : 1;
  };

  // Get form fields with user data
  const formFields = createFormFieldsRHAbsence(allUsers, collaborators);

  // Export handler for single absence
  const handleExportSingle = async () => {
    try {


      // Create filters for just this absence
      const exportFilters = {
        absenceNumber: absence.numeroEnregistrement || `ABS-${absence.id}`,
        page: 0,
        size: 1,
        requestType: 'ABSENCE'
      };

      const result = await startExport(exportFilters);

      if (result.success && result.exportPath) {
        enqueueSnackbar(result.message, { variant: 'success' });

        // Auto-download the file
        setTimeout(async () => {
          try {
            const downloadResult = await downloadExport(result.exportPath!);
            if (downloadResult.success) {
              enqueueSnackbar(downloadResult.message, { variant: 'success' });
            } else {
              enqueueSnackbar(downloadResult.message, { variant: 'error' });
            }
          } catch (error) {
            console.error('Download failed:', error);
            enqueueSnackbar('Échec du téléchargement automatique', { variant: 'error' });
          }
        }, 2000);
      } else {
        enqueueSnackbar(result.message, { variant: 'error' });
      }
    } catch (error) {
      console.error('Export failed:', error);
      enqueueSnackbar('Échec de l\'export', { variant: 'error' });
    }
  };

  if (usersLoading) {
    return <div>Chargement des utilisateurs...</div>;
  }

  return (
    <FormContainer titre="Fiche Absence">
      <ConditionalComponent isValid={isReadOnly}>
        <EditExportButtons
          onEdit={isTraiteAbsence ? undefined : () => onEdit(absence)}
          onExport={handleExportSingle}
          dataRow={absence}
        />
      </ConditionalComponent>

      <form onSubmit={formik.handleSubmit}>
        <Grid container spacing={4}>
          {formFields.map((field) => (
            <Grid item xs={12} sm={4} key={field.name}>
              {renderField(field)}
            </Grid>
          ))}
          <input type="file" ref={fileInputRef} style={{ display: "none" }} onChange={handleFileUpload} />
          <Grid item xs={12}>
            <ConditionalComponent isValid={mode !== "view"}>
              <ActionButtons
                onSave={() => {
                  formik.validateForm().then((errors) => {
                    formik.submitForm();
                  });
                }}
                onCancel={() => onClose(false)}
                mode={mode}
              />
            </ConditionalComponent>
          </Grid>
        </Grid>
      </form>
    </FormContainer>
  );
} 
