// gp-auth.jsx — authentification, rôles, menu utilisateur
// ───────────────────────────────────────────────────────────────
// Deux modes :
//  • PRODUCTION : window.GPTO_AUTH_API défini → vraie auth (Worker Cloudflare, cookies).
//  • DÉMO/LOCAL : non défini → connexion par profils de démonstration (localStorage).
const { Icon: AIcon, USERS: AUSERS, ROLES: AROLES } = window;

const API = window.GPTO_AUTH_API || null;              // ex. "https://gpto-auth.xxx.workers.dev"
const ROLE_LABELS = { super_admin: 'Super-administrateur', store_manager: 'Gérant de magasin', admin: 'Administrateur', user: 'Estimateur' };
const roleLabel = (r) => ROLE_LABELS[r] || (AROLES[r] || {}).label || r;
const roleCls = (r) => (r === 'super_admin' || r === 'admin' || r === 'store_manager') ? 'admin' : ((AROLES[r] || {}).cls || 'user');

// ── Client API (fetch avec cookie de session + en-tête anti-CSRF) ──
const GPTOAuth = {
  enabled: !!API,
  async call(path, body, method = 'POST') {
    const res = await fetch(API + path, {
      method,
      credentials: 'include',
      headers: { 'content-type': 'application/json', 'x-requested-with': 'gpto' },
      body: body ? JSON.stringify(body) : undefined,
    });
    let data = {}; try { data = await res.json(); } catch (_) {}
    return { ok: res.ok, status: res.status, data };
  },
  me() { return this.call('/api/auth/me', null, 'GET'); },
  login(email, password) { return this.call('/api/auth/login', { email, password }); },
  signup(payload) { return this.call('/api/auth/signup', payload); },
  logout() { return this.call('/api/auth/logout', {}); },
};
window.GPTOAuth = GPTOAuth;

function Avatar({ user, size = 34 }) {
  const inits = user.initiales || ((user.prenom || '')[0] || '') + ((user.nom || '')[0] || '');
  return (
    <span className={'avatar role-' + roleCls(user.role)}
      style={{ width: size, height: size, fontSize: size * 0.38 }}>
      {inits}
    </span>
  );
}

// ── Écran de connexion / inscription ───────────────────────────
function LoginScreen({ onLogin }) {
  const [mode, setMode] = React.useState('login');   // login | signup | sent
  const [f, setF] = React.useState({ email: '', password: '', prenom: '', nom: '', confirm: '' });
  const [errors, setErrors] = React.useState({});
  const [msg, setMsg] = React.useState(null);         // { type:'error'|'info', text }
  const [busy, setBusy] = React.useState(false);
  const set = (k) => (e) => setF((s) => ({ ...s, [k]: e.target.value }));

  // Retour de vérification courriel (?verified=1) → message.
  React.useEffect(() => {
    const p = new URLSearchParams(location.search);
    if (p.get('verified') === '1') setMsg({ type: 'info', text: 'Courriel vérifié — vous pouvez vous connecter.' });
    if (p.get('verified') === '0') setMsg({ type: 'error', text: 'Lien de vérification invalide ou expiré.' });
  }, []);

  async function doLogin() {
    setErrors({}); setMsg(null); setBusy(true);
    try {
      const { ok, data } = await GPTOAuth.login(f.email.trim(), f.password);
      if (ok && data.user) return onLogin(data.user);
      setMsg({ type: 'error', text: data.error || 'Connexion impossible.' });
    } catch (_) { setMsg({ type: 'error', text: 'Serveur injoignable.' }); }
    finally { setBusy(false); }
  }

  function validateSignup() {
    const e = {};
    if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(f.email.trim())) e.email = 'Courriel invalide.';
    if (!f.prenom.trim()) e.prenom = 'Prénom requis.';
    if (!f.nom.trim()) e.nom = 'Nom requis.';
    if (f.password.length < 10) e.password = 'Au moins 10 caractères.';
    else if (!/[a-z]/.test(f.password) || !/[A-Z]/.test(f.password) || !/[0-9]/.test(f.password))
      e.password = 'Minuscule, majuscule et chiffre requis.';
    if (f.confirm !== f.password) e.confirm = 'Les mots de passe diffèrent.';
    return e;
  }
  async function doSignup() {
    const e = validateSignup(); setErrors(e); setMsg(null);
    if (Object.keys(e).length) return;
    setBusy(true);
    try {
      const { ok, status, data } = await GPTOAuth.signup({
        email: f.email.trim(), password: f.password, prenom: f.prenom.trim(), nom: f.nom.trim(),
      });
      if (ok) return setMode('sent');
      if (status === 422 && data.errors) setErrors(data.errors);
      else setMsg({ type: 'error', text: data.error || 'Inscription impossible.' });
    } catch (_) { setMsg({ type: 'error', text: 'Serveur injoignable.' }); }
    finally { setBusy(false); }
  }

  const Err = ({ k }) => errors[k] ? <div className="field-err">{errors[k]}</div> : null;

  return (
    <div className="login">
      <div className="login-brand-side">
        <div className="login-brand">
          <div className="login-logo">G</div>
          <div>
            <div className="login-brand-name">GO·PASSIF</div>
            <div className="login-brand-sub">Estimateur sur plan</div>
          </div>
        </div>
        <div className="login-tagline">
          <h1>Prise de mesure &amp; soumission de matériaux</h1>
          <p>Relevés sur plan, recettes par produit et bordereaux — pour une enveloppe haute performance.</p>
        </div>
        <div className="login-foot">© 2026 GO·PASSIF · accès réservé à l’équipe</div>
      </div>

      <div className="login-card-side">
        <div className="login-card">
          {msg && <div className={'login-msg ' + msg.type}>{msg.text}</div>}

          {/* ── Écran « courriel envoyé » ── */}
          {mode === 'sent' && (
            <>
              <div className="login-card-h">Vérifiez votre courriel</div>
              <div className="login-card-s">Un lien d’activation a été envoyé à <b>{f.email}</b>. Cliquez-le pour activer votre compte.</div>
              <button className="btn login-go" onClick={() => setMode('login')}>Retour à la connexion</button>
            </>
          )}

          {/* ── Connexion ── */}
          {mode === 'login' && (
            <>
              <div className="login-card-h">Connexion</div>
              <div className="login-card-s">Entrez vos identifiants pour accéder à vos projets.</div>

              <label className="lbl">Courriel</label>
              <input className="field" type="email" autoComplete="username" placeholder="prenom.nom@gopassif.ca"
                value={f.email} onChange={set('email')} onKeyDown={(e) => e.key === 'Enter' && API && doLogin()} />
              <div style={{ height: 12 }} />
              <label className="lbl">Mot de passe</label>
              <input className="field" type="password" autoComplete="current-password" placeholder="••••••••"
                value={f.password} onChange={set('password')} onKeyDown={(e) => e.key === 'Enter' && API && doLogin()} />

              {API ? (
                <>
                  <button className="btn accent login-go" disabled={busy} onClick={doLogin}>
                    {busy ? 'Connexion…' : <>Se connecter <AIcon n="chev" style={{ width: 15, height: 15 }} /></>}
                  </button>
                  <div className="login-alt">Pas de compte ? <button className="linkbtn" onClick={() => { setMode('signup'); setMsg(null); setErrors({}); }}>Créer un compte</button></div>
                </>
              ) : (
                <button className="btn accent login-go" onClick={() => onLogin(AUSERS[0])}>
                  Se connecter <AIcon n="chev" style={{ width: 15, height: 15 }} />
                </button>
              )}

              {/* Profils de démonstration (mode local sans backend) */}
              {!API && (
                <>
                  <div className="login-div"><span>profils de démonstration</span></div>
                  <div className="login-demos">
                    {AUSERS.map((u) => (
                      <button key={u.id} className="login-demo" onClick={() => onLogin(u)}>
                        <Avatar user={u} size={36} />
                        <div className="login-demo-tx">
                          <div className="login-demo-name">{u.prenom} {u.nom}</div>
                          <div className="login-demo-titre">{u.titre}</div>
                        </div>
                        <span className={'role-badge role-' + roleCls(u.role)}>
                          {(u.role === 'admin' || u.role === 'super_admin') && <AIcon n="shield" style={{ width: 11, height: 11 }} />}
                          {roleLabel(u.role)}
                        </span>
                      </button>
                    ))}
                  </div>
                </>
              )}
            </>
          )}

          {/* ── Inscription ── */}
          {mode === 'signup' && (
            <>
              <div className="login-card-h">Créer un compte</div>
              <div className="login-card-s">Votre accès sera activé après vérification du courriel.</div>

              <div style={{ display: 'flex', gap: 10 }}>
                <div style={{ flex: 1 }}>
                  <label className="lbl">Prénom</label>
                  <input className="field" value={f.prenom} onChange={set('prenom')} />
                  <Err k="prenom" />
                </div>
                <div style={{ flex: 1 }}>
                  <label className="lbl">Nom</label>
                  <input className="field" value={f.nom} onChange={set('nom')} />
                  <Err k="nom" />
                </div>
              </div>
              <div style={{ height: 10 }} />
              <label className="lbl">Courriel</label>
              <input className="field" type="email" autoComplete="username" value={f.email} onChange={set('email')} />
              <Err k="email" />
              <div style={{ height: 10 }} />
              <label className="lbl">Mot de passe</label>
              <input className="field" type="password" autoComplete="new-password" value={f.password} onChange={set('password')} />
              <Err k="password" />
              <div style={{ height: 10 }} />
              <label className="lbl">Confirmer le mot de passe</label>
              <input className="field" type="password" autoComplete="new-password" value={f.confirm} onChange={set('confirm')} />
              <Err k="confirm" />

              <button className="btn accent login-go" disabled={busy} onClick={doSignup}>
                {busy ? 'Création…' : 'Créer mon compte'}
              </button>
              <div className="login-alt">Déjà un compte ? <button className="linkbtn" onClick={() => { setMode('login'); setMsg(null); setErrors({}); }}>Se connecter</button></div>
            </>
          )}
        </div>
      </div>
    </div>
  );
}

// ── Écran « en attente d'autorisation » (après vérif courriel) ──
function AwaitingScreen({ user, onLogout }) {
  const status = user.status;
  const logout = async () => { try { if (GPTOAuth.enabled) await GPTOAuth.logout(); } catch (_) {} onLogout(); };
  const disabled = status === 'disabled';
  return (
    <div className="login">
      <div className="login-brand-side">
        <div className="login-brand">
          <div className="login-logo">G</div>
          <div>
            <div className="login-brand-name">GO·PASSIF</div>
            <div className="login-brand-sub">Estimateur sur plan</div>
          </div>
        </div>
        <div className="login-tagline">
          <h1>Accès sur autorisation</h1>
          <p>Les comptes sont validés manuellement par un administrateur avant l'accès à l'application.</p>
        </div>
        <div className="login-foot">© 2026 GO·PASSIF · accès réservé à l’équipe</div>
      </div>
      <div className="login-card-side">
        <div className="login-card" style={{ textAlign: 'center' }}>
          <div style={{ width: 56, height: 56, borderRadius: '50%', margin: '4px auto 16px', display: 'grid', placeItems: 'center',
            background: disabled ? 'color-mix(in srgb,var(--danger,#d24b3e) 15%,transparent)' : 'color-mix(in srgb,var(--accent) 15%,transparent)' }}>
            <AIcon n={disabled ? 'alert' : 'check'} style={{ width: 26, height: 26, color: disabled ? 'var(--danger,#d24b3e)' : 'var(--accent)' }} />
          </div>
          {disabled ? <>
            <div className="login-card-h">Accès non autorisé</div>
            <div className="login-card-s">Votre compte n’a pas été autorisé, ou l’accès a été retiré. Contactez un administrateur GO·PASSIF si vous pensez qu’il s’agit d’une erreur.</div>
          </> : <>
            <div className="login-card-h">Courriel validé ✓</div>
            <div className="login-card-s">Votre adresse <b>{user.email}</b> est confirmée. Il reste une étape : un administrateur doit <b>autoriser votre accès</b>. Vous pourrez vous connecter dès qu’il aura approuvé votre compte.</div>
          </>}
          <button className="btn login-go" onClick={logout} style={{ marginTop: 20 }}>
            <AIcon n="logout" style={{ width: 15, height: 15 }} /> Se déconnecter
          </button>
        </div>
      </div>
    </div>
  );
}

// ── Menu utilisateur (pied de la barre latérale) ───────────────
function UserMenu({ user, onLogout }) {
  const [open, setOpen] = React.useState(false);
  const mail = user.courriel || user.email || '';
  const logout = async () => { try { if (GPTOAuth.enabled) await GPTOAuth.logout(); } catch (_) {} onLogout(); };
  return (
    <div className="usermenu">
      {open && <>
        <div className="sb-switch-backdrop" onClick={() => setOpen(false)} />
        <div className="usermenu-pop">
          <div className="usermenu-pop-head">
            <Avatar user={user} size={38} />
            <div style={{ minWidth: 0 }}>
              <div className="usermenu-name">{user.prenom} {user.nom}</div>
              <div className="usermenu-mail">{mail}</div>
            </div>
          </div>
          <div className={'role-badge role-' + roleCls(user.role)} style={{ margin: '2px 4px 8px' }}>
            {(user.role === 'admin' || user.role === 'super_admin') && <AIcon n="shield" style={{ width: 11, height: 11 }} />}
            {roleLabel(user.role)}
          </div>
          <button className="usermenu-item"><AIcon n="settings" /> Mon profil</button>
          <button className="usermenu-item danger" onClick={logout}><AIcon n="logout" /> Déconnexion</button>
        </div>
      </>}
      <button className="usermenu-btn" onClick={() => setOpen((o) => !o)}>
        <Avatar user={user} size={30} />
        <div className="usermenu-btn-tx">
          <div className="usermenu-btn-name">{user.prenom} {user.nom}</div>
          <div className={'usermenu-btn-role role-' + roleCls(user.role)}>{roleLabel(user.role)}</div>
        </div>
        <AIcon n="chevd" style={{ width: 14, height: 14, opacity: .6, flexShrink: 0 }} />
      </button>
    </div>
  );
}

Object.assign(window, { LoginScreen, UserMenu, Avatar, AwaitingScreen, roleLabel, roleCls, GPTOAuth });
