import { useState } from 'react';
import {
  Alert,
  Anchor,
  Button,
  Checkbox,
  Group,
  PasswordInput,
  SimpleGrid,
  Stack,
  Text,
  TextInput,
  Title,
  UnstyledButton,
} from '@mantine/core';
import {
  IconArrowLeft,
  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 { useTranslation } from 'react-i18next';
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';

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 { t } = useTranslation();
  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 handleBack = () => {
    if (window.history.length > 1) {
      navigate(-1);
    } else {
      navigate('/');
    }
  };

  // Order matches passwordRules' default list: length, lowercase, uppercase,
  // number, special character. Shared between the zod schema (field error)
  // and the live checklist below, so both agree on the wording.
  const passwordRuleLabels = [
    t('signup.passwordRule.minLength', { min: 8, defaultValue: 'At least {{min}} characters' }),
    t('signup.passwordRule.lowercase', 'One lowercase letter'),
    t('signup.passwordRule.uppercase', 'One uppercase letter'),
    t('signup.passwordRule.number', 'One number'),
    t('signup.passwordRule.special', 'One special character'),
  ];

  // Built inside the component (not module scope) so validation messages
  // pick up the active language — same pattern as ProfilePage's forms.
  const schema = z
    .object({
      email: z.string().email(),
      username: z.string().min(3, { message: t('signup.usernameMinLength', 'Username must be at least 3 characters') }),
      phoneNumber: z.string().min(1, { message: t('signup.phoneRequired', 'Phone number is required') }),
      userType: z.literal('individual'),
      nameEn: z
        .string()
        .min(1, { message: t('signup.nameEnRequired', 'Name (English) is required') })
        .refine((v) => v.trim().split(/\s+/).length >= 3, {
          message: t('signup.nameEnFullNameRequired', 'Please enter your full name (first, middle, and last)'),
        }),
      nameAm: z.string().optional(),
      password: passwordSchema(8, passwordRuleLabels),
      confirmPassword: z.string().min(1, { message: t('signup.confirmPasswordRequired', 'Confirm your password') }),
    })
    .refine((data) => data.password === data.confirmPassword, {
      message: t('signup.passwordsDontMatch', 'Passwords do not match'),
      path: ['confirmPassword'],
    });

  type FormValues = z.infer<typeof schema>;

  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={t('signup.brandTitle', { appName, defaultValue: "Join {{appName}}'s community." })}
      brandSubtitle={t('signup.brandSubtitle', {
        appName,
        defaultValue: 'Create your account to access {{appName}} features.',
      })}
    >
      <Stack gap="lg">
        <UnstyledButton
          onClick={handleBack}
          style={{
            display: 'inline-flex',
            alignItems: 'center',
            gap: 6,
            fontSize: 14,
            fontWeight: 600,
            color: 'var(--mantine-color-dimmed)',
            cursor: 'pointer',
            width: 'fit-content',
            transition: 'all 150ms ease',
          }}
          onMouseEnter={(e) => {
            e.currentTarget.style.color = 'var(--mantine-primary-color-filled)';
            e.currentTarget.style.transform = 'translateX(-3px)';
          }}
          onMouseLeave={(e) => {
            e.currentTarget.style.color = 'var(--mantine-color-dimmed)';
            e.currentTarget.style.transform = 'translateX(0)';
          }}
        >
          <IconArrowLeft size={18} />
          {t('common.back', 'Back')}
        </UnstyledButton>

        <div>
          <Title order={2} fz={30}>
            {t('signup.title', 'Create account')}
          </Title>
          <Text c="dimmed" mt={6}>
            {t('signup.subtitle', '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={t('signup.nameEnLabel', 'Full name (English)')}
                placeholder={t('signup.nameEnPlaceholder', 'Abebe Bekele')}
                leftSection={<IconUser size={18} />}
                error={errors.nameEn?.message}
                {...register('nameEn')}
              />
              <TextInput
                label={t('signup.nameAmLabel', 'Name (Amharic)')}
                placeholder={t('signup.nameAmPlaceholder', 'ስም')}
                leftSection={<IconUser size={18} />}
                error={errors.nameAm?.message}
                {...register('nameAm')}
              />
            </SimpleGrid>

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

            <TextInput
              label={t('signup.phoneLabel', 'Phone number')}
              placeholder={t('signup.phonePlaceholder', '+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={t('signup.passwordLabel', 'Password')}
                  placeholder={t('signup.passwordPlaceholder', 'At least 8 characters')}
                  leftSection={<IconLock size={18} />}
                  error={errors.password?.message}
                  {...register('password')}
                />
                <PasswordRequirements
                  password={watch('password') ?? ''}
                  minLength={8}
                  labels={passwordRuleLabels}
                />
              </div>
              <PasswordInput
                label={t('signup.confirmPasswordLabel', 'Confirm password')}
                placeholder={t('signup.confirmPasswordPlaceholder', '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">
                  {t('signup.agreeToThe', 'I agree to the ')}
                  <Anchor
                    size="sm"
                    fw={600}
                    onClick={(e) => e.preventDefault()}
                  >
                    {t('signup.termsAndPrivacy', 'Terms & Privacy Policy')}
                  </Anchor>
                </Text>
              }
            />

            <Button
              type="submit"
              loading={loading}
              disabled={!agreed}
              fullWidth
              size="md"
              rightSection={<IconArrowRight size={18} />}
            >
              {t('signup.createAccount', 'Create account')}
            </Button>
          </Stack>
        </form>

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