'use client';

import React, { useEffect, useRef, useState } from 'react';
import { Box, Stepper, Step, StepLabel, Grid, Divider } from '@mui/material';
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { fr } from 'date-fns/locale';
import { useFormik } from 'formik';
import { IRole } from '@/shared/types/role';
import { ScrollBox } from '@/shared/theme/css';
import FormField from '@/shared/components/form/form-field';
import ActionButtons from '@/shared/components/form/buttons-action';
import EditExportButtons from '@/shared/components/form/edit-export-buttons';
import ConditionalComponent from '@/shared/components/table/ConditionalComponent';
import ConnectionHistoryTable from '../components/connection-history-table';
import {
  personalInfoFields,
  professionalInfoFields,
  rolePermissionFields,
} from '../utils/form-fields-agent';
import { agentSchema } from '../utils/agent-schema';
import {
  AddressDTO,
  CollaboratorStatus,
  ContractType,
  IAgent,
  IBaseEntity,
  UserConnectionHistoryDto,
  UserStatus,
} from '@/shared/types/client';
import { FormFieldType, ModeType } from '@/shared/types/common';
import { useAgencyStore } from '@/shared/api/stores/agencyStore';
import { useInfrastructureStore } from '@/shared/api/stores/admin-service/infrastructureStore';
import { useTeamStore } from '@/shared/api/stores/teamStore';
import { useRoleStore } from '@/shared/api/stores/roleStore';
import { faUserShield, faListCheck } from '@fortawesome/free-solid-svg-icons';
import AgentStepContent from './AgentStepContent';
import { useAuthStore } from '@/shared/api/stores/authStore';
import { getInitialValues } from './AgentField';

const steps = ['Informations personnelles', 'Informations professionnelles', 'Rôles & permissions'];

interface AgentFormProps {
  agent: IAgent;
  mode: ModeType;
  onSave: (updatedAgent: IAgent) => void;
  onEdit: (agent: IAgent) => void;
  onClose: (forceClose: boolean) => void;
  updateTabContent: (tabId: string, newContent: IAgent) => void;
  tabId: string;
}

export default function AgentForm({
  agent,
  mode,
  onSave,
  onClose,
  onEdit,
  updateTabContent,
  tabId,
}: AgentFormProps) {
  const [activeStep, setActiveStep] = useState(0);
  const isReadOnly = mode === 'view';
  const { agenciesName, loading, error, fetchAgenciesName } = useAgencyStore();
  const { minimalTeams, getMinimalTeams } = useTeamStore();
  const { roles, fetchRoles, getPermissionsByRoleName } = useRoleStore();
  const [departementOptions, setDepartementOptions] = useState<{ label: string; value: string }[]>(
    []
  );
  const [teamsOptions, setTeamsOptions] = useState<{ label: string; value: string }[]>([]);
  const [agencyOptions, setAgencyOptions] = useState<{ label: string; value: string }[]>([]);
  const [roleOptions, setRoleOptions] = useState<{ label: string; value: string }[]>([]);
  const [permissions, setPermissions] = useState<{ label: string; value: string }[]>([]);
  const {
    departmentNamesByAgencyId,
    fetchDepartmentNamesByAgencyId
  } = useInfrastructureStore();

  useEffect(() => {
    fetchAgenciesName();
    getMinimalTeams();
    fetchRoles();
  }, []);



  useEffect(() => {
    if (agenciesName.length > 0) {
      const options = agenciesName.map((agency) => ({
        label: agency.name,
        value: agency.id.toString(),
      }));
      setAgencyOptions(options);
    }
  }, [agenciesName]);

  useEffect(() => {
    if (roles.length > 0) {
      const options = roles
        .filter(role => !['COLLABORATOR', 'PASSENGER', 'CLIENT_DO', 'DRIVER'].includes(role.name))
        .map((role) => ({
          label: role.name,
          value: role.id.toString(),
        }));
      setRoleOptions(options);
    }
  }, [roles]);




  useEffect(() => {
    if (minimalTeams.length > 0) {
      const options = minimalTeams.map((teams) => ({
        label: teams.name,
        value: teams.id.toString(),
      }));
      setTeamsOptions(options);
    }
  }, [minimalTeams]);

  const formik = useFormik<IAgent>({
    initialValues: getInitialValues(agent, mode),
    validationSchema: agentSchema(mode),
    validateOnBlur: true,
    validateOnChange: false,
    onSubmit: (values) => {
      onSave(values);
      onClose(true);
    },
  });

  const previousAgencyIdRef = useRef<number | null>(null);

  useEffect(() => {
    const agencyId = Number(mode === 'add' ? formik.values.agencyName : formik.values.agencyId);

    if (agencyId) {
      fetchDepartmentNamesByAgencyId(agencyId);
    } else {
      setDepartementOptions([]);
    }

    if (
      previousAgencyIdRef.current !== null &&
      previousAgencyIdRef.current !== agencyId
    ) {
      formik.setFieldValue('departmentId', 0);
      formik.setFieldValue('departmentName', '');
    }

    previousAgencyIdRef.current = agencyId;
  }, [mode, formik.values.agencyName, formik.values.agencyId]);


  useEffect(() => {
    if (departmentNamesByAgencyId.length > 0) {
      const options = departmentNamesByAgencyId.map((dept) => ({
        label: dept.name,
        value: dept.id.toString(),
      }));
      setDepartementOptions(options);
    }
  }, [departmentNamesByAgencyId]);

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

  const handleNext = async () => {
    const fields =
      activeStep === 0
        ? personalInfoFields
        : activeStep === 1
          ? professionalInfoFields(agencyOptions, departementOptions, teamsOptions)
          : rolePermissionFields(roleOptions);

    const errors = await formik.validateForm();

    const hasErrors = fields.some((f: FormFieldType<IAgent>) => {
      if (f.name === 'mapAdresse') {
        return !!(errors.mapAdresse as any)?.formattedAddress;
      }
      return Boolean((errors as any)[f.name]);
    });

    if (!hasErrors) {
      setActiveStep((s) => s + 1);
    } else {
      const touchedFields: any = {};

      fields.forEach((f: FormFieldType<IAgent>) => {
        if (f.name === 'mapAdresse') {
          touchedFields.mapAdresse = {
            formattedAddress: true,
          };
        } else {
          touchedFields[f.name] = true;
        }
      });

      formik.setTouched(touchedFields, true);
    }
  };


  const handleBack = () => setActiveStep((s) => s - 1);

  useEffect(() => {
    if ((mode === 'view' || mode === 'copy' || mode === 'edit') && formik.values.roles?.[0]?.name) {
      const roleName = formik.values.roles[0].name;
      const fetchPermissions = async () => {
        const fetchedPermissions = await getPermissionsByRoleName(roleName);
        setPermissions(fetchedPermissions.map((perm) => ({ label: perm, value: perm })));
      };
      fetchPermissions();
    }
  }, [mode, formik.values.roles]);


  const handleFormFieldChange = async (name: string, value: string | string[] | number[]) => {

    if (name === 'roles') {
      const selectedRole = roleOptions.find((role) => role.value === value);
      if (selectedRole) {
        formik.setFieldValue('roles', [
          {
            id: selectedRole.value,
            name: selectedRole.label,
            description: '',
          },
        ]);

        const fetchedPermissions = await getPermissionsByRoleName(selectedRole.label);
        setPermissions(fetchedPermissions.map((perm) => ({ label: perm, value: perm })));
      }
    } else if (name === 'teams') {
      const parsed = Array.isArray(value)
        ? value.map((v) => {
          const team = teamsOptions.find((option) => option.value === v);
          return { id: Number(v), name: team?.label || '' };
        })
        : [];

      formik.setFieldValue('teams', parsed);

    }
    else if (name === 'agencyName' && mode !== 'add') {
      formik.setFieldValue('agencyId', value);
    } else if (name === 'departmentName' && mode !== 'add') {
      formik.setFieldValue('departmentId', value);
      formik.setFieldValue('departmentName', value);

    }

    else {
      formik.setFieldValue(name, value);
    }
  };

  return (
    <LocalizationProvider dateAdapter={AdapterDateFns} adapterLocale={fr}>
      <ScrollBox>
        <Box sx={{ p: 3, backgroundColor: 'background.paper', borderRadius: 1 }}>
          {isReadOnly && (
            <EditExportButtons
              onEdit={() => onEdit(agent)}
              tooltipTitle="l'agent"
            />
          )}

          <Box sx={{ mt: isReadOnly ? 3 : 0 }}>
            <Stepper activeStep={activeStep} sx={{ mb: 4 }}>
              {steps.map((label) => (
                <Step key={label}>
                  <StepLabel>{label}</StepLabel>
                </Step>
              ))}
            </Stepper>

            <Box component="form" onSubmit={formik.handleSubmit}>
              <AgentStepContent
                step={activeStep}
                formik={formik}
                agencyOptions={agencyOptions}
                departementOptions={departementOptions}
                teamsOptions={teamsOptions}
                roleOptions={roleOptions}
                permissions={permissions}
                isReadOnly={isReadOnly}
                mode={mode}
                handleFormFieldChange={handleFormFieldChange}
              />

              <Box sx={{ mt: 3, display: 'flex', justifyContent: 'flex-end' }}>
                {!isReadOnly ? (
                  <ActionButtons
                    onSave={formik.handleSubmit}
                    onNext={activeStep < steps.length - 1 ? handleNext : undefined}
                    onBack={activeStep > 0 ? handleBack : undefined}
                    onCancel={() => onClose(false)}
                    mode={mode}
                  />
                ) : (
                  <ActionButtons
                    onSave={formik.handleSubmit}
                    onNext={activeStep < steps.length - 1 ? handleNext : undefined}
                    onBack={activeStep > 0 ? handleBack : undefined}
                    onCancel={() => onClose(false)}
                    mode="view"
                  />
                )}
              </Box>
            </Box>
          </Box>
        </Box>

        {agent.id && (
          <>
            <Divider sx={{ my: 4 }} />
            <ConnectionHistoryTable userId={agent.id} />
          </>
        )}

      </ScrollBox>
    </LocalizationProvider>
  );
}
