'use client';
import { FormEvent, FunctionComponent, useState } from 'react';
import { CircularProgress, Link as MuiLink, Stack, Typography } from '@mui/material';
import { useLocale, useTranslations } from 'next-intl';

import PhoneNumberField, { isIranianMobile } from '@/components/PhoneNumberField';
import { AppButton, AppLink } from '@/components';
import { APP_ROLES, ROUTES, type AppRole } from '@/constants';
import { useRequestOtp } from '@/services/auth';
import type { ApiError } from '@/lib/api/errors';
import type { RequestOtpResult } from '@/services/auth/types';

interface PhoneStepProps {
  intendedRole: AppRole;
  onSwitchRole: () => void;
  onSent: (phone: string, result: RequestOtpResult) => void;
}

const RATE_LIMIT_STATUS = 429;

/**
 * A1 (customer) / B1 (nurse) — the phone entry step. Same mechanism for both actors; only the
 * copy and the role-switch link differ. Requests an OTP and advances to the code step; domain
 * 4xx (invalid number, rate-limit) render inline.
 * @component PhoneStep
 */
const PhoneStep: FunctionComponent<PhoneStepProps> = ({ intendedRole, onSwitchRole, onSent }) => {
  const t = useTranslations('auth');
  const locale = useLocale();
  const [phone, setPhone] = useState('');
  const [invalid, setInvalid] = useState(false);
  const [rateLimited, setRateLimited] = useState(false);
  const requestOtp = useRequestOtp();

  const isNurse = intendedRole === APP_ROLES.NURSE;

  const submit = (event: FormEvent) => {
    event.preventDefault();
    setRateLimited(false);
    if (!isIranianMobile(phone)) {
      setInvalid(true);
      return;
    }
    setInvalid(false);
    requestOtp.mutate(
      { phone },
      {
        onSuccess: (result) => onSent(phone, result),
        onError: (error) => {
          if ((error as ApiError).status === RATE_LIMIT_STATUS) setRateLimited(true);
          else setInvalid(true);
        },
      },
    );
  };

  return (
    <Stack component="form" onSubmit={submit} sx={{ gap: 2 }}>
      <Stack sx={{ gap: 0.5, textAlign: 'center' }}>
        <Typography variant="h6" component="h1">
          {isNurse ? t('nurse_title') : t('customer_title')}
        </Typography>
        <Typography variant="body2" sx={{ color: 'text.secondary' }}>
          {isNurse ? t('nurse_subtitle') : t('customer_subtitle')}
        </Typography>
      </Stack>

      <PhoneNumberField
        value={phone}
        onChange={(next) => {
          setPhone(next);
          if (invalid) setInvalid(false);
        }}
        label={t('phone_label')}
        placeholder="0912 000 0000"
        error={invalid || rateLimited}
        helperText={invalid ? t('phone_invalid') : rateLimited ? t('rate_limited') : ' '}
        fullWidth
        autoFocus
      />

      <AppButton
        type="submit"
        color="primary"
        variant="contained"
        fullWidth
        disabled={requestOtp.isPending}
        startIcon={requestOtp.isPending ? <CircularProgress size={18} color="inherit" /> : undefined}
      >
        {t('request_code')}
      </AppButton>

      <Typography variant="caption" sx={{ color: 'text.secondary', textAlign: 'center' }}>
        {t.rich('consent_line', {
          terms: (chunks) => <AppLink to={`/${locale}${ROUTES.TERMS}`}>{chunks}</AppLink>,
          privacy: (chunks) => <AppLink to={`/${locale}${ROUTES.PRIVACY}`}>{chunks}</AppLink>,
        })}
      </Typography>

      <MuiLink
        component="button"
        type="button"
        onClick={onSwitchRole}
        underline="hover"
        sx={{ color: 'text.secondary', textAlign: 'center' }}
      >
        {isNurse ? t('customer_switch') : t('nurse_switch')}
      </MuiLink>
    </Stack>
  );
};

export default PhoneStep;
