'use client';

import { useEffect, useId, useMemo, useRef, useState } from 'react';
import { Icon } from '@/components/marketing/icons';
import {
  DIAL_COUNTRIES,
  DEFAULT_DIAL_ISO,
  formatNationalDisplay,
  parsePhoneValue,
  toE164,
  type DialCountry,
} from '@/lib/phone';
import { cn } from '@/lib/utils';

type PhoneInputProps = {
  id?: string;
  name?: string;
  value: string;
  onChange: (e164: string) => void;
  placeholder?: string;
  disabled?: boolean;
  required?: boolean;
  className?: string;
  /** Prefer this ISO when value is empty / local-only. */
  defaultIso?: string;
};

export function PhoneInput({
  id,
  name,
  value,
  onChange,
  placeholder = '7XX XXX XXX',
  disabled,
  required,
  className,
  defaultIso = DEFAULT_DIAL_ISO,
}: PhoneInputProps) {
  const listId = useId();
  const rootRef = useRef<HTMLDivElement>(null);
  const searchRef = useRef<HTMLInputElement>(null);
  const parsed = useMemo(() => parsePhoneValue(value, defaultIso), [value, defaultIso]);
  const [country, setCountry] = useState<DialCountry>(parsed.country);
  const [national, setNational] = useState(parsed.national);
  const [open, setOpen] = useState(false);
  const [query, setQuery] = useState('');

  useEffect(() => {
    const next = parsePhoneValue(value, defaultIso);
    setCountry(next.country);
    setNational(next.national);
  }, [value, defaultIso]);

  useEffect(() => {
    if (!open) return;
    const onDoc = (event: MouseEvent) => {
      if (!rootRef.current?.contains(event.target as Node)) setOpen(false);
    };
    const onKey = (event: KeyboardEvent) => {
      if (event.key === 'Escape') setOpen(false);
    };
    document.addEventListener('mousedown', onDoc);
    document.addEventListener('keydown', onKey);
    const focusTimer = window.setTimeout(() => searchRef.current?.focus(), 0);
    return () => {
      document.removeEventListener('mousedown', onDoc);
      document.removeEventListener('keydown', onKey);
      window.clearTimeout(focusTimer);
    };
  }, [open]);

  const filtered = useMemo(() => {
    const q = query.trim().toLowerCase();
    if (!q) return DIAL_COUNTRIES;
    return DIAL_COUNTRIES.filter(c =>
      c.name.toLowerCase().includes(q)
      || c.dial.includes(q.replace(/^\+/, ''))
      || c.iso.toLowerCase().includes(q),
    );
  }, [query]);

  function emit(nextIso: string, nextNational: string) {
    onChange(toE164(nextIso, nextNational));
  }

  function selectCountry(next: DialCountry) {
    setCountry(next);
    setOpen(false);
    setQuery('');
    emit(next.iso, national);
  }

  function onNationalChange(raw: string) {
    const digits = raw.replace(/\D/g, '').replace(/^0+/, '').slice(0, 12);
    setNational(digits);
    emit(country.iso, digits);
  }

  return (
    <div ref={rootRef} className={cn('phone-input', className)}>
      {name && <input type="hidden" name={name} value={value} />}
      <div className={cn('phone-input-shell', open && 'is-open', disabled && 'is-disabled')}>
        <button
          type="button"
          className="phone-input-code"
          disabled={disabled}
          aria-haspopup="listbox"
          aria-expanded={open}
          aria-controls={listId}
          onClick={() => setOpen(v => !v)}
        >
          <span className="phone-input-flag" aria-hidden>{country.flag}</span>
          <span className="phone-input-dial">+{country.dial}</span>
          <Icon name="chevron" size={14} className={cn('phone-input-caret', open && 'is-open')} />
        </button>
        <span className="phone-input-divider" aria-hidden />
        <input
          id={id}
          type="tel"
          inputMode="tel"
          autoComplete="tel-national"
          disabled={disabled}
          required={required}
          placeholder={placeholder}
          className="phone-input-number"
          value={formatNationalDisplay(national)}
          onChange={e => onNationalChange(e.target.value)}
          aria-label="Phone number"
        />
      </div>

      {open && (
        <div className="phone-input-popover" role="listbox" id={listId} aria-label="Country code">
          <div className="phone-input-search">
            <Icon name="search" size={15} />
            <input
              ref={searchRef}
              value={query}
              onChange={e => setQuery(e.target.value)}
              placeholder="Search country or code"
              aria-label="Search country"
            />
          </div>
          <ul className="phone-input-list">
            {filtered.map(item => {
              const active = item.iso === country.iso && item.dial === country.dial;
              return (
                <li key={`${item.iso}-${item.dial}-${item.name}`}>
                  <button
                    type="button"
                    role="option"
                    aria-selected={active}
                    className={cn('phone-input-option', active && 'is-active')}
                    onClick={() => selectCountry(item)}
                  >
                    <span className="phone-input-flag">{item.flag}</span>
                    <span className="phone-input-option-name">{item.name}</span>
                    <span className="phone-input-option-dial">+{item.dial}</span>
                  </button>
                </li>
              );
            })}
            {filtered.length === 0 && (
              <li className="phone-input-empty">No countries match.</li>
            )}
          </ul>
        </div>
      )}
    </div>
  );
}
