import { useState } from 'react';
import {
  Alert,
  Anchor,
  Button,
  Checkbox,
  Group,
  PasswordInput,
  SimpleGrid,
  Stack,
  Text,
  TextInput,
  Title,
} from '@mantine/core';
import {
  IconArrowRight,
  IconAt,
  IconDeviceMobile,
  IconLock,
  IconMail,
  IconUser,
} from '@tabler/icons-react';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import { useNavigate, Link } from 'react-router-dom';
import { useDispatch } from 'react-redux';
import { useApiMutation } from '@ema-platform/api';
import { useErrorHandler, passwordSchema, PasswordRequirements } from '@ema-platform/ui';
import { AuthShell } from '../components/AuthShell';
import { loginSuccess, setUser } from '../store/auth.slice';
import type { AuthUser } from '../types/auth.types';
import { useAuthConfig } from '../AuthConfig';

const schema = z
  .object({
    email: z.string().email(),
    username: z.string().min(3, { message: 'Username must be at least 3 characters' }),
    phoneNumber: z.string().min(1, { message: 'Phone number is required' }),
    userType: z.literal('individual'),
    nameEn: z.string().min(1, { message: 'Name (English) is required' }),
    nameAm: z.string().optional(),
    password: passwordSchema(8),
    confirmPassword: z.string().min(1, { message: 'Confirm your password' }),
  })
  .refine((data) => data.password === data.confirmPassword, {
    message: 'Passwords do not match',
    path: ['confirmPassword'],
  });

type FormValues = z.infer<typeof schema>;

interface SignupPayload {
  email: string;
  username: string;
  phoneNumber: string;
  userType: string;
  name: {
    am: string;
    en: string;
  };
  password: string;
  confirmPassword: string;
}

export function SignupPage() {
  const navigate = useNavigate();
  const dispatch = useDispatch();
  const { appName, loginRedirectPath } = useAuthConfig();
  const [agreed, setAgreed] = useState(false);
  const [serverError, setServerError] = useState<string | null>(null);
  const { handleError } = useErrorHandler();
  const [signupTrigger, { isLoading: loading }] = useApiMutation<{
    token: string;
    refreshToken: string;
    isPhoneNumberVerified: boolean;
  }>();
  const [meTrigger] = useApiMutation<AuthUser>();

  const {
    register,
    handleSubmit,
    watch,
    formState: { errors },
  } = useForm<FormValues>({
    resolver: zodResolver(schema),
    defaultValues: { userType: 'individual' },
  });

  const onSubmit = async (values: FormValues) => {
    try {
      const payload: SignupPayload = {
        email: values.email,
        username: values.username,
        phoneNumber: values.phoneNumber,
        userType: values.userType,
        name: { en: values.nameEn, am: values.nameAm ?? '' },
        password: values.password,
        confirmPassword: values.confirmPassword,
      };

      const data = await signupTrigger({
        url: '/auth/signup-with-pwd',
        method: 'POST',
        body: payload,
      }).unwrap();

      dispatch(
        loginSuccess({
          token: data.token,
          refreshToken: data.refreshToken,
          isPhoneNumberVerified: data.isPhoneNumberVerified,
        }),
      );

      const me = await meTrigger({ url: '/auth/me', method: 'GET' }).unwrap();
      dispatch(setUser(me));

      if (data.isPhoneNumberVerified) {
        navigate(loginRedirectPath);
      } else {
        navigate('/otp-verify', {
          state: {
            email: values.email,
            phoneNumber: values.phoneNumber,
          },
        });
      }
    } catch (err: unknown) {
      setServerError(handleError(err));
    }
  };

  return (
    <AuthShell
      brandTitle={`Join ${appName}'s community.`}
      brandSubtitle={`Create your account to access ${appName} features.`}
    >
      <Stack gap="lg">
        <div>
          <Title order={2} fz={30}>
            Create account
          </Title>
          <Text c="dimmed" mt={6}>
            It only takes a minute to get started.
          </Text>
        </div>

        {serverError && (
          <Alert variant="light" color="red" withCloseButton onClose={() => setServerError(null)}>
            {serverError}
          </Alert>
        )}

        <form onSubmit={handleSubmit(onSubmit)}>
          <Stack gap="md">
            <SimpleGrid cols={{ base: 1, xs: 2 }} spacing="md">
              <TextInput
                label="Name (English)"
                placeholder="Abebe Bekele"
                leftSection={<IconUser size={18} />}
                error={errors.nameEn?.message}
                {...register('nameEn')}
              />
              <TextInput
                label="Name (Amharic)"
                placeholder="ስም"
                leftSection={<IconUser size={18} />}
                error={errors.nameAm?.message}
                {...register('nameAm')}
              />
            </SimpleGrid>

            <SimpleGrid cols={{ base: 1, xs: 2 }} spacing="md">
              <TextInput
                label="Email address"
                placeholder="you@example.com"
                leftSection={<IconMail size={18} />}
                error={errors.email?.message}
                {...register('email')}
              />
              <TextInput
                label="Username"
                placeholder="Choose a username"
                leftSection={<IconAt size={18} />}
                error={errors.username?.message}
                {...register('username')}
              />
            </SimpleGrid>

            <TextInput
              label="Phone number"
              placeholder="+251 911 234 567"
              leftSection={<IconDeviceMobile size={18} />}
              error={errors.phoneNumber?.message}
              {...register('phoneNumber')}
            />

            <SimpleGrid cols={{ base: 1, xs: 2 }} spacing="md">
              <div>
                <PasswordInput
                  label="Password"
                  placeholder="At least 8 characters"
                  leftSection={<IconLock size={18} />}
                  error={errors.password?.message}
                  {...register('password')}
                />
                <PasswordRequirements password={watch('password') ?? ''} minLength={8} />
              </div>
              <PasswordInput
                label="Confirm password"
                placeholder="Re-enter password"
                leftSection={<IconLock size={18} />}
                error={errors.confirmPassword?.message}
                {...register('confirmPassword')}
              />
            </SimpleGrid>

            <Checkbox
              size="sm"
              checked={agreed}
              onChange={(e) => setAgreed(e.currentTarget.checked)}
              label={
                <Text size="sm">
                  I agree to the{' '}
                  <Anchor
                    size="sm"
                    fw={600}
                    onClick={(e) => e.preventDefault()}
                  >
                    Terms &amp; Privacy Policy
                  </Anchor>
                </Text>
              }
            />

            <Button
              type="submit"
              loading={loading}
              disabled={!agreed}
              fullWidth
              size="md"
              rightSection={<IconArrowRight size={18} />}
            >
              Create account
            </Button>
          </Stack>
        </form>

        <Text ta="center" size="sm" c="dimmed">
          Already have an account?{' '}
          <Anchor component={Link} to="/login" fw={700}>
            Sign in
          </Anchor>
        </Text>
      </Stack>
    </AuthShell>
  );
}
