'use client';

import * as React from 'react';
import RouterLink from 'next/link';
import { useParams, useRouter } from 'next/navigation';
//
import { COL_USERS } from '@/constants';
import { zodResolver } from '@hookform/resolvers/zod';
import { LoadingButton } from '@mui/lab';
//
import Avatar from '@mui/material/Avatar';
import Box from '@mui/material/Box';
import Button from '@mui/material/Button';
import Card from '@mui/material/Card';
import CardActions from '@mui/material/CardActions';
import CardContent from '@mui/material/CardContent';
import Divider from '@mui/material/Divider';
import FormControl from '@mui/material/FormControl';
import FormHelperText from '@mui/material/FormHelperText';
import InputLabel from '@mui/material/InputLabel';
import MenuItem from '@mui/material/MenuItem';
import OutlinedInput from '@mui/material/OutlinedInput';
import Select from '@mui/material/Select';
import Stack from '@mui/material/Stack';
import Typography from '@mui/material/Typography';
import Grid from '@mui/material/Unstable_Grid2';
//
import { Camera as CameraIcon } from '@phosphor-icons/react/dist/ssr/Camera';
//
import { Controller, useForm } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import { z as zod } from 'zod';

import { paths } from '@/paths';
import isDevelopment from '@/lib/check-is-development';
import { logger } from '@/lib/default-logger';
import { base64ToFile, fileToBase64 } from '@/lib/file-to-base64';
import { pb } from '@/lib/pb';
import { toast } from '@/components/core/toaster';
import FormLoading from '@/components/loading';

// import ErrorDisplay from '../../error';
import ErrorDisplay from '../error';

// TODO: review this
const schema = zod.object({
  name: zod.string().min(1, 'Name is required').max(255),
  email: zod.string().email('Must be a valid email').min(1, 'Email is required').max(255),
  phone: zod.string().min(1, 'Phone is required').max(25),
  company: zod.string().max(255).optional(),
  billingAddress: zod.object({
    country: zod.string().min(1, 'Country is required').max(255),
    state: zod.string().min(1, 'State is required').max(255),
    city: zod.string().min(1, 'City is required').max(255),
    zipCode: zod.string().min(1, 'Zip code is required').max(255),
    line1: zod.string().min(1, 'Street line 1 is required').max(255),
    line2: zod.string().max(255).optional(),
  }),
  taxId: zod.string().max(255).optional(),
  timezone: zod.string().min(1, 'Timezone is required').max(255),
  language: zod.string().min(1, 'Language is required').max(255),
  currency: zod.string().min(1, 'Currency is required').max(255),
  avatar: zod.string().optional(),
});

type Values = zod.infer<typeof schema>;

const defaultValues = {
  name: '',
  email: '',
  phone: '',
  company: '',
  billingAddress: {
    country: '',
    state: '',
    city: '',
    zipCode: '',
    line1: '',
    line2: '',
  },
  taxId: '',
  timezone: '',
  language: '',
  currency: '',
  avatar: '',
} satisfies Values;

export function UserEditForm(): React.JSX.Element {
  const router = useRouter();
  const { t } = useTranslation(['lp_categories']);

  const { id: userId } = useParams<{ userId: string }>();
  //
  const [isUpdating, setIsUpdating] = React.useState<boolean>(false);
  const [showLoading, setShowLoading] = React.useState<boolean>(false);
  //
  const [showError, setShowError] = React.useState({ show: false, detail: '' });

  const {
    control,
    handleSubmit,
    formState: { errors },
    setValue,
    reset,
    watch,
  } = useForm<Values>({ defaultValues, resolver: zodResolver(schema) });

  const onSubmit = React.useCallback(
    async (values: Values): Promise<void> => {
      setIsUpdating(true);

      const updateData = {
        name: values.name,
        email: values.email,
        phone: values.phone,
        company: values.company,
        billingAddress: values.billingAddress,
        taxId: values.taxId,
        timezone: values.timezone,
        language: values.language,
        currency: values.currency,
        avatar: values.avatar ? await base64ToFile(values.avatar) : null,
      };

      try {
        await pb.collection(COL_USERS).update(userId, updateData);
        toast.success('User updated successfully');
        router.push(paths.dashboard.user_metas.list);
      } catch (error) {
        logger.error(error);
        toast.error('Failed to update user');
      } finally {
        setIsUpdating(false);
      }
    },
    [userId, router]
  );

  const avatarInputRef = React.useRef<HTMLInputElement>(null);
  const avatar = watch('avatar');

  const handleAvatarChange = React.useCallback(
    async (event: React.ChangeEvent<HTMLInputElement>) => {
      const file = event.target.files?.[0];

      if (file) {
        const url = await fileToBase64(file);
        setValue('avatar', url);
      }
    },
    [setValue]
  );

  // TODO: need to align with save form
  // use trycatch
  const [textDescription, setTextDescription] = React.useState<string>('');
  const [textRemarks, setTextRemarks] = React.useState<string>('');

  // load existing data when user arrive
  const loadExistingData = React.useCallback(
    async (id: string) => {
      setShowLoading(true);

      try {
        const result = await pb.collection(COL_USERS).getOne(id);
        reset({ ...defaultValues, ...result });
        console.log({ result });

        if (result.avatar_file) {
          const fetchResult = await fetch(
            `http://127.0.0.1:8090/api/files/${result.collectionId}/${result.id}/${result.avatar_file}`
          );
          const blob = await fetchResult.blob();
          const url = await fileToBase64(blob);
          setValue('avatar', url);
        }
      } catch (error) {
        logger.error(error);
        toast.error('Failed to load user data');
        setShowError({ show: true, detail: JSON.stringify(error, null, 2) });
      } finally {
        setShowLoading(false);
      }
    },
    [reset, setValue]
  );

  React.useEffect(() => {
    void loadExistingData(userId);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [userId]);

  if (showLoading) return <FormLoading />;
  if (showError.show)
    return (
      <ErrorDisplay
        message={t('error.unable-to-process-request')}
        code="500"
        details={showError.detail}
      />
    );

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <Card>
        <CardContent>
          <Stack
            divider={<Divider />}
            spacing={4}
          >
            <Stack spacing={3}>
              <Typography variant="h6">{t('edit.basic-info')}</Typography>
              <Grid
                container
                spacing={3}
              >
                <Grid xs={12}>
                  <Stack
                    direction="row"
                    spacing={3}
                    sx={{ alignItems: 'center' }}
                  >
                    <Box
                      sx={{
                        border: '1px dashed var(--mui-palette-divider)',
                        borderRadius: '5%',
                        display: 'inline-flex',
                        p: '4px',
                      }}
                    >
                      <Avatar
                        variant="rounded"
                        src={avatar}
                        sx={{
                          '--Avatar-size': '100px',
                          '--Icon-fontSize': 'var(--icon-fontSize-lg)',
                          alignItems: 'center',
                          bgcolor: 'var(--mui-palette-background-level1)',
                          color: 'var(--mui-palette-text-primary)',
                          display: 'flex',
                          justifyContent: 'center',
                        }}
                      >
                        <CameraIcon fontSize="var(--Icon-fontSize)" />
                      </Avatar>
                    </Box>
                    <Stack
                      spacing={1}
                      sx={{ alignItems: 'flex-start' }}
                    >
                      <Typography variant="subtitle1">{t('edit.avatar')}</Typography>
                      <Typography variant="caption">{t('edit.avatarRequirements')}</Typography>
                      <Button
                        color="secondary"
                        onClick={() => {
                          avatarInputRef.current?.click();
                        }}
                        variant="outlined"
                      >
                        {t('edit.avatar_select')}
                      </Button>
                      <input
                        hidden
                        onChange={handleAvatarChange}
                        ref={avatarInputRef}
                        type="file"
                      />
                    </Stack>
                  </Stack>
                </Grid>
                <Grid
                  md={6}
                  xs={12}
                >
                  <Controller
                    control={control}
                    name="name"
                    render={({ field }) => (
                      <FormControl
                        error={Boolean(errors.name)}
                        fullWidth
                      >
                        <InputLabel required>Name</InputLabel>
                        <OutlinedInput {...field} />
                        {errors.name ? <FormHelperText>{errors.name.message}</FormHelperText> : null}
                      </FormControl>
                    )}
                  />
                </Grid>
                <Grid
                  md={6}
                  xs={12}
                >
                  <Controller
                    control={control}
                    name="email"
                    render={({ field }) => (
                      <FormControl
                        error={Boolean(errors.email)}
                        fullWidth
                      >
                        <InputLabel required>Email</InputLabel>
                        <OutlinedInput
                          {...field}
                          type="email"
                        />
                        {errors.email ? <FormHelperText>{errors.email.message}</FormHelperText> : null}
                      </FormControl>
                    )}
                  />
                </Grid>
                <Grid
                  md={6}
                  xs={12}
                >
                  <Controller
                    control={control}
                    name="phone"
                    render={({ field }) => (
                      <FormControl
                        error={Boolean(errors.phone)}
                        fullWidth
                      >
                        <InputLabel required>Phone</InputLabel>
                        <OutlinedInput {...field} />
                        {errors.phone ? <FormHelperText>{errors.phone.message}</FormHelperText> : null}
                      </FormControl>
                    )}
                  />
                </Grid>
                <Grid
                  md={6}
                  xs={12}
                >
                  <Controller
                    control={control}
                    name="company"
                    render={({ field }) => (
                      <FormControl
                        error={Boolean(errors.company)}
                        fullWidth
                      >
                        <InputLabel>Company</InputLabel>
                        <OutlinedInput
                          {...field}
                          placeholder="no company name"
                        />
                        {errors.company ? <FormHelperText>{errors.company.message}</FormHelperText> : null}
                      </FormControl>
                    )}
                  />
                </Grid>
              </Grid>
            </Stack>
            {/*  */}
            <Stack spacing={3}>
              <Typography variant="h6">Billing Information</Typography>
              <Grid
                container
                spacing={3}
              >
                <Grid
                  md={6}
                  xs={12}
                >
                  <Controller
                    control={control}
                    name="billingAddress.country"
                    render={({ field }) => (
                      <FormControl
                        error={Boolean(errors.billingAddress?.country)}
                        fullWidth
                      >
                        <InputLabel required>Country</InputLabel>
                        <Select {...field}>
                          <MenuItem value="US">United States</MenuItem>
                          <MenuItem value="UK">United Kingdom</MenuItem>
                          <MenuItem value="CA">Canada</MenuItem>
                        </Select>
                        {errors.billingAddress?.country ? (
                          <FormHelperText>{errors.billingAddress.country.message}</FormHelperText>
                        ) : null}
                      </FormControl>
                    )}
                  />
                </Grid>
                <Grid
                  md={6}
                  xs={12}
                >
                  <Controller
                    control={control}
                    name="billingAddress.state"
                    render={({ field }) => (
                      <FormControl
                        error={Boolean(errors.billingAddress?.state)}
                        fullWidth
                      >
                        <InputLabel required>State</InputLabel>
                        <OutlinedInput {...field} />
                        {errors.billingAddress?.state ? (
                          <FormHelperText>{errors.billingAddress.state.message}</FormHelperText>
                        ) : null}
                      </FormControl>
                    )}
                  />
                </Grid>
                <Grid
                  md={6}
                  xs={12}
                >
                  <Controller
                    control={control}
                    name="billingAddress.city"
                    render={({ field }) => (
                      <FormControl
                        error={Boolean(errors.billingAddress?.city)}
                        fullWidth
                      >
                        <InputLabel required>City</InputLabel>
                        <OutlinedInput {...field} />
                        {errors.billingAddress?.city ? (
                          <FormHelperText>{errors.billingAddress.city.message}</FormHelperText>
                        ) : null}
                      </FormControl>
                    )}
                  />
                </Grid>
                <Grid
                  md={6}
                  xs={12}
                >
                  <Controller
                    control={control}
                    name="billingAddress.zipCode"
                    render={({ field }) => (
                      <FormControl
                        error={Boolean(errors.billingAddress?.zipCode)}
                        fullWidth
                      >
                        <InputLabel required>Zip Code</InputLabel>
                        <OutlinedInput {...field} />
                        {errors.billingAddress?.zipCode ? (
                          <FormHelperText>{errors.billingAddress.zipCode.message}</FormHelperText>
                        ) : null}
                      </FormControl>
                    )}
                  />
                </Grid>
                <Grid
                  md={6}
                  xs={12}
                >
                  <Controller
                    control={control}
                    name="billingAddress.line1"
                    render={({ field }) => (
                      <FormControl
                        error={Boolean(errors.billingAddress?.line1)}
                        fullWidth
                      >
                        <InputLabel required>Address Line 1</InputLabel>
                        <OutlinedInput {...field} />
                        {errors.billingAddress?.line1 ? (
                          <FormHelperText>{errors.billingAddress.line1.message}</FormHelperText>
                        ) : null}
                      </FormControl>
                    )}
                  />
                </Grid>
                <Grid
                  md={6}
                  xs={12}
                >
                  <Controller
                    control={control}
                    name="taxId"
                    render={({ field }) => (
                      <FormControl
                        error={Boolean(errors.taxId)}
                        fullWidth
                      >
                        <InputLabel>Tax ID</InputLabel>
                        <OutlinedInput
                          {...field}
                          placeholder="no tax id..."
                        />
                        {errors.taxId ? <FormHelperText>{errors.taxId.message}</FormHelperText> : null}
                      </FormControl>
                    )}
                  />
                </Grid>
              </Grid>
            </Stack>

            <Stack spacing={3}>
              <Typography variant="h6">Additional Information</Typography>
              <Grid
                container
                spacing={3}
              >
                <Grid
                  md={6}
                  xs={12}
                >
                  <Controller
                    control={control}
                    name="timezone"
                    render={({ field }) => (
                      <FormControl
                        error={Boolean(errors.timezone)}
                        fullWidth
                      >
                        <InputLabel required>Timezone</InputLabel>
                        <Select {...field}>
                          <MenuItem value="America/New_York">New York</MenuItem>
                          <MenuItem value="Europe/London">London</MenuItem>
                          <MenuItem value="Asia/Tokyo">Tokyo</MenuItem>
                          <MenuItem value="America/Boa_Vista">Boa Vista</MenuItem>
                          <MenuItem value="America/Grand_Turk">Grand Turk</MenuItem>
                          <MenuItem value="Asia/Manila">Manila</MenuItem>
                          <MenuItem value="Asia/Urumqi">Urumqi</MenuItem>
                          <MenuItem value="Africa/Tunis">Tunis</MenuItem>
                        </Select>
                        {errors.timezone ? <FormHelperText>{errors.timezone.message}</FormHelperText> : null}
                      </FormControl>
                    )}
                  />
                </Grid>
                <Grid
                  md={6}
                  xs={12}
                >
                  <Controller
                    control={control}
                    name="language"
                    render={({ field }) => (
                      <FormControl
                        error={Boolean(errors.language)}
                        fullWidth
                      >
                        <InputLabel required>Language</InputLabel>
                        <Select {...field}>
                          <MenuItem value="en">English</MenuItem>
                          <MenuItem value="es">Spanish</MenuItem>
                          <MenuItem value="fr">French</MenuItem>
                        </Select>
                        {errors.language ? <FormHelperText>{errors.language.message}</FormHelperText> : null}
                      </FormControl>
                    )}
                  />
                </Grid>
                <Grid
                  md={6}
                  xs={12}
                >
                  <Controller
                    control={control}
                    name="currency"
                    render={({ field }) => (
                      <FormControl
                        error={Boolean(errors.currency)}
                        fullWidth
                      >
                        <InputLabel required>Currency</InputLabel>
                        <Select {...field}>
                          <MenuItem value="USD">USD</MenuItem>
                          <MenuItem value="EUR">EUR</MenuItem>
                          <MenuItem value="GBP">GBP</MenuItem>
                        </Select>
                        {errors.currency ? <FormHelperText>{errors.currency.message}</FormHelperText> : null}
                      </FormControl>
                    )}
                  />
                </Grid>
              </Grid>
            </Stack>
          </Stack>
        </CardContent>
        <CardActions sx={{ justifyContent: 'flex-end' }}>
          <Button
            color="secondary"
            component={RouterLink}
            href={paths.dashboard.user_metas.list}
          >
            {t('edit.cancelButton')}
          </Button>

          <LoadingButton
            disabled={isUpdating}
            loading={isUpdating}
            type="submit"
            variant="contained"
          >
            {t('edit.updateButton')}
          </LoadingButton>
        </CardActions>
      </Card>
      <Box sx={{ display: isDevelopment ? 'block' : 'none' }}>
        <pre>{JSON.stringify({ errors }, null, 2)}</pre>
      </Box>
    </form>
  );
}
