import FusePageSimple from '@fuse/core/FusePageSimple';
import _ from '@lodash';
import FuseSvgIcon from '@fuse/core/FuseSvgIcon/FuseSvgIcon';
import { yupResolver } from '@hookform/resolvers/yup';
import Button from '@mui/material/Button';
import Paper from '@mui/material/Paper';
import TextField from '@mui/material/TextField';
import { styled } from '@mui/material/styles';
import { selectUser, updateUserSettings } from 'app/store/userSlice';
import { Controller, useForm } from 'react-hook-form';
import { withTranslation } from 'react-i18next';
import { useDispatch, useSelector } from 'react-redux';
import * as yup from 'yup';
import { toBase64 } from 'src/app/utils';
import { forwardRef } from 'react';

const MAX_PICTURE_SIZE = 5000000;
const AVAILABLE_MEDIA_TYPES = ['image/png', 'image/jpeg'];

const Root = styled(FusePageSimple)(({ theme }) => ({
  '& .FusePageSimple-header': {},
  '& .FusePageSimple-toolbar': {},
  '& .FusePageSimple-content': {
    backgroundColor: theme.palette.background.default,
  },
  '& .FusePageSimple-sidebarHeader': {},
  '& .FusePageSimple-sidebarContent': {},
}));

const StyledTextField = forwardRef((props, ref) => (
  <TextField
    InputProps={{
      sx: {
        background: (theme) => theme.palette.background.paper,
        borderRadius: '10px',
      },
    }}
    {...props}
    ref={ref}
  />
));

function ProfilePage({ t }) {
  const dispatch = useDispatch();
  const user = useSelector(selectUser);

  const defaultValues = {
    photoURL: '',
    firstName: '',
    lastName: '',
    displayName: '',
    email: '',
    mobileNumber: '',
    information: '',
    address: '',
    ...user.data,
  };
  const schema = yup.object().shape({
    photoURL: yup.string().notRequired(),
    firstName: yup
      .string()
      .max(150, t('max_length_error', { length: 150 }))
      .trim()
      .notRequired(),
    lastName: yup
      .string()
      .max(150, t('max_length_error', { length: 150 }))
      .trim()
      .notRequired(),
    displayName: yup
      .string()
      .required(t('display_name_error'))
      .max(30, t('max_length_error', { length: 30 }))
      .trim(),
    email: yup
      .string()
      .matches(/^[\w-.]+@([\w-]+\.)+[\w-]{2,4}$/g, t('email_error'))
      .required(t('email_error'))
      .max(40, t('max_length_error', { length: 40 })),
    mobileNumber: yup
      .string()
      .matches(/^(?=(.*\d){7,})\+?(\d[\d-. ]+)?(\([\d-. ]+\))?[\d-. ]+\d$/, {
        message: t('mobile_number_error'),
        excludeEmptyString: true,
      })
      .max(20, t('max_length_error', { length: 20 }))
      .notRequired(),
    information: yup
      .string()
      .max(300, t('max_length_error', { length: 300 }))
      .trim()
      .notRequired(),
    address: yup
      .string()
      .max(150, t('max_length_error', { length: 150 }))
      .trim()
      .notRequired(),
  });

  const { control, formState, watch, setValue, handleSubmit, setError, reset } = useForm({
    mode: 'onChange',
    defaultValues,
    resolver: yupResolver(schema),
  });
  const { dirtyFields, errors } = formState;

  // eslint-disable-next-line consistent-return
  const uploadPicture = async (event) => {
    const { target } = event;
    if (target.files && target.files[0]) {
      const file = target.files[0];
      if (file.size > MAX_PICTURE_SIZE) {
        return setError('photoURL', { type: 'custom', message: t('picture_size_error') });
      }

      if (!AVAILABLE_MEDIA_TYPES.includes(file.type)) {
        return setError('photoURL', {
          type: 'custom',
          message: t('picture_extensions_error'),
        });
      }

      const base64 = await toBase64(file);
      setValue('photoURL', base64, { shouldDirty: true });
    } else {
      setError('photoURL', { type: 'custom', message: 'Choose a file please' });
    }
  };

  const deletePicture = () => setValue('photoURL', '', { shouldDirty: true });

  const onSubmit = (data) => {
    dispatch(updateUserSettings(data)).catch((error) => {
      setError('root', {
        type: 'manual',
        message: error.message,
      });
    });
    reset(data);
  };

  return (
    <Root
      content={
        <div className="w-full p-60">
          <form name="profileForm" noValidate onSubmit={handleSubmit(onSubmit)}>
            <div className="flex items-end mb-68">
              <Paper className="relative w-[240px] h-[240px] mr-20 bg-common-disabled overflow-hidden">
                {watch('photoURL') && (
                  <img
                    src={watch('photoURL')}
                    alt="user"
                    className="absolute w-full h-full object-cover"
                  />
                )}
              </Paper>
              <div className="grid grid-cols-[200px_minmax(0,_1fr)] gap-x-40 gap-y-28">
                <Controller
                  name="photoURL"
                  control={control}
                  render={({ field: { name, ref, onBlur } }) => (
                    <label htmlFor="input-file">
                      <input
                        id="input-file"
                        name={name}
                        ref={ref}
                        type="file"
                        accept={AVAILABLE_MEDIA_TYPES.join(', ')}
                        style={{ display: 'none' }}
                        onBlur={onBlur}
                        onChange={uploadPicture}
                      />
                      <Button
                        variant="outlined"
                        component="span"
                        color="secondary"
                        className="text-lg rounded-xl border-2 border-secondary-main shadow hover:shadow-hover hover:shadow-secondary-main hover:border-2 ease-in-out duration-300"
                        aria-label={t('upload_picture_btn')}
                        size="small"
                        fullWidth
                      >
                        {t('upload_picture_btn')}
                      </Button>
                    </label>
                  )}
                />
                <Button
                  variant="text"
                  color="secondary"
                  className="justify-self-start min-w-fit text-base"
                  aria-label={t('delete_picture')}
                  disabled={!watch('photoURL')}
                  size="small"
                  onClick={deletePicture}
                >
                  <FuseSvgIcon className="mr-10">heroicons-outline:trash</FuseSvgIcon>
                  {t('delete_picture')}
                </Button>
                <ul className="col-span-2 text-lg">
                  <li className="bullet">{t('first_picture_req')}</li>
                  <li className="bullet">{t('second_picture_req')}</li>
                </ul>
              </div>
            </div>

            <div className="grid grid-cols-6 gap-x-24 gap-y-32 w-full mb-48">
              <Controller
                name="firstName"
                control={control}
                render={({ field }) => (
                  <StyledTextField
                    {...field}
                    className="col-span-2"
                    label={t('first_name')}
                    type="text"
                    error={!!errors.firstName}
                    helperText={errors?.firstName?.message}
                    variant="outlined"
                    fullWidth
                  />
                )}
              />

              <Controller
                name="lastName"
                control={control}
                render={({ field }) => (
                  <StyledTextField
                    {...field}
                    className="col-span-2"
                    label={t('last_name')}
                    type="text"
                    error={!!errors.lastName}
                    helperText={errors?.lastName?.message}
                    variant="outlined"
                    fullWidth
                  />
                )}
              />

              <Controller
                name="displayName"
                control={control}
                render={({ field }) => (
                  <StyledTextField
                    {...field}
                    className="col-span-2"
                    label={t('display_name')}
                    type="text"
                    error={!!errors.displayName}
                    helperText={errors?.displayName?.message}
                    variant="outlined"
                    required
                    fullWidth
                  />
                )}
              />

              <Controller
                name="email"
                control={control}
                render={({ field }) => (
                  <StyledTextField
                    {...field}
                    className="col-span-3"
                    label={t('email')}
                    type="email"
                    error={!!errors.email}
                    helperText={errors?.email?.message}
                    variant="outlined"
                    required
                    fullWidth
                  />
                )}
              />

              <Controller
                name="mobileNumber"
                control={control}
                render={({ field }) => (
                  <StyledTextField
                    {...field}
                    className="col-span-3"
                    label={t('mobile_number')}
                    type="tel"
                    error={!!errors.mobileNumber}
                    helperText={errors?.mobileNumber?.message}
                    variant="outlined"
                    fullWidth
                  />
                )}
              />

              <Controller
                name="information"
                control={control}
                render={({ field }) => (
                  <TextField
                    {...field}
                    className="col-span-3"
                    label={t('information')}
                    type="text"
                    error={!!errors.information}
                    helperText={errors?.information?.message}
                    variant="outlined"
                    multiline
                    rows={7}
                    fullWidth
                    InputProps={{
                      sx: {
                        padding: 0,
                        background: (theme) => theme.palette.background.paper,
                        borderRadius: '10px',
                      },
                    }}
                    // eslint-disable-next-line react/jsx-no-duplicate-props
                    inputProps={{
                      sx: {
                        padding: '16.5px 14px',
                      },
                    }}
                  />
                )}
              />

              <Controller
                name="address"
                control={control}
                render={({ field }) => (
                  <TextField
                    {...field}
                    className="col-span-3"
                    label={t('address')}
                    type="text"
                    error={!!errors.address}
                    helperText={errors?.address?.message}
                    variant="outlined"
                    multiline
                    rows={7}
                    fullWidth
                    InputProps={{
                      sx: {
                        padding: 0,
                        background: (theme) => theme.palette.background.paper,
                        borderRadius: '10px',
                      },
                    }}
                    // eslint-disable-next-line react/jsx-no-duplicate-props
                    inputProps={{
                      sx: {
                        padding: '16.5px 14px',
                      },
                    }}
                  />
                )}
              />
            </div>

            <div className="flex flex-col items-center justify-center gap-10 w-full">
              <Button
                variant="contained"
                color="secondary"
                className="max-w-320 text-base uppercase rounded-xl"
                aria-label={t('save_changes')}
                disabled={_.isEmpty(dirtyFields) || !_.isEmpty(errors)}
                type="submit"
                size="large"
              >
                {t('save_changes')}
              </Button>
              {errors.root?.message && (
                <p className="text-l text-error-main">{errors.root?.message}</p>
              )}
            </div>
          </form>
        </div>
      }
      scroll="content"
    />
  );
}

export default withTranslation('profilePage')(ProfilePage);
