import { useEffect, useState, type ReactNode } from 'react';
import type { PublicBuildDTO, PublicBuildsResponse } from '../types';
import {
  AETHERFORGE_CLIENT_HEADER,
  AETHERFORGE_CLIENT_VALUE,
  authHeaders,
  clearStoredAuth,
  consumeAuthExpiredFlag,
  encodeBasicToken,
  getStoredAuth,
  setStoredAuth,
} from '../api/auth';
import { useSound } from '../context/SoundContext';
import { FlowerOfLifeWatermark, KnowledgeKey } from './Visual/sacredGeometry/motifs';
import DocsEntryCard from './DocsEntryCard';

export default function SessionGate({ children }: { children: ReactNode }) {
  const { play } = useSound();
  const [ready, setReady] = useState(false);
  const [authed, setAuthed] = useState(!!getStoredAuth());
  const [degraded, setDegraded] = useState(false);
  const [user, setUser] = useState('');
  const [pass, setPass] = useState('');
  const [err, setErr] = useState('');
  const [sessionExpired, setSessionExpired] = useState(false);
  const [publicOpen, setPublicOpen] = useState(false);
  const [publicBuilds, setPublicBuilds] = useState<PublicBuildDTO[]>([]);
  const [publicBuildsEnabled, setPublicBuildsEnabled] = useState(false);
  const [publicLatestN, setPublicLatestN] = useState(3);
  const [publicLoading, setPublicLoading] = useState(false);
  const [publicErr, setPublicErr] = useState('');

  useEffect(() => {
    const sync = () => {
      const hasAuth = !!getStoredAuth();
      setAuthed(hasAuth);
      if (!hasAuth) {
        setSessionExpired(consumeAuthExpiredFlag());
      }
    };
    window.addEventListener('aetherforge-auth', sync);
    return () => window.removeEventListener('aetherforge-auth', sync);
  }, []);

  useEffect(() => {
    const token = getStoredAuth();
    if (!token) {
      setAuthed(false);
      setSessionExpired(consumeAuthExpiredFlag());
      setReady(true);
      return;
    }
    fetch('/api/v1/config', { headers: authHeaders() })
      .then((r) => {
        if (r.status === 401) {
          clearStoredAuth({ silent: true, expired: true });
          setAuthed(false);
          setSessionExpired(true);
        } else if (!r.ok) {
          // Server reachable but unhappy — keep saved credentials (degraded mode).
          setAuthed(true);
          setDegraded(true);
        } else {
          setAuthed(true);
          setDegraded(false);
        }
        setReady(true);
      })
      .catch(() => {
        // Network blip — trust stored credentials until the server responds.
        setAuthed(true);
        setDegraded(true);
        setReady(true);
      });
  }, []);

  const handleLogin = async (e: React.FormEvent) => {
    e.preventDefault();
    setErr('');
    setSessionExpired(false);
    const headers: Record<string, string> = {
      [AETHERFORGE_CLIENT_HEADER]: AETHERFORGE_CLIENT_VALUE,
      Authorization: `Basic ${encodeBasicToken(user, pass)}`,
    };
    try {
      const res = await fetch('/api/v1/config', { headers });
      if (!res.ok) {
        setErr('Login failed — check username and password.');
        play('error');
        return;
      }
      setStoredAuth(user, pass);
      setAuthed(true);
      setDegraded(false);
      play('success');
    } catch {
      setErr('Cannot reach server — check that miner-server is running.');
    }
  };

  if (!ready) {
    return (
      <div className="session-gate">
        <div className="session-gate-sacred-ring" aria-hidden>
          <FlowerOfLifeWatermark opacity={0.5} />
        </div>
        <p className="font-tech">Starting AetherForge…</p>
      </div>
    );
  }

  const loadPublicBuilds = async () => {
    setPublicLoading(true);
    setPublicErr('');
    try {
      const res = await fetch('/api/v1/public/builds');
      if (!res.ok) throw new Error('unavailable');
      const data = (await res.json()) as PublicBuildsResponse;
      setPublicBuilds(data.builds ?? []);
      setPublicBuildsEnabled(!!data.public_builds_enabled);
      setPublicLatestN(data.latest_n ?? 3);
      setPublicOpen(true);
    } catch {
      setPublicErr('Public builds are not available yet — forge an installer first.');
      setPublicOpen(true);
    } finally {
      setPublicLoading(false);
    }
  };

  if (!authed) {
    return (
      <div className="session-gate">
        <div className="session-gate-sacred-ring" aria-hidden>
          <FlowerOfLifeWatermark opacity={0.5} />
        </div>
        <div className="session-gate-keys" aria-hidden>
          <div className="session-gate-key session-gate-key--tl">
            <KnowledgeKey opacity={0.55} />
          </div>
          <div className="session-gate-key session-gate-key--br">
            <KnowledgeKey opacity={0.45} />
          </div>
        </div>
        <form className="session-gate-card card" onSubmit={handleLogin}>
          <h1 className="font-display">AetherForge</h1>
          <p className="form-hint">Sign in to open the command deck.</p>
          {sessionExpired && (
            <p className="form-hint" style={{ color: 'var(--accent-red)' }}>
              Your session expired — please sign in again.
            </p>
          )}
          <label className="label" htmlFor="session-user">Username</label>
          <input id="session-user" className="input" value={user} onChange={(e) => setUser(e.target.value)} autoComplete="username" />
          <label className="label" htmlFor="session-pass">Password</label>
          <input
            id="session-pass"
            className="input"
            type="password"
            value={pass}
            onChange={(e) => setPass(e.target.value)}
            autoComplete="current-password"
          />
          {err && <p className="form-hint" style={{ color: 'var(--accent-red)' }}>{err}</p>}
          <button type="submit" className="btn btn-primary btn-lg">
            Enter Command Deck
          </button>
          <p className="session-gate-whisper" aria-hidden>
            ψ · the deck remembers every key
          </p>
          <DocsEntryCard variant="featured" />
          <div className="session-public-drawer" style={{ marginTop: '1rem', width: '100%' }}>
            <div style={{ display: 'flex', gap: '0.5rem', flexWrap: 'wrap' }}>
              <button
                type="button"
                className="btn btn-outline btn-sm"
                style={{ flex: 1, minWidth: '10rem' }}
                onClick={() => void loadPublicBuilds()}
                disabled={publicLoading}
              >
                {publicLoading ? 'Loading…' : 'Public builds (no login)'}
              </button>
              <a
                href="/spread/"
                className="btn btn-outline btn-sm"
                style={{ flex: 1, minWidth: '10rem', textAlign: 'center' }}
              >
                Spread Kit
              </a>
            </div>
            {publicOpen && (
              <div className="card" style={{ marginTop: '0.75rem', textAlign: 'left' }}>
                <p className="form-hint" style={{ marginTop: 0 }}>
                  {publicBuildsEnabled
                    ? 'All forged installers exposed — no credentials required.'
                    : `Pinned + marked-public + latest ${publicLatestN} forged installers — no credentials required.`}
                </p>
                {publicErr && <p className="form-hint" style={{ color: 'var(--accent-red)' }}>{publicErr}</p>}
                {publicBuilds.length === 0 && !publicErr && (
                  <p className="form-hint">No public builds yet.</p>
                )}
                <ul style={{ listStyle: 'none', margin: 0, padding: 0 }}>
                  {publicBuilds.map((b) => (
                    <li key={b.id} style={{ marginBottom: '0.5rem', fontSize: '0.85rem' }}>
                      <strong>{b.worker_name}</strong>
                      <span className="form-hint"> · {b.platform}</span>
                      {b.pinned && <span> 📌</span>}
                      <br />
                      <a href={b.download_url} className="mono" style={{ fontSize: '0.75rem' }}>
                        Download
                      </a>
                    </li>
                  ))}
                </ul>
              </div>
            )}
          </div>
        </form>
      </div>
    );
  }

  return (
    <>
      {degraded && (
        <div className="session-degraded-banner" role="status">
          Cannot reach server — using saved credentials. Some data may be stale until connectivity returns.
        </div>
      )}
      {children}
    </>
  );
}
