// LoginScreen + SetupScreen - layout B from the auth brainstorm spec:
// 22px wordmark + "WILD DRAGON BROADCAST" tagline above a --bg-1 card.
// Matches DESIGN.md tokens; no decoration, dense, ops register.

(function () {
  const API_BASE = '/api/v1';

  async function postJson(path, body) {
    return fetch(API_BASE + path, {
      method: 'POST',
      credentials: 'include',
      headers: {
        'Content-Type': 'application/json',
        'X-Requested-With': 'dragonflight-ui',
      },
      body: JSON.stringify(body),
    });
  }

  function Brand() {
    return (
      <div style={{ textAlign: 'center', marginBottom: 22 }}>
        <div style={{ fontSize: 22, fontWeight: 600, color: 'var(--text-1)', letterSpacing: '-0.01em' }}>Dragonflight</div>
        <div style={{ fontSize: 10.5, fontWeight: 600, color: 'var(--text-3)', marginTop: 6, letterSpacing: '0.08em', textTransform: 'uppercase' }}>
          Wild Dragon Broadcast
        </div>
      </div>
    );
  }

  function Card({ children }) {
    return (
      <div style={{
        background: 'var(--bg-1)',
        border: '1px solid var(--border)',
        borderRadius: 12,
        padding: 22,
      }}>{children}</div>
    );
  }

  function Field({ label, type = 'text', value, onChange, autoComplete, autoFocus }) {
    return (
      <div style={{ marginBottom: 14 }}>
        <label style={{ display: 'block', fontSize: 10.5, fontWeight: 600, color: 'var(--text-2)', letterSpacing: '0.06em', textTransform: 'uppercase', marginBottom: 6 }}>
          {label}
        </label>
        <input
          type={type}
          autoComplete={autoComplete}
          autoFocus={autoFocus}
          value={value}
          onChange={e => onChange(e.target.value)}
          style={{
            width: '100%',
            background: 'var(--bg-3)',
            border: '1px solid var(--border)',
            borderRadius: 4,
            padding: '8px 10px',
            fontSize: 12.5,
            color: 'var(--text-1)',
            fontFamily: 'var(--font-mono)',
            boxSizing: 'border-box',
          }}
        />
      </div>
    );
  }

  function Button({ children, disabled, onClick, type = 'button' }) {
    return (
      <button
        type={type}
        disabled={disabled}
        onClick={onClick}
        style={{
          width: '100%',
          background: disabled ? 'var(--bg-3)' : 'var(--accent)',
          color: disabled ? 'var(--text-3)' : '#0a0c10',
          border: 'none',
          borderRadius: 4,
          padding: '9px',
          fontSize: 13,
          fontWeight: 600,
          fontFamily: 'inherit',
          cursor: disabled ? 'default' : 'pointer',
          opacity: disabled ? 0.6 : 1,
        }}
      >{children}</button>
    );
  }

  function ErrorRow({ text }) {
    if (!text) return null;
    return (
      <div style={{
        fontSize: 11.5,
        color: 'var(--danger)',
        marginBottom: 12,
        padding: '6px 10px',
        background: 'var(--danger-soft)',
        border: '1px solid var(--danger)',
        borderRadius: 4,
      }}>{text}</div>
    );
  }

  function Screen({ children }) {
    return (
      <div style={{ minHeight: '100vh', background: 'var(--bg-0)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
        <form onSubmit={e => e.preventDefault()} style={{ width: 300 }}>
          <Brand />
          <Card>{children}</Card>
        </form>
      </div>
    );
  }

  // Google sign-in availability + a friendly message for the callback's
  // ?auth_error redirect (domain-not-allowed / generic google failure).
  function useGoogleAndAuthError(setError) {
    const [googleEnabled, setGoogleEnabled] = React.useState(false);
    React.useEffect(() => {
      fetch(API_BASE + '/auth/google/enabled', { credentials: 'include' })
        .then(r => r.json()).then(d => setGoogleEnabled(!!d.enabled)).catch(() => {});
      const params = new URLSearchParams(location.search);
      const e = params.get('auth_error');
      if (e === 'domain') setError('That Google account is not in an allowed domain.');
      else if (e === 'google') setError('Google sign-in failed. Please try again.');
      if (e) {
        // Clean the query string so a reload doesn't re-show the error.
        const url = location.pathname + location.hash;
        history.replaceState(null, '', url);
      }
    }, [setError]);
    return googleEnabled;
  }

  function GoogleButton() {
    return (
      <a href={API_BASE + '/auth/google'} style={{
        display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8,
        width: '100%', boxSizing: 'border-box', textDecoration: 'none',
        background: 'var(--bg-3)', color: 'var(--text-1)',
        border: '1px solid var(--border)', borderRadius: 4,
        padding: '9px', fontSize: 13, fontWeight: 600, marginTop: 10,
      }}>
        <span style={{ fontFamily: 'var(--font-mono)', fontWeight: 700 }}>G</span>
        Sign in with Google
      </a>
    );
  }

  function Divider() {
    return (
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, margin: '14px 0 4px' }}>
        <div style={{ flex: 1, height: 1, background: 'var(--border)' }} />
        <span style={{ fontSize: 10, color: 'var(--text-3)', textTransform: 'uppercase', letterSpacing: '0.08em' }}>or</span>
        <div style={{ flex: 1, height: 1, background: 'var(--border)' }} />
      </div>
    );
  }

  function LoginScreen({ onDone }) {
    const [username, setUsername] = React.useState('');
    const [password, setPassword] = React.useState('');
    const [error,    setError]    = React.useState('');
    const [busy,     setBusy]     = React.useState(false);
    // Second factor: when the server returns { mfa_required, ticket }, we switch
    // to the code step instead of completing login. `ticket` may be a real value
    // (password path) or the sentinel 'session' (Google path, where the ticket
    // lives in the session cookie and is not exposed to JS).
    const [ticket,   setTicket]   = React.useState(null);
    const [code,     setCode]     = React.useState('');
    const googleEnabled = useGoogleAndAuthError(setError);

    // Google OAuth with TOTP redirects back to /?mfa=1; the ticket is in the
    // session, so enter the code step without a body ticket.
    React.useEffect(() => {
      const params = new URLSearchParams(location.search);
      if (params.get('mfa') === '1') {
        setTicket('session');
        history.replaceState(null, '', location.pathname + location.hash);
      }
    }, []);

    const submit = async () => {
      setError(''); setBusy(true);
      try {
        const r = await postJson('/auth/login', { username, password });
        if (r.status === 200) {
          const body = await r.json().catch(() => ({}));
          if (body.mfa_required) { setTicket(body.ticket); setBusy(false); return; }
          onDone(); return;
        }
        const body = await r.json().catch(() => ({}));
        setError(body.error || ('Login failed: ' + r.status));
      } catch (e) { setError(e.message || 'Login failed'); }
      finally { setBusy(false); }
    };

    const submitCode = async () => {
      setError(''); setBusy(true);
      try {
        // For the Google path the ticket is the session sentinel — send code only.
        const payload = ticket === 'session' ? { code: code.trim() } : { ticket, code: code.trim() };
        const r = await postJson('/auth/login/totp', payload);
        if (r.status === 200) { onDone(); return; }
        const body = await r.json().catch(() => ({}));
        // An expired/used ticket means the user must start over.
        if (r.status === 401 && /ticket/.test(body.error || '')) {
          setTicket(null); setCode(''); setPassword('');
          setError('Session timed out. Please sign in again.');
        } else {
          setError(body.error || ('Verification failed: ' + r.status));
        }
      } catch (e) { setError(e.message || 'Verification failed'); }
      finally { setBusy(false); }
    };

    if (ticket) {
      return (
        <Screen>
          <div style={{ fontSize: 10.5, fontWeight: 600, color: 'var(--text-3)', letterSpacing: '0.08em', textTransform: 'uppercase', marginBottom: 14 }}>
            Two-factor authentication
          </div>
          <ErrorRow text={error} />
          <Field label="Authenticator code" value={code} onChange={setCode} autoComplete="one-time-code" autoFocus />
          <div style={{ fontSize: 10.5, color: 'var(--text-3)', marginBottom: 12 }}>
            Enter the 6-digit code from your authenticator app, or a recovery code.
          </div>
          <Button type="submit" disabled={busy || !code.trim()} onClick={submitCode}>Verify</Button>
        </Screen>
      );
    }

    return (
      <Screen>
        <ErrorRow text={error} />
        <Field label="Username" value={username} onChange={setUsername} autoComplete="username" autoFocus />
        <Field label="Password" type="password" value={password} onChange={setPassword} autoComplete="current-password" />
        <Button type="submit" disabled={busy || !username || !password} onClick={submit}>Sign in</Button>
        {googleEnabled && <><Divider /><GoogleButton /></>}
      </Screen>
    );
  }

  function SetupScreen({ onDone }) {
    const [username, setUsername] = React.useState('');
    const [password, setPassword] = React.useState('');
    const [confirm,  setConfirm]  = React.useState('');
    const [error,    setError]    = React.useState('');
    const [busy,     setBusy]     = React.useState(false);
    const submit = async () => {
      setError('');
      if (password !== confirm) { setError('Passwords do not match'); return; }
      if (password.length < 12) { setError('Password must be at least 12 characters'); return; }
      setBusy(true);
      try {
        const r = await postJson('/auth/setup', { username, password });
        if (r.status === 200) { onDone(); return; }
        const body = await r.json().catch(() => ({}));
        setError(body.error || ('Setup failed: ' + r.status));
      } catch (e) { setError(e.message || 'Setup failed'); }
      finally { setBusy(false); }
    };
    return (
      <Screen>
        <div style={{ fontSize: 10.5, fontWeight: 600, color: 'var(--text-3)', letterSpacing: '0.08em', textTransform: 'uppercase', marginBottom: 14 }}>
          First-run setup: create the first admin
        </div>
        <ErrorRow text={error} />
        <Field label="Username" value={username} onChange={setUsername} autoComplete="username" autoFocus />
        <Field label="Password" type="password" value={password} onChange={setPassword} autoComplete="new-password" />
        <Field label="Confirm password" type="password" value={confirm} onChange={setConfirm} autoComplete="new-password" />
        <Button type="submit" disabled={busy || !username || !password || !confirm} onClick={submit}>Create admin</Button>
      </Screen>
    );
  }

  window.LoginScreen = LoginScreen;
  window.SetupScreen = SetupScreen;
})();
