'use client';

import { useEffect, useId, useRef, useState, type FormEvent } from 'react';
import { createPortal } from 'react-dom';
import { isValidEmail } from '@/lib/email';

/**
 * Blocking email step shown part-way through the assessment. While it is open, everything else on
 * the page is inert (no clicks, focus or keyboard input) and the page cannot scroll. It can only be
 * closed by entering a valid email and pressing "Continue your assessment".
 */
export function EmailGate({
  open,
  questionNumber,
  total,
  onContinue,
}: {
  open: boolean;
  questionNumber: number;
  total: number;
  onContinue: (email: string) => void;
}) {
  const [email, setEmail] = useState('');
  const [error, setError] = useState('');
  const backdropRef = useRef<HTMLDivElement>(null);
  const inputRef = useRef<HTMLInputElement>(null);
  const id = useId();

  useEffect(() => {
    if (!open) return;
    const backdrop = backdropRef.current;
    const others = Array.from(document.body.children).filter(
      (el): el is HTMLElement => el instanceof HTMLElement && el !== backdrop && !el.inert,
    );
    others.forEach((el) => {
      el.inert = true;
      el.setAttribute('aria-hidden', 'true');
    });
    const previousOverflow = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    inputRef.current?.focus();
    return () => {
      others.forEach((el) => {
        el.inert = false;
        el.removeAttribute('aria-hidden');
      });
      document.body.style.overflow = previousOverflow;
    };
  }, [open]);

  if (!open) return null;

  function submit(e: FormEvent<HTMLFormElement>) {
    e.preventDefault();
    const value = email.trim();
    if (!isValidEmail(value)) {
      setError('Please enter a valid email address to continue.');
      inputRef.current?.focus();
      return;
    }
    setError('');
    onContinue(value);
  }

  return createPortal(
    <div ref={backdropRef} className="gate-backdrop">
      <div
        className="card card-raised gate"
        role="dialog"
        aria-modal="true"
        aria-labelledby={`${id}-title`}
        aria-describedby={`${id}-desc`}
      >
        <span className="eyebrow">
          Question {questionNumber} of {total}
        </span>
        <h2 id={`${id}-title`} style={{ fontSize: '1.6rem' }}>
          You're nearly halfway there.
        </h2>
        <p id={`${id}-desc`} className="muted">
          Enter your email address to continue your assessment.
        </p>
        <form className="form" onSubmit={submit} noValidate>
          <label htmlFor={`${id}-email`} className="sr-only">
            Email address
          </label>
          <input
            ref={inputRef}
            id={`${id}-email`}
            className="input"
            type="email"
            name="email"
            autoComplete="email"
            inputMode="email"
            placeholder="you@example.com"
            value={email}
            onChange={(e) => setEmail(e.target.value)}
            aria-invalid={error ? true : undefined}
            aria-describedby={error ? `${id}-error` : undefined}
            required
          />
          {error && (
            <p id={`${id}-error`} className="form-msg err" role="alert">
              {error}
            </p>
          )}
          <button className="btn btn-primary btn-lg btn-block" type="submit">
            Continue your assessment
          </button>
        </form>
      </div>
    </div>,
    document.body,
  );
}
