'use client';

import * as React from 'react';
import RouterLink from 'next/link';
import { useRouter } from 'next/navigation';
import { COL_USER_METAS } 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 CardHeader from '@mui/material/CardHeader';
import FormControl from '@mui/material/FormControl';
import FormHelperText from '@mui/material/FormHelperText';
import InputAdornment from '@mui/material/InputAdornment';
import InputLabel from '@mui/material/InputLabel';
import Link from '@mui/material/Link';
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 { Camera as CameraIcon } from '@phosphor-icons/react/dist/ssr/Camera';
import { User as UserIcon } from '@phosphor-icons/react/dist/ssr/User';
import { Controller, useForm } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import { z as zod } from 'zod';

import { paths } from '@/paths';
import { logger } from '@/lib/default-logger';
import { fileToBase64 } from '@/lib/file-to-base64';
import getImageUrlFromFile from '@/lib/get-image-url-from-file.ts';
import { pb } from '@/lib/pb';
import { useUser } from '@/hooks/use-user';
import { Option } from '@/components/core/option';
import { toast } from '@/components/core/toaster';
import FormLoading from '@/components/loading';

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

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 AccountDetails(): React.JSX.Element {
  const router = useRouter();
  const { t } = useTranslation();

  const { user, isLoading } = useUser();
  const [isUpdating, setIsUpdating] = React.useState<boolean>(false);
  const [showLoading, setShowLoading] = React.useState<boolean>(false);
  const [showError, setShowError] = React.useState({ show: false, detail: '' });

  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_CUSTOMERS).update(customerId, updateData);
      //   toast.success('Customer updated successfully');
      //   router.push(paths.dashboard.students.list);
      // } catch (error) {
      //   logger.error(error);
      //   toast.error('Failed to update customer');
      // } finally {
      //   setIsUpdating(false);
      // }
    },
    [router]
  );

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

  const loadExistingData = React.useCallback(async () => {
    setShowLoading(true);
    if (user) {
      try {
        const result = await pb.collection(COL_USER_METAS).getOne(user.id);
        reset({ ...defaultValues, ...result });
        console.log({ result });

        if (result.avatar) {
          // TODO: remove me
          // const fetchResult = await fetch(
          //   `http://127.0.0.1:8090/api/files/${result.collectionId}/${result.id}/${result.avatar}`
          // );
          const fetchResult = await fetch(getImageUrlFromFile(result.collectionId, result.id, result.avatar));
          const blob = await fetchResult.blob();
          const url = await fileToBase64(blob);
          setValue('avatar', url);
        }
      } catch (error) {
        logger.error(error);

        // TODO: add i18n here
        toast.error('Failed to load customer data');

        setShowError({ show: true, detail: JSON.stringify(error, null, 2) });
      } finally {
        setShowLoading(false);
      }
    }
  }, [user, reset, setValue]);

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

  if (showLoading) return <FormLoading />;
  if (!user) return <>loading</>;

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

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <Card>
        <CardHeader
          avatar={
            <Avatar>
              <UserIcon fontSize="var(--Icon-fontSize)" />
            </Avatar>
          }
          title="Basic details"
        />
        <CardContent>
          <Stack spacing={3}>
            <Stack
              direction="row"
              spacing={2}
              sx={{ alignItems: 'center' }}
            >
              <Box
                sx={{
                  border: '1px dashed var(--mui-palette-divider)',
                  borderRadius: '50%',
                  display: 'inline-flex',
                  p: '4px',
                }}
              >
                <Box sx={{ borderRadius: 'inherit', position: 'relative' }}>
                  <Box
                    sx={{
                      alignItems: 'center',
                      bgcolor: 'rgba(0, 0, 0, 0.5)',
                      borderRadius: 'inherit',
                      bottom: 0,
                      color: 'var(--mui-palette-common-white)',
                      cursor: 'pointer',
                      display: 'flex',
                      justifyContent: 'center',
                      left: 0,
                      opacity: 0,
                      position: 'absolute',
                      right: 0,
                      top: 0,
                      zIndex: 1,
                      '&:hover': { opacity: 1 },
                    }}
                  >
                    <Stack
                      direction="row"
                      spacing={1}
                      sx={{ alignItems: 'center' }}
                    >
                      <CameraIcon fontSize="var(--icon-fontSize-md)" />
                      <Typography
                        color="inherit"
                        variant="subtitle2"
                      >
                        {t('select')}
                      </Typography>
                    </Stack>
                  </Box>
                  <Avatar
                    src={getImageUrlFromFile(user.collectionId, user.id, user.avatar)}
                    sx={{ '--Avatar-size': '100px' }}
                  />
                </Box>
              </Box>
              <Button
                color="secondary"
                size="small"
              >
                {t('remove')}
              </Button>
            </Stack>
            <Stack spacing={2}>
              <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>
                )}
              />

              <Controller
                disabled
                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>
                )}
              />

              <Stack
                direction="row"
                spacing={2}
              >
                <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>
                  )}
                />
              </Stack>
              <FormControl>
                <InputLabel>Title</InputLabel>
                <OutlinedInput
                  name="title"
                  placeholder="e.g Golang Developer"
                />
              </FormControl>
              <FormControl>
                <InputLabel>Biography (optional)</InputLabel>
                <OutlinedInput
                  name="bio"
                  placeholder="Describe yourself..."
                />
                <FormHelperText>0/200 characters</FormHelperText>
              </FormControl>
            </Stack>
          </Stack>
        </CardContent>
        <CardActions sx={{ justifyContent: 'flex-end' }}>
          <Button
            color="secondary"
            component={RouterLink}
            href={paths.dashboard.overview}
          >
            {t('edit.cancelButton')}
          </Button>
          {/* <Button variant="contained">Save changes</Button> */}
          <LoadingButton
            disabled={isUpdating}
            loading={isUpdating}
            type="submit"
            variant="contained"
          >
            {t('edit.updateButton')}
          </LoadingButton>
        </CardActions>
      </Card>
    </form>
  );
}
