import React, { useEffect, useState } from 'react';
import FormField from '@/shared/components/form/form-field';
import { FormFieldType, ModeType } from '@/shared/types/common';
import { IAgent, CollaboratorStatus, WorkSchedule } from '@/shared/types/client';
import WorkScheduleForm from './WorkScheduleForm';

interface AgentFieldProps {
  field: FormFieldType<IAgent>;
  formik: any;
  mode: ModeType;
  isReadOnly: boolean;
  permissions: { label: string; value: string }[];
  handleFormFieldChange: (name: string, value: any) => void;
}
const editableInCopy = [
    'lastName',
    'firstName',
    'phoneNumber',
    'email',
    'agentIdentifier',
    'personalEmail',
    'socialSecurityNumber',
    'password',
  ];
  
type TransformerFunction = (
  formik: any,
  mode: ModeType,
  permissions: any[],
  setValue?: (value: any) => void,
  currentValue?: any
) => any;
export const getInitialValues = (agent: IAgent, mode: ModeType): IAgent => {
    if (mode !== 'copy') {
      // Pour les modes add, edit, view, on s'assure qu'il y a un emploi du temps par défaut
      const defaultSchedule = {
        id: agent.schedule?.id,
        collaboratorId: agent.id,
        weeklySchedule: {
          monday: { isWorkingDay: true, startTime: null, endTime: null, breakStartTime: null, breakEndTime: null, notes: '' },
          tuesday: { isWorkingDay: true, startTime: null, endTime: null, breakStartTime: null, breakEndTime: null, notes: '' },
          wednesday: { isWorkingDay: true, startTime: null, endTime: null, breakStartTime: null, breakEndTime: null, notes: '' },
          thursday: { isWorkingDay: true, startTime: null, endTime: null, breakStartTime: null, breakEndTime: null, notes: '' },
          friday: { isWorkingDay: true, startTime: null, endTime: null, breakStartTime: null, breakEndTime: null, notes: '' },
          saturday: { isWorkingDay: false, startTime: null, endTime: null, breakStartTime: null, breakEndTime: null, notes: '' },
          sunday: { isWorkingDay: false, startTime: null, endTime: null, breakStartTime: null, breakEndTime: null, notes: '' },
        },
        createdAt: agent.schedule?.createdAt,
        updatedAt: agent.schedule?.updatedAt,
      };

      return {
        ...agent,
        schedule: agent.schedule || defaultSchedule,
      };
    }
  
    const clearedFields = editableInCopy.reduce((acc, key) => {
      acc[key as keyof IAgent] = '' as any;
      return acc;
    }, {} as Partial<IAgent>);
  
    return {
      ...agent,
      ...clearedFields,
      id: '0',
      schedule: agent.schedule, // Garder l'emploi du temps en mode copy
    };
  };
  
const fieldTransformers: Record<string, TransformerFunction> = {
    
  permissions: (formik, mode, permissions) =>
    permissions.map((p: any) => p.value).join(', '),

  agencyName: (formik, mode, permissions) =>
    ['view', 'edit', 'copy'].includes(mode)
      ? String(formik.values['agencyId'] || '')
      : formik.values['agencyName'] || '',

  departmentName: (formik, mode, permissions) =>
    ['view', 'edit', 'copy'].includes(mode)
      ? String(formik.values['departmentId'] || '')
      : formik.values['departmentName'] || '',

  teams: (formik, mode, permissions) =>
    formik.values.teams?.map((t: { id: number }) => String(t.id)) || [],

  roles: (formik, mode, permissions) =>
    ['view', 'edit', 'copy', 'add'].includes(mode)
      ? String(formik.values.roles?.[0]?.id || '')
      : formik.values['roles'] || '',

  collaboratorStatus: (formik, mode, permissions) =>
    ['view', 'copy', 'edit'].includes(mode)
      ? CollaboratorStatus[formik.values.collaboratorStatus as keyof typeof CollaboratorStatus]
      : formik.values.collaboratorStatus,

  mapAdresse: (formik, mode, permissions, setValue, currentValue) => {
    const values = formik?.values || {};
    const formikMapAdresse = values.mapAdresse;

    if (formikMapAdresse && typeof formikMapAdresse === 'object') {
      return formikMapAdresse.formattedAddress || '';
    }

    if (values.addresses?.length > 0) {
      const addr = values.addresses[0];
      const addressData = {
        address: addr.additionalAddress || '',
        lat: addr.latitude || 0,
        lng: addr.longitude || 0,
        formattedAddress: addr.additionalAddress || '',
        city: addr.city || '',
        postalCode: addr.zipCode || '',
        country: addr.country || '',
      };

      if (typeof formik.setFieldValue === 'function') {
        formik.setFieldValue('mapAdresse', addressData);
      }

      return addressData.formattedAddress || '';
    }

    return '';
  },

  password: (formik, mode, permissions) =>
    mode === 'view' ? '**********' : formik.values['password'] || '',
  
};

const AgentField: React.FC<AgentFieldProps> = ({
  field,
  formik,
  mode,
  isReadOnly,
  permissions,
  handleFormFieldChange,
}) => {
  const [value, setValue] = useState<any>(formik.values?.[field.name]);

  useEffect(() => {
    const formikValue = formik.values?.[field.name];
    const transformer = fieldTransformers[field.name];

    let newValue = transformer
      ? transformer(formik, mode, permissions, setValue, value)
      : formikValue;

    if (mode === 'copy' && editableInCopy.includes(field.name)) {
      if (formikValue !== '' && formikValue !== value) {
        newValue = formikValue;
      }
    }

    setValue(newValue);
  }, [mode, permissions, formik.values[field.name]]);

 

  const error = (() => {
    if (field.name === 'mapAdresse') {
      return formik.touched?.mapAdresse?.formattedAddress && formik.errors?.mapAdresse?.formattedAddress
        ? formik.errors.mapAdresse.formattedAddress
        : undefined;
    }

    const meta = formik.getFieldMeta(field.name as keyof IAgent);
    return meta.touched && meta.error ? meta.error : undefined;
  })();

  const fieldIsReadOnly =
    isReadOnly ||
    (['copy', 'view'].includes(mode) && !editableInCopy.includes(field.name)) ||
    (mode === 'edit' && field.name === 'email');

  if (field.name === 'schedule') {
    return (
      <WorkScheduleForm
        schedule={formik.values.schedule}
        mode={mode}
        isReadOnly={isReadOnly}
        onChange={(schedule: WorkSchedule) => {
          handleFormFieldChange('schedule', schedule);
        }}
        errors={formik.errors}
        touched={formik.touched}
        onBlur={(fieldPath: string) => {
          formik.setFieldTouched(fieldPath, true);
          formik.validateField(fieldPath);
        }}
      />
    );
  }

  return (
    <FormField
      field={field}
      value={value}
      onChange={(name, val) => {
        if (name === 'mapAdresse') {
          const addressObject = typeof val === 'object' && val.formattedAddress
            ? val
            : {
                address: val,
                formattedAddress: val,
                lat: 0,
                lng: 0,
                placeId: '',
                city: '',
                postalCode: '',
                country: '',
              };

          setValue(addressObject.formattedAddress);
          handleFormFieldChange(name, addressObject);
        } else {
          setValue(val);
          handleFormFieldChange(name, val);
        }
      }}
      onBlur={formik.handleBlur}
      error={error}
      isReadOnly={fieldIsReadOnly || field.name === 'permissions'}
      formData={formik.values}
    />
  );
};

export default AgentField;
