import { useState } from 'react';
import {
  Alert,
  Anchor,
  Button,
  Center,
  Group,
  Stack,
  Text,
  TextInput,
  ThemeIcon,
  Title,
} from '@mantine/core';
import {
  IconArrowLeft,
  IconMail,
  IconMailForward,
  IconSend,
} from '@tabler/icons-react';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import { Link } from 'react-router-dom';
import { useApiMutation } from '@ema-platform/api';
import { notify, useErrorHandler } from '@ema-platform/ui';
import { isValidPhoneNumber, parsePhoneNumberFromString } from 'libphonenumber-js';
import { AuthShell } from '../components/AuthShell';
import { useAuthConfig } from '../AuthConfig';

// Same email-or-phone rule as LoginPage: a phone-looking value normalizes to
// E.164 (bare Ethiopian national numbers default to +251) so the backend
// always gets a value it can look the account up by, under the `email` key.
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
const schema = z.object({
  email: z
    .string()
    .trim()
    .transform((value) => {
      if (emailRegex.test(value)) return value;
      return parsePhoneNumberFromString(value, 'ET')?.number ?? value;
    })
    .refine((value) => emailRegex.test(value) || isValidPhoneNumber(value), {
      message: 'Enter a valid email or phone number',
    }),
});

type FormValues = z.infer<typeof schema>;

export function ForgotPasswordPage() {
  const { appName } = useAuthConfig();
  const [forgotTrigger, { isLoading }] = useApiMutation();
  const [sentTo, setSentTo] = useState<string | null>(null);
  const [serverError, setServerError] = useState<string | null>(null);
  const { handleError } = useErrorHandler();

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

  const sendResetLink = async (email: string) => {
    await forgotTrigger({
      url: '/auth/forgot-password',
      method: 'POST',
      body: { email },
    }).unwrap();
    setSentTo(email);
  };

  const onSubmit = async (values: FormValues) => {
    try {
      await sendResetLink(values.email);
    } catch (err: unknown) {
      setServerError(handleError(err));
    }
  };

  const handleResend = async () => {
    if (!sentTo || isLoading) return;
    try {
      await sendResetLink(sentTo);
      notify.success('Reset link sent again');
    } catch (err: unknown) {
      setServerError(handleError(err));
    }
  };

  const backToSignIn = (
    <Center>
      <Anchor
        component={Link}
        to="/login"
        size="sm"
        fw={600}
        style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}
      >
        <IconArrowLeft size={16} />
        Back to sign in
      </Anchor>
    </Center>
  );

  if (sentTo) {
    return (
      <AuthShell
        brandTitle="Reset your password securely."
        brandSubtitle={`We'll email you a secure link to set a new password and get you back into ${appName}.`}
      >
        <Stack gap="lg">
          <ThemeIcon size={56} radius="md" variant="light" color="emaPrimary">
            <IconMailForward size={30} />
          </ThemeIcon>

          <div>
            <Title order={2} fz={30}>
              Check your email
            </Title>
            <Text c="dimmed" mt={6}>
              We&apos;ve sent a password reset link to{' '}
              <Text span fw={600} c="dark">
                {sentTo}
              </Text>
              . Follow the link in that email to choose a new password.
            </Text>
          </div>

          <Button
            component="a"
            href="https://mail.google.com"
            target="_blank"
            rel="noopener noreferrer"
            fullWidth
            size="md"
            leftSection={<IconMail size={18} />}
          >
            Open email app
          </Button>

          <Group justify="center" gap={6}>
            <Text size="sm" c="dimmed">
              Didn&apos;t get the email?
            </Text>
            <Anchor
              size="sm"
              fw={600}
              onClick={handleResend}
              style={isLoading ? { pointerEvents: 'none', opacity: 0.6 } : undefined}
            >
              Resend link
            </Anchor>
          </Group>

          {backToSignIn}
        </Stack>
      </AuthShell>
    );
  }

  return (
    <AuthShell
      brandTitle="Reset your password securely."
      brandSubtitle={`We'll email you a secure link to set a new password and get you back into ${appName}.`}
    >
      <Stack gap="lg">
        <div>
          <Title order={2} fz={30}>
            Forgot your password?
          </Title>
          <Text c="dimmed" mt={6}>
            Enter the email or phone number linked to your account and
            we&apos;ll send you a link to reset your password.
          </Text>
        </div>

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

        <form onSubmit={handleSubmit(onSubmit)}>
          <Stack gap="md">
            <TextInput
              label="Email or phone"
              placeholder="you@example.com"
              size="md"
              leftSection={<IconMail size={18} />}
              error={errors.email?.message}
              {...register('email')}
            />

            <Button
              type="submit"
              loading={isLoading}
              fullWidth
              size="md"
              rightSection={<IconSend size={18} />}
            >
              Send reset link
            </Button>
          </Stack>
        </form>

        {backToSignIn}
      </Stack>
    </AuthShell>
  );
}
