// username.jsx — shared username helpers and dialogs.
// Used by the home page (Start now) and the German page (claim after sign-in).
// Loaded as its own babel script, so everything is published on window and uses
// unique local names (top-level consts are shared between scripts).

const { useState: useStateU, useEffect: useEffectU, useRef: useRefU } = React;

const USERNAME_KEY = 'de_username';
const USERNAME_RE = /^[\p{L}\p{N}_-]{3,20}$/u;

function getLocalUsername() {
  try { return localStorage.getItem(USERNAME_KEY) || ''; } catch { return ''; }
}
function setLocalUsername(name) {
  try { localStorage.setItem(USERNAME_KEY, name); } catch {}
}
function usernameProblem(name) {
  if (name.length < 3) return 'At least 3 characters.';
  if (name.length > 20) return 'At most 20 characters.';
  if (!USERNAME_RE.test(name)) return 'Letters, numbers, _ and - only.';
  return '';
}

// Step 1, before any account: just a display name, saved in this browser.
function UsernameDialog({ onDone, onClose }) {
  const [name, setName] = useStateU(getLocalUsername());
  const [touched, setTouched] = useStateU(false);
  const ref = useRefU(null);
  useEffectU(() => { ref.current && ref.current.focus(); }, []);
  const problem = usernameProblem(name.trim());
  const submit = (e) => {
    e.preventDefault();
    setTouched(true);
    if (problem) return;
    setLocalUsername(name.trim());
    onDone(name.trim());
  };
  return (
    <div className="un-overlay" role="dialog" aria-modal="true" aria-labelledby="un-title">
      <form className="un-card" onSubmit={submit} noValidate>
        {onClose && <button type="button" className="un-x" aria-label="Close" onClick={onClose}>×</button>}
        <h2 id="un-title" className="un-title">What should we call you?</h2>
        <p className="un-sub">Pick a username. You will keep it when you create your account, and it can't be changed later.</p>
        <input ref={ref} className="un-input" value={name} maxLength={20} autoComplete="off"
               placeholder="e.g. anna_k" aria-label="Username"
               onChange={(e) => setName(e.target.value)} />
        <div className="un-msg" role="alert">{touched && problem ? problem : ''}</div>
        <button type="submit" className="un-btn">Start learning</button>
      </form>
    </div>
  );
}

// Link that asks for a username first if this browser doesn't have one yet.
function StartLink({ href, className, children }) {
  const [open, setOpen] = useStateU(false);
  const onClick = (e) => {
    if (getLocalUsername()) return;
    e.preventDefault();
    setOpen(true);
  };
  return (
    <>
      <a className={className} href={href} onClick={onClick}>{children}</a>
      {open && <UsernameDialog onClose={() => setOpen(false)} onDone={() => { window.location.href = href; }} />}
    </>
  );
}

// Step 2, after sign-in: make the name permanent. Unique, can't be skipped.
function ClaimUsernameModal({ supabase, userId, initial, onClaimed }) {
  const [name, setName] = useStateU(initial || '');
  const [status, setStatus] = useStateU('idle'); // idle | checking | free | taken | saving
  const [err, setErr] = useStateU('');
  const problem = usernameProblem(name.trim());

  useEffectU(() => {
    setErr('');
    if (!name.trim() || problem) { setStatus('idle'); return; }
    setStatus('checking');
    let live = true;
    const t = setTimeout(async () => {
      const { data, error } = await supabase.rpc('username_available', { name: name.trim() });
      if (!live) return;
      if (error) { setStatus('idle'); return; } // the insert below is the real check
      setStatus(data ? 'free' : 'taken');
    }, 350);
    return () => { live = false; clearTimeout(t); };
  }, [name]);

  const base = name.trim().slice(0, 16) || 'learner';
  const suggestions = [`${base}_de`, `${base}${Math.floor(10 + Math.random() * 90)}`].filter(s => !usernameProblem(s));

  const submit = async (e) => {
    e.preventDefault();
    if (problem || status === 'taken' || status === 'saving') return;
    setStatus('saving');
    const { error } = await supabase.from('profiles').insert({ user_id: userId, username: name.trim() });
    if (!error) { setLocalUsername(name.trim()); onClaimed(name.trim()); return; }
    if (error.code === '23505') { setStatus('taken'); return; } // someone claimed it first
    setStatus('idle');
    setErr('Could not save. Please try again.');
  };

  const msg = problem && name ? problem
    : status === 'taken' ? 'That username is taken.'
    : status === 'free' ? 'Available.'
    : status === 'checking' ? 'Checking…' : err;

  return (
    <div className="un-overlay" role="dialog" aria-modal="true" aria-labelledby="un-claim-title">
      <form className="un-card" onSubmit={submit} noValidate>
        <h2 id="un-claim-title" className="un-title">Claim your username</h2>
        <p className="un-sub">This is permanent and can't be changed later, so choose one you like.</p>
        <input className="un-input" value={name} maxLength={20} autoComplete="off" aria-label="Username"
               onChange={(e) => setName(e.target.value)} />
        <div className={`un-msg ${status === 'free' ? 'un-ok' : ''}`} role="status">{msg}</div>
        {status === 'taken' && (
          <div className="un-sugs">
            {suggestions.map(s => <button type="button" key={s} className="un-chip" onClick={() => setName(s)}>{s}</button>)}
          </div>
        )}
        <button type="submit" className="un-btn" disabled={!!problem || status === 'taken' || status === 'saving' || status === 'checking'}>
          {status === 'saving' ? 'Saving…' : 'Claim username'}
        </button>
      </form>
    </div>
  );
}

Object.assign(window, { getLocalUsername, setLocalUsername, usernameProblem, UsernameDialog, StartLink, ClaimUsernameModal });
