import { useState, type FormEvent } from 'react'
import { Link } from 'react-router-dom'
import { useQuery } from '@tanstack/react-query'
import { Clock, Mail, Lock, User, Users } from 'lucide-react'
import { AuthLayout } from '@/components/auth/AuthLayout'
import { getRegistrationOptions, register } from '@/api/auth'
import { ApiError, errorDetail } from '@/api/client'

const CONSENT_POLICY_PATH = '/legal/personal-data-consent'

/** Текст предупреждения о несовпадении домена почты с эталонными. */
function domainMismatchMessage(domains: string[]): string {
  const list = domains.map((domain) => `@${domain}`).join(' или ')
  return `Укажите рабочую почту — регистрация доступна только для домена ${list}`
}

/**
 * Экран регистрации (см. design/mockups/auth.html, блок «регистрация»).
 * Поле «Команда» показывается только если выбор команды включён в
 * настройках инстанса (`GET /auth/registration-options`, публичный эндпоинт).
 * Поле «Рабочая почта» дополнительно сверяется с эталонными доменами
 * (`registration-options.email_domains` — подходит совпадение с ЛЮБЫМ),
 * если в админке включена верификация по домену — проверка идёт по blur и
 * при сабмите, backend при включённой верификации и чужом домене отвечает
 * 400 `invalid_email_domain`.
 * После успешной регистрации показывает состояние «подтвердите почту»
 * (письмо со ссылкой backend в dev-режиме печатает в консоль).
 * Галочка согласия на обработку персональных данных (`consent_required`)
 * показывается только при включённой настройке инстанса; ссылка рядом
 * ведёт на публичную страницу регламента (`ConsentPolicyPage`), которая
 * берёт тот же текст/версию из `registration-options`. Кнопка отправки
 * заблокирована, пока галочка не отмечена, — сервер отдельно перепроверяет
 * это же условие (`POST /auth/register` отвечает 400 `consent_required`).
 */
export function RegisterPage() {
  const [name, setName] = useState('')
  const [email, setEmail] = useState('')
  const [password, setPassword] = useState('')
  const [teamId, setTeamId] = useState('')
  const [consentAccepted, setConsentAccepted] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const [emailDomainError, setEmailDomainError] = useState<string | null>(null)
  const [pending, setPending] = useState(false)
  const [registeredEmail, setRegisteredEmail] = useState<string | null>(null)

  const { data: registrationOptions } = useQuery({
    queryKey: ['auth', 'registration-options'],
    queryFn: getRegistrationOptions,
  })
  const teamChoiceEnabled = registrationOptions?.team_choice_enabled ?? false
  const teams = registrationOptions?.teams ?? []
  const expectedEmailDomains = registrationOptions?.email_domains ?? []
  const consentRequired = registrationOptions?.consent_required ?? false

  /** Домен после «@» не совпадает (без учёта регистра) ни с одним эталонным — `null`, если сверять не с чем. */
  function checkEmailDomain(value: string): string | null {
    if (expectedEmailDomains.length === 0) return null
    const atIndex = value.lastIndexOf('@')
    if (atIndex === -1) return null
    const domain = value.slice(atIndex + 1).trim().toLowerCase()
    if (!expectedEmailDomains.some((expected) => domain === expected.toLowerCase())) {
      return domainMismatchMessage(expectedEmailDomains)
    }
    return null
  }

  async function handleSubmit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault()
    setError(null)

    const domainError = checkEmailDomain(email)
    setEmailDomainError(domainError)
    if (domainError) return
    if (consentRequired && !consentAccepted) return

    setPending(true)
    try {
      await register({
        email,
        name_user: name,
        password,
        team_id: teamChoiceEnabled ? teamId || null : null,
        consent_accepted: consentAccepted,
      })
      setRegisteredEmail(email)
    } catch (err) {
      if (err instanceof ApiError && err.status === 409) {
        setError('Пользователь с таким email уже зарегистрирован')
      } else if (err instanceof ApiError && err.status === 400 && errorDetail(err) === 'invalid_email_domain') {
        setEmailDomainError(expectedEmailDomains.length > 0 ? domainMismatchMessage(expectedEmailDomains) : 'Регистрация с этим доменом почты недоступна')
      } else if (err instanceof ApiError && err.status === 400 && errorDetail(err) === 'consent_required') {
        setError('Отметьте согласие на обработку персональных данных')
      } else {
        setError('Не удалось зарегистрироваться. Проверьте данные и попробуйте снова')
      }
    } finally {
      setPending(false)
    }
  }

  if (registeredEmail) {
    return (
      <AuthLayout>
        <section className="screen-block">
          <div className="confirm-card pending">
            <div className="confirm-icon">
              <Clock className="lucide" aria-hidden="true" />
            </div>
            <h3>Подтвердите почту</h3>
            <p>
              Мы отправили письмо со ссылкой на{' '}
              <span className="mail-chip">
                <Mail className="lucide" style={{ width: 14, height: 14 }} aria-hidden="true" />
                {registeredEmail}
              </span>
            </p>
            <Link to="/login" className="btn btn-secondary btn-block btn-lg">
              Перейти ко входу
            </Link>
          </div>
        </section>
      </AuthLayout>
    )
  }

  return (
    <AuthLayout>
      <section className="screen-block">
        <div className="tabs" role="tablist" aria-label="Способ авторизации">
          <Link to="/login" className="tab" role="tab" aria-selected="false">
            Вход
          </Link>
          <span className="tab is-active" role="tab" aria-selected="true">
            Регистрация
          </span>
        </div>
        <h2 className="screen-title">Создать аккаунт</h2>
        <form onSubmit={handleSubmit} noValidate>
          <div className="field">
            <label htmlFor="reg-name">Имя и фамилия</label>
            <div className="input-wrap">
              <User className="lucide field-icon" aria-hidden="true" />
              <input
                id="reg-name"
                type="text"
                required
                placeholder="Мария Кузнецова"
                value={name}
                onChange={(e) => setName(e.target.value)}
              />
            </div>
          </div>
          <div className={`field${emailDomainError ? ' has-error' : ''}`}>
            <label htmlFor="reg-email">Рабочая почта</label>
            <div className="input-wrap">
              <Mail className="lucide field-icon" aria-hidden="true" />
              <input
                id="reg-email"
                type="email"
                autoComplete="email"
                required
                placeholder="you@company.ru"
                value={email}
                onChange={(e) => setEmail(e.target.value)}
                onBlur={(e) => setEmailDomainError(checkEmailDomain(e.target.value))}
              />
            </div>
            {emailDomainError && <p className="error-msg">{emailDomainError}</p>}
          </div>
          {teamChoiceEnabled && (
            <div className="field">
              <label htmlFor="reg-team">Команда</label>
              <div className="input-wrap">
                <Users className="lucide field-icon" aria-hidden="true" />
                <select id="reg-team" value={teamId} onChange={(e) => setTeamId(e.target.value)}>
                  <option value="">Иное</option>
                  {teams.map((team) => (
                    <option key={team.id} value={team.id}>
                      {team.name}
                    </option>
                  ))}
                </select>
              </div>
            </div>
          )}
          <div className={`field${error ? ' has-error' : ''}`}>
            <label htmlFor="reg-pass">Пароль</label>
            <div className="input-wrap">
              <Lock className="lucide field-icon" aria-hidden="true" />
              <input
                id="reg-pass"
                type="password"
                autoComplete="new-password"
                required
                minLength={8}
                placeholder="Минимум 8 символов"
                value={password}
                onChange={(e) => setPassword(e.target.value)}
              />
            </div>
            {error ? (
              <p className="error-msg">{error}</p>
            ) : (
              <p className="hint-msg">Минимум 8 символов, буквы и цифры</p>
            )}
          </div>
          {consentRequired && (
            <label className="checkbox-row" style={{ marginBottom: 'var(--space-4)' }}>
              <input
                type="checkbox"
                checked={consentAccepted}
                onChange={(e) => setConsentAccepted(e.target.checked)}
              />
              Согласен(на) на{' '}
              <Link
                to={CONSENT_POLICY_PATH}
                target="_blank"
                rel="noopener"
                style={{ fontWeight: 700, textDecoration: 'underline' }}
              >
                обработку персональных данных
              </Link>
            </label>
          )}
          <button
            type="submit"
            className="btn btn-primary btn-block btn-lg"
            disabled={pending || (consentRequired && !consentAccepted)}
          >
            {pending ? 'Регистрируем…' : 'Зарегистрироваться'}
          </button>
        </form>
      </section>
    </AuthLayout>
  )
}
