import { useState } from 'react';
import { useNavigate, useSearchParams } from 'react-router-dom';
import {
  Alert,
  Button,
  Card,
  Center,
  PasswordInput,
  Stack,
  Text,
  TextInput,
  Title,
} from '@mantine/core';
import { IconInfoCircle, IconLockCheck } from '@tabler/icons-react';
import { useApiMutation } from '@ema-platform/api';
import { notify } from '@ema-platform/ui';

/** Mirrors the API's IsStrongPassword rule so failures are explained locally. */
function passwordProblem(password: string): string | null {
  if (password.length < 8) return 'At least 8 characters';
  if (!/[a-z]/.test(password)) return 'At least one lowercase letter';
  if (!/[0-9]/.test(password)) return 'At least one number';
  if (!/[^A-Za-z0-9]/.test(password)) return 'At least one symbol';
  return null;
}

/**
 * Completes the forgot-password flow (US-IAM-007).
 *
 * The reset message carries a link to this page with `userId` and `email` —
 * the set-password endpoint requires both, and the account holder only knows
 * one of them. Arriving without the link means the code alone cannot finish
 * the reset, and the page says so instead of failing cryptically.
 */
export function SetPasswordPage() {
  const navigate = useNavigate();
  const [params] = useSearchParams();
  const userId = params.get('userId') ?? '';
  const email = params.get('email') ?? '';

  // The IAM package's link carries the code as `verificationCode`.
  const [code, setCode] = useState(
    params.get('verificationCode') ?? params.get('code') ?? '',
  );
  const [password, setPassword] = useState('');
  const [confirm, setConfirm] = useState('');
  const [error, setError] = useState<string | null>(null);
  const [setPasswordTrigger, { isLoading }] = useApiMutation();

  const linkMissing = !userId || !email;
  const problem = password ? passwordProblem(password) : null;

  const submit = async () => {
    setError(null);
    if (problem) return setError(`Password needs: ${problem.toLowerCase()}`);
    if (password !== confirm) return setError("Passwords don't match");
    try {
      await setPasswordTrigger({
        url: '/auth/set-password',
        method: 'PATCH',
        body: {
          userId,
          email,
          verificationCode: code,
          newPassword: password,
          confirmPassword: confirm,
        },
      }).unwrap();
      notify.success('Password updated — sign in with your new password');
      navigate('/login');
    } catch (err) {
      const message = (err as { data?: { message?: string } })?.data?.message;
      setError(
        typeof message === 'string' && message === 'verification_code_expired'
          ? 'The code has expired. Request a new reset from the sign-in page.'
          : 'Could not set the password. Check the code and try again.',
      );
    }
  };

  return (
    <Center mih="100vh" p="md">
      <Card withBorder radius="md" p="xl" w={420}>
        <Stack>
          <Stack gap={4} align="center">
            <IconLockCheck size={32} color="var(--mantine-color-blue-6)" />
            <Title order={3}>Set a new password</Title>
            {email && (
              <Text size="sm" c="dimmed">
                for {email}
              </Text>
            )}
          </Stack>

          {linkMissing ? (
            <Alert color="orange" icon={<IconInfoCircle size={16} />}>
              Open this page from the reset link we sent you — the link carries
              the details needed to finish the reset. You can request one from
              the{' '}
              <Text
                component="span"
                c="blue"
                style={{ cursor: 'pointer' }}
                onClick={() => navigate('/forgot-password')}
              >
                forgot-password page
              </Text>
              .
            </Alert>
          ) : (
            <>
              <TextInput
                label="Verification code"
                placeholder="The code from the reset message"
                required
                value={code}
                onChange={(e) => setCode(e.currentTarget.value)}
              />
              <PasswordInput
                label="New password"
                required
                value={password}
                onChange={(e) => setPassword(e.currentTarget.value)}
                error={password && problem ? problem : undefined}
              />
              <PasswordInput
                label="Confirm password"
                required
                value={confirm}
                onChange={(e) => setConfirm(e.currentTarget.value)}
                error={
                  confirm && confirm !== password
                    ? "Passwords don't match"
                    : undefined
                }
              />
              {error && <Alert color="red">{error}</Alert>}
              <Button
                fullWidth
                loading={isLoading}
                disabled={!code.trim() || !password || !confirm}
                onClick={submit}
              >
                Set password
              </Button>
            </>
          )}
        </Stack>
      </Card>
    </Center>
  );
}
