import dayjs from 'dayjs';
import { z as zod } from 'zod';
import { useForm, Controller } from 'react-hook-form';
import React, { useMemo, useState, useEffect } from 'react';

import EditIcon from '@mui/icons-material/Edit';
import SaveIcon from '@mui/icons-material/Save';
import CancelIcon from '@mui/icons-material/Cancel';
import Autocomplete from '@mui/material/Autocomplete';
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
import { Box, Card, Grid, Button, TextField, Typography } from '@mui/material';

import { _mock } from 'src/shared/_mock';

import { Label } from 'src/shared/components/label';
import { toast } from 'src/shared/components/snackbar';
import { Form, Field } from 'src/shared/components/hook-form';
import ConditionalComponent from 'src/shared/components/ConditionalComponent/ConditionalComponent';

import { useRoleStore } from 'src/shared/api/stores/roleStore';
import { useUserStore } from 'src/shared/api/stores/userStore';
import { BaseUser, IChild } from 'src/contexts/types/user';

export const UserManagementSchema = zod.object({
  firstName: zod.string().min(1, { message: 'Prénom est requis!' }),
  lastName: zod.string().min(1, { message: 'Nom est requis!' }),
  email: zod
    .string()
    .min(1, { message: 'Email est requis!' })
    .email({ message: 'Email doit être une adresse valide!' }),
  phoneNumber: zod.string().min(1, { message: 'Numéro de téléphone est requis!' }),
  birthDate: zod.string().min(1, { message: 'La date de naissance est requise.' }),
  // Adresse primaire
  primaryAddress: zod.string().min(1, { message: 'Adresse primaire est requise!' }),
  primaryCountry: zod.string().min(1, { message: 'Pays primaire est requis!' }),
  primaryState: zod.string().optional(),
  primaryCity: zod.string().min(1, { message: 'Ville primaire est requise!' }),
  primaryZipCode: zod.string().min(1, { message: 'Code postal primaire est requis!' }),
  // Adresse secondaire (optionnelle)
  secondaryAddress: zod.string().optional(),
  secondaryCountry: zod.string().optional(),
  secondaryState: zod.string().optional(),
  secondaryCity: zod.string().optional(),
  secondaryZipCode: zod.string().optional(),
  status: zod.string(),
  isVerified: zod.boolean(),
  parentId: zod.string().optional(),
  daily_question_limit: zod.number().optional(),
});

const createDefaultValues = (currentUser?: BaseUser) => {
  const baseValues = {
    status: '',
    firstName: '',
    lastName: '',
    email: '',
    phoneNumber: '',
    birthDate: '',
    // Adresse principale
    primaryCountry: '',
    primaryCity: '',
    primaryAddress: '',
    primaryZipCode: '',
    primaryState: '',
    // Adresse secondaire
    secondaryCountry: '',
    secondaryCity: '',
    secondaryAddress: '',
    secondaryZipCode: '',
    secondaryState: '',
    userType: '',
    parentId: '',
    daily_question_limit: 12,
    isVerified: false,
  };

  if (!currentUser) {
    return baseValues;
  }

  // Mise à jour avec les données utilisateur
  const values = {
    ...baseValues,
    status: currentUser?.status || '',
    firstName: currentUser?.firstName || '',
    lastName: currentUser?.lastName || '',
    email: currentUser?.email || '',
    phoneNumber: currentUser?.phoneNumber || '',
    birthDate: currentUser?.birthDate,
    // Adresse principale
    primaryCountry: currentUser?.primaryAddress?.country || '',
    primaryCity: currentUser?.primaryAddress?.city || '',
    primaryAddress: currentUser?.primaryAddress?.fullAddress || '',
    primaryZipCode: currentUser?.primaryAddress?.zipCode || '',
    primaryState: currentUser?.primaryAddress?.complimentaryAddress || '',
    // Adresse secondaire
    secondaryCountry: currentUser?.secondaryAddress?.country || '',
    secondaryCity: currentUser?.secondaryAddress?.city || '',
    secondaryAddress: currentUser?.secondaryAddress?.fullAddress || '',
    secondaryZipCode: currentUser?.secondaryAddress?.zipCode || '',
    secondaryState: currentUser?.secondaryAddress?.complimentaryAddress || '',
    userType: currentUser?.userType || '',
    isVerified: false,
  };

  // Propriétés spécifiques aux enfants
  if (currentUser?.userType === 'CHILD') {
    const childUser = currentUser as IChild;
    values.parentId = childUser.parent?.id || '';
    values.daily_question_limit = 12;
  }

  return values;
};

export type UserManagementSchemaType = zod.infer<typeof UserManagementSchema>;

interface PersonalInfoTabProps {
  currentUser?: BaseUser;
}

const PersonalInfoTab: React.FC<PersonalInfoTabProps> = ({ currentUser }) => {
  const [isEditing, setIsEditing] = useState(false);

  const { loading: roleLoading } = useRoleStore();
  const {
    getParents,
    loading: isLoading,
    updateAdmin,
    updateParent,
    updateChild,
    parents,
  } = useUserStore();

  const defaultValues = useMemo(() => createDefaultValues(currentUser), [currentUser]);

  const methods = useForm<UserManagementSchemaType>({
    mode: 'onSubmit',
    defaultValues,
  });

  const { control, watch, reset, handleSubmit } = methods;
  const values = watch();

  useEffect(() => {
    const fetchInitialData = async () => {
      try {
        if (!parents.length) {
          await getParents();
        }
      } catch (err) {
        console.error('Erreur lors du chargement des données:', err);
        toast.error('Erreur lors du chargement des données');
      }
    };

    fetchInitialData();
  }, [getParents, parents.length]);

  useEffect(() => {
    if (currentUser) {
      const newValues = createDefaultValues(currentUser);
      reset(newValues);
    }
  }, [currentUser, reset]);

  const onSubmit = handleSubmit(async (data) => {
    try {
      const baseUserData = {
        firstName: data.firstName,
        lastName: data.lastName,
        email: data.email,
        phoneNumber: data.phoneNumber,
        birthDate: data.birthDate,
        primaryAddress: {
          country: data.primaryCountry,
          city: data.primaryCity,
          fullAddress: data.primaryAddress,
          zipCode: data.primaryZipCode,
          complimentaryAddress: data.primaryState,
        },
        secondaryAddress: data.secondaryAddress
          ? {
              country: data.secondaryCountry,
              city: data.secondaryCity,
              fullAddress: data.secondaryAddress,
              zipCode: data.secondaryZipCode,
              complimentaryAddress: data.secondaryState,
            }
          : undefined,
      };

      if (currentUser?.userType === 'ADMIN') {
        if (currentUser?.id) {
          await updateAdmin(currentUser.id, { ...baseUserData });
        } else {
          console.error("L'identifiant de l'utilisateur est manquant.");
        }
      } else if (currentUser?.userType === 'PARENT') {
        if (currentUser?.id) {
          await updateParent(currentUser?.id, { ...baseUserData });
        } else {
          console.error("L'identifiant de l'utilisateur est manquant.");
        }
      } else if (currentUser?.userType === 'CHILD') {
        if (currentUser?.id) {
          const childData = {
            ...baseUserData,
            parentId: data.parentId || '',
          };
          await updateChild(currentUser?.id, childData);
        } else {
          console.error("L'identifiant de l'utilisateur est manquant.");
        }
      }
      toast.success('Informations mises à jour avec succès !');
      setIsEditing(false);
    } catch (error: any) {
      // Error handling is now managed by the store
      // Just show appropriate toast messages
      const errorMessage = error?.response?.data?.message;
      console.log(errorMessage);

      if (errorMessage === 'Email already exists') {
        toast.error('Cet email est déjà utilisé.');
      } else if (errorMessage === 'Missing data') {
        toast.error('Données manquantes.');
      } else {
        console.error("Erreur lors de la mise à jour de l'utilisateur:", error);
        toast.error('Erreur lors de la mise à jour!');
      }
    }
  });

  const getCurrentParent = () => {
    if (currentUser?.userType === 'CHILD') {
      const childUser = currentUser as IChild;
      return childUser.parent
        ? {
            id: childUser.parent.id,
            firstName: childUser.parent.firstName,
            lastName: childUser.parent.lastName,
            email: childUser.parent.email,
          }
        : null;
    }
    return null;
  };

  const handleEdit = () => {
    if (currentUser?.status !== 'ACTIVE') {
      toast.error('Impossible de modifier un utilisateur non activé');
      return;
    }
    setIsEditing(true);
  };

  const handleCancel = () => {
    setIsEditing(false);
    if (currentUser) {
      const originalValues = createDefaultValues(currentUser);
      reset(originalValues);
    }
  };

  return (
    <Form methods={methods} onSubmit={onSubmit}>
      <Grid container spacing={3} sx={{ alignItems: 'stretch' }}>
        <Grid xs={12} md={4}>
          <Card
            sx={{
              height: '100%',
              p: 3,
              display: 'flex',
              flexDirection: 'column',
              position: 'relative',
            }}
          >
            <ConditionalComponent isValid={!!currentUser}>
              <>
                <Label color="success" sx={{ position: 'absolute', top: 16, left: 16 }}>
                  {currentUser?.userType}
                </Label>
                <Label color="warning" sx={{ position: 'absolute', top: 16, right: 16 }}>
                  {currentUser?.status}
                </Label>
              </>
            </ConditionalComponent>

            <Box sx={{ mt: 4, mb: 2, textAlign: 'center' }}>
              {currentUser?.photo ? (
                <Box
                  component="img"
                  src={currentUser?.photo}
                  alt="Avatar"
                  sx={{ width: 120, height: 120, borderRadius: '50%', mx: 'auto' }}
                />
              ) : (
                <Box
                  component="img"
                  src={_mock.image.avatar(1)}
                  alt="Avatar"
                  sx={{ width: 120, height: 120, borderRadius: '50%', mx: 'auto' }}
                />
              )}
            </Box>

            <Box sx={{ textAlign: 'center' }}>
              <Typography variant="h6" gutterBottom>
                {currentUser?.firstName} {currentUser?.lastName}
              </Typography>
              <Typography variant="body2" color="text.secondary">
                {currentUser?.email}
              </Typography>
            </Box>
          </Card>
        </Grid>

        <Grid xs={12} md={8}>
          <Card
            sx={{
              height: '100%',
              p: 3,
              display: 'flex',
              flexDirection: 'column',
            }}
          >
            <Box sx={{ display: 'flex', justifyContent: 'space-between', mb: 3 }}>
              <Typography variant="h6">Informations personnelles</Typography>
              <ConditionalComponent
                isValid={!isEditing}
                defaultComponent={
                  <Box>
                    <Button
                      color="primary"
                      startIcon={<SaveIcon />}
                      variant="contained"
                      type="submit"
                      size="small"
                      sx={{ mr: 1 }}
                      disabled={isLoading}
                    >
                      {isLoading ? 'Sauvegarde...' : 'Sauvegarder'}
                    </Button>
                    <Button
                      startIcon={<CancelIcon />}
                      onClick={handleCancel}
                      variant="outlined"
                      color="error"
                      size="small"
                      disabled={isLoading}
                    >
                      Annuler
                    </Button>
                  </Box>
                }
              >
                <Button
                  startIcon={<EditIcon />}
                  onClick={handleEdit}
                  variant="outlined"
                  size="small"
                >
                  Modifier
                </Button>
              </ConditionalComponent>
            </Box>

            {/* Informations de base */}
            <Box sx={{ mb: 4 }}>
              <Typography variant="subtitle1" sx={{ mb: 2, fontWeight: 'bold' }}>
                Informations générales
              </Typography>
              <Box
                display="grid"
                rowGap={3}
                columnGap={2}
                gridTemplateColumns={{ xs: '1fr', sm: 'repeat(2, 1fr)' }}
              >
                <Field.Text name="firstName" label="Prénom" InputProps={{ readOnly: !isEditing }} />
                <Field.Text name="lastName" label="Nom" InputProps={{ readOnly: !isEditing }} />
                <Field.Text
                  name="email"
                  label="Adresse e-mail"
                  InputProps={{ readOnly: !isEditing }}
                />
                <Field.Phone name="phoneNumber" label="Numéro de téléphone" disabled={!isEditing} />
                <Controller
                  name="birthDate"
                  control={control}
                  render={({ field, fieldState }) => (
                    <DatePicker
                      label="Date de naissance"
                      value={field.value ? dayjs(field.value) : null}
                      onChange={(newValue) => {
                        field.onChange(newValue ? newValue.format('YYYY-MM-DD') : '');
                      }}
                      disabled={!isEditing}
                      format="DD/MM/YYYY"
                      slotProps={{
                        textField: {
                          fullWidth: true,
                          sx: { '& .MuiInputBase-root': { height: 48 } },
                          helperText: fieldState.error?.message,
                          error: !!fieldState.error,
                        },
                      }}
                    />
                  )}
                />
              </Box>
            </Box>

            {/* Adresse primaire */}
            <Box sx={{ mb: 4 }}>
              <Typography variant="subtitle1" sx={{ mb: 2, fontWeight: 'bold' }}>
                Adresse principale
              </Typography>
              <Box
                display="grid"
                rowGap={3}
                columnGap={2}
                gridTemplateColumns={{ xs: '1fr', sm: 'repeat(2, 1fr)' }}
              >
                <Field.CountrySelect
                  name="primaryCountry"
                  label="Pays"
                  placeholder="Choisissez un pays"
                  disabled={!isEditing}
                />
                <Field.Text
                  name="primaryCity"
                  label="Ville"
                  InputProps={{ readOnly: !isEditing }}
                />
                <Field.Text
                  name="primaryAddress"
                  label="Adresse"
                  InputProps={{ readOnly: !isEditing }}
                />
                <Field.Text
                  name="primaryZipCode"
                  label="Code postal"
                  InputProps={{ readOnly: !isEditing }}
                />
                <Field.Text
                  name="primaryState"
                  label="Complément d'adresse"
                  InputProps={{ readOnly: !isEditing }}
                  sx={{ gridColumn: { sm: 'span 2' } }}
                />
              </Box>
            </Box>

            {/* Adresse secondaire */}
            <Box sx={{ mb: 4 }}>
              <Typography variant="subtitle1" sx={{ mb: 2, fontWeight: 'bold' }}>
                Adresse secondaire (optionnelle)
              </Typography>
              <Box
                display="grid"
                rowGap={3}
                columnGap={2}
                gridTemplateColumns={{ xs: '1fr', sm: 'repeat(2, 1fr)' }}
              >
                <Field.CountrySelect
                  name="secondaryCountry"
                  label="Pays"
                  placeholder="Choisissez un pays"
                  disabled={!isEditing}
                />
                <Field.Text
                  name="secondaryCity"
                  label="Ville"
                  InputProps={{ readOnly: !isEditing }}
                />
                <Field.Text
                  name="secondaryAddress"
                  label="Adresse"
                  InputProps={{ readOnly: !isEditing }}
                />
                <Field.Text
                  name="secondaryZipCode"
                  label="Code postal"
                  InputProps={{ readOnly: !isEditing }}
                />
                <Field.Text
                  name="secondaryState"
                  label="Complément d'adresse"
                  InputProps={{ readOnly: !isEditing }}
                  sx={{ gridColumn: { sm: 'span 2' } }}
                />
              </Box>
            </Box>

            {/* Parent pour les enfants */}
            <ConditionalComponent isValid={currentUser?.userType === 'CHILD'}>
              <Box sx={{ mt: 3 }}>
                <Typography variant="subtitle1" sx={{ mb: 2, fontWeight: 'bold' }}>
                  Parent associé
                </Typography>
                <Controller
                  name="parentId"
                  control={control}
                  render={({ field, fieldState }) => {
                    const currentParent = getCurrentParent();
                    const selectedParent = field.value
                      ? parents.find((p) => p.id === field.value) || currentParent
                      : currentParent;

                    return (
                      <Autocomplete
                        options={parents}
                        getOptionLabel={(option) =>
                          `${option.firstName || ''} ${option.lastName || ''} (${option.email})`
                        }
                        value={selectedParent}
                        onChange={(event, newValue) => {
                          field.onChange(newValue ? newValue.id : '');
                        }}
                        renderInput={(params) => (
                          <TextField
                            {...params}
                            label="Parent"
                            variant="outlined"
                            error={!!fieldState.error}
                            helperText={fieldState.error?.message}
                          />
                        )}
                        renderOption={(props, option) => (
                          <Box component="li" {...props}>
                            <Box>
                              <Typography variant="body1">
                                {option.firstName} {option.lastName}
                              </Typography>
                              <Typography variant="body2" color="text.secondary">
                                {option.email}
                              </Typography>
                            </Box>
                          </Box>
                        )}
                        disabled={!isEditing}
                        clearOnEscape
                        isOptionEqualToValue={(option, value) => option.id === value?.id}
                        noOptionsText="Aucun parent trouvé"
                        loadingText="Chargement des parents..."
                      />
                    );
                  }}
                />
              </Box>
            </ConditionalComponent>
          </Card>
        </Grid>
      </Grid>
    </Form>
  );
};

export default PersonalInfoTab;
