/* =============================================================================
   Admin — Candidats intervenants (liste + approbation)
   Route : #admin  (protégé par mot de passe, vérifié côté serveur)
   Dépend de : /api/admin (candidats + demandes + matching)
   ============================================================================= */

const ADMIN_PW_KEY = 'ms_admin_pw';

const MS = {
  ink: '#1F2420',
  ink2: '#3B423D',
  ink3: '#6F7872',
  line: '#E5E1D8',
  bg: '#F6F4EF',
  surface: '#FFFFFF',
  primary: '#2C5449',
  accent: '#C2693E',
  amberBg: '#FBEFD9',
  amberInk: '#9A6A12',
  greenBg: '#E3EFEA',
};

const STATUS_META = {
  en_attente_entrevue: { label: "En attente d'entrevue", bg: MS.amberBg, ink: MS.amberInk },
  autorise_sterling: { label: 'Autorisé Sterling', bg: '#E1ECF7', ink: '#1F5C9A' },
  active: { label: 'Actif', bg: MS.greenBg, ink: MS.primary },
};

const FILTERS = [
  { id: 'en_attente_entrevue', label: 'En attente' },
  { id: 'autorise_sterling', label: 'Autorisés' },
  { id: 'active', label: 'Actifs' },
  { id: '', label: 'Tous' },
];

function adminHeaders(pw) {
  return { 'x-admin-password': pw, 'Content-Type': 'application/json' };
}

function fmtDate(iso) {
  if (!iso) return '—';
  try {
    return new Date(iso).toLocaleString('fr-CA', { dateStyle: 'medium', timeStyle: 'short' });
  } catch (e) {
    return iso;
  }
}

function AdminLogin({ onAuth }) {
  const [pw, setPw] = React.useState('');
  const [loading, setLoading] = React.useState(false);
  const [error, setError] = React.useState('');

  const submit = async (e) => {
    if (e) e.preventDefault();
    if (!pw || loading) return;
    setLoading(true);
    setError('');
    try {
      const res = await fetch('/api/admin?resource=intervenants&status=en_attente_entrevue', {
        headers: adminHeaders(pw),
      });
      if (res.status === 401) {
        setError('Mot de passe incorrect.');
        return;
      }
      if (!res.ok) {
        const data = await res.json().catch(() => ({}));
        setError(data.error || 'Erreur serveur.');
        return;
      }
      try { sessionStorage.setItem(ADMIN_PW_KEY, pw); } catch (e2) {}
      if (typeof window.msSyncMaintenanceGate === 'function') window.msSyncMaintenanceGate();
      onAuth(pw);
    } catch (e3) {
      setError('Connexion impossible.');
    } finally {
      setLoading(false);
    }
  };

  return (
    <div style={{ minHeight: '100vh', background: MS.bg, display: 'grid', placeItems: 'center', padding: 24 }}>
      <form onSubmit={submit} style={{ width: '100%', maxWidth: 380, background: MS.surface, border: `1px solid ${MS.line}`, borderRadius: 16, padding: 28 }}>
        <div style={{ fontFamily: 'Georgia, serif', fontSize: 22, color: MS.ink, marginBottom: 6 }}>Espace admin</div>
        <p style={{ fontSize: 14, color: MS.ink3, marginTop: 0, marginBottom: 20 }}>
          Candidats intervenants — accès réservé.
        </p>
        <label style={{ fontSize: 13, fontWeight: 600, color: MS.ink2 }}>Mot de passe</label>
        <input
          type="password"
          value={pw}
          onChange={(e) => setPw(e.target.value)}
          autoFocus
          style={{ width: '100%', marginTop: 8, marginBottom: 16, padding: '12px 14px', borderRadius: 12, border: `1px solid ${MS.line}`, fontSize: 16, boxSizing: 'border-box' }}
        />
        {error ? <div style={{ color: MS.accent, fontSize: 13, marginBottom: 12 }}>{error}</div> : null}
        <button
          type="submit"
          disabled={loading || !pw}
          style={{ width: '100%', padding: '12px 14px', borderRadius: 12, border: 'none', background: MS.primary, color: '#fff', fontSize: 15, fontWeight: 700, cursor: loading ? 'default' : 'pointer', opacity: loading || !pw ? 0.55 : 1 }}
        >
          {loading ? 'Connexion…' : 'Se connecter'}
        </button>
        <p style={{ fontSize: 13, color: MS.ink3, marginTop: 16, marginBottom: 0, textAlign: 'center' }}>
          Après connexion, utilisez <a href="#home" style={{ color: MS.primary }}>Prévisualiser le site</a> dans l'admin.
        </p>
      </form>
    </div>
  );
}

function StatusBadge({ status }) {
  const meta = STATUS_META[status] || { label: status, bg: MS.line, ink: MS.ink2 };
  return (
    <span style={{ display: 'inline-block', background: meta.bg, color: meta.ink, fontSize: 12, fontWeight: 700, padding: '4px 10px', borderRadius: 999 }}>
      {meta.label}
    </span>
  );
}

function CandidateCard({ rec, pw, onUpdated }) {
  const [busy, setBusy] = React.useState(false);
  const [msg, setMsg] = React.useState('');
  const name = [rec.prenom, rec.nom].filter(Boolean).join(' ') || '(sans nom)';

  const approve = async () => {
    if (busy) return;
    if (!window.confirm(`Approuver ${name} pour l'étape de sécurité ?\nUn courriel d'invitation Sterling lui sera envoyé.`)) return;
    setBusy(true);
    setMsg('');
    try {
      const res = await fetch('/api/admin', {
        method: 'POST',
        headers: adminHeaders(pw),
        body: JSON.stringify({ action: 'approve', id: rec.id }),
      });
      const data = await res.json().catch(() => ({}));
      if (!res.ok) {
        setMsg(data.error || 'Échec.');
        return;
      }
      onUpdated(data.intervenant, data.invitationSent ? 'Invitation envoyée ✅' : `Statut mis à jour (courriel non envoyé : ${data.invitationError || '—'})`);
    } catch (e) {
      setMsg('Connexion impossible.');
    } finally {
      setBusy(false);
    }
  };

  return (
    <div style={{ background: MS.surface, border: `1px solid ${MS.line}`, borderRadius: 14, padding: 16, marginBottom: 12 }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 12, flexWrap: 'wrap' }}>
        <div style={{ minWidth: 200 }}>
          <div style={{ fontSize: 16, fontWeight: 700, color: MS.ink }}>{name}</div>
          <div style={{ fontSize: 13, color: MS.ink3, marginTop: 2 }}>{rec.institution || '—'}</div>
          <div style={{ fontSize: 13, color: MS.ink2, marginTop: 8 }}>
            <a href={`mailto:${rec.email}`} style={{ color: MS.primary }}>{rec.email}</a>
            {rec.phone ? <span> · <a href={`tel:${rec.phone}`} style={{ color: MS.primary }}>{rec.phone}</a></span> : null}
          </div>
          <div style={{ fontSize: 12, color: MS.ink3, marginTop: 6 }}>Reçu le {fmtDate(rec.createdAt)}</div>
        </div>
        <StatusBadge status={rec.status} />
      </div>

      {rec.status === 'en_attente_entrevue' ? (
        <button
          onClick={approve}
          disabled={busy}
          style={{ marginTop: 14, width: '100%', padding: '11px 14px', borderRadius: 10, border: 'none', background: '#1F8A4C', color: '#fff', fontSize: 14, fontWeight: 700, cursor: busy ? 'default' : 'pointer', opacity: busy ? 0.6 : 1 }}
        >
          {busy ? 'Traitement…' : '✅ Approuver pour l’étape de sécurité'}
        </button>
      ) : null}

      {rec.status === 'autorise_sterling' ? (
        <ActivateButton rec={rec} pw={pw} onUpdated={onUpdated} />
      ) : null}

      {msg ? <div style={{ marginTop: 10, fontSize: 13, color: MS.ink2 }}>{msg}</div> : null}
    </div>
  );
}

function ActivateButton({ rec, pw, onUpdated }) {
  const [busy, setBusy] = React.useState(false);
  const [msg, setMsg] = React.useState('');
  const name = [rec.prenom, rec.nom].filter(Boolean).join(' ') || '(sans nom)';

  const activate = async () => {
    if (busy) return;
    if (!window.confirm(`Activer ${name} (Sterling complété) ?`)) return;
    setBusy(true);
    setMsg('');
    try {
      const res = await fetch('/api/admin', {
        method: 'POST',
        headers: adminHeaders(pw),
        body: JSON.stringify({ action: 'activate', id: rec.id }),
      });
      const data = await res.json().catch(() => ({}));
      if (!res.ok) { setMsg(data.error || 'Échec.'); return; }
      onUpdated(data.intervenant, `${name} est maintenant actif ✅`);
    } catch (e) {
      setMsg('Connexion impossible.');
    } finally {
      setBusy(false);
    }
  };

  return (
    <>
      <button
        onClick={activate}
        disabled={busy}
        style={{ marginTop: 14, width: '100%', padding: '11px 14px', borderRadius: 10, border: 'none', background: MS.primary, color: '#fff', fontSize: 14, fontWeight: 700, cursor: busy ? 'default' : 'pointer', opacity: busy ? 0.6 : 1 }}
      >
        {busy ? 'Traitement…' : '✓ Activer (Sterling complété)'}
      </button>
      {msg ? <div style={{ marginTop: 10, fontSize: 13, color: MS.ink2 }}>{msg}</div> : null}
    </>
  );
}

function DemandeCard({ d, actifs, pw, onMatched }) {
  const [ivId, setIvId] = React.useState('');
  const [busy, setBusy] = React.useState(false);
  const [msg, setMsg] = React.useState('');
  const client = d.client || {};

  const match = async () => {
    if (!ivId || busy) return;
    setBusy(true);
    setMsg('');
    try {
      const res = await fetch('/api/admin', {
        method: 'POST',
        headers: adminHeaders(pw),
        body: JSON.stringify({ action: 'match', demandeId: d.id, intervenantId: ivId }),
      });
      const data = await res.json().catch(() => ({}));
      if (!res.ok) { setMsg(data.error || 'Échec.'); return; }
      onMatched(data.demande, 'Assignation effectuée ✅');
    } catch (e) {
      setMsg('Connexion impossible.');
    } finally {
      setBusy(false);
    }
  };

  const iv = d.intervenant || {};
  const ivName = [iv.prenom, iv.nom].filter(Boolean).join(' ');

  return (
    <div style={{ background: MS.surface, border: `1px solid ${MS.line}`, borderRadius: 14, padding: 16, marginBottom: 12 }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 12, flexWrap: 'wrap' }}>
        <div style={{ minWidth: 200 }}>
          <div style={{ fontSize: 16, fontWeight: 700, color: MS.ink }}>{client.name || '—'}</div>
          <div style={{ fontSize: 13, color: MS.ink3, marginTop: 2 }}>Pour : {d.beneficiary || '—'}</div>
          <div style={{ fontSize: 13, color: MS.ink2, marginTop: 8 }}>{d.tierLabel || '—'} · {d.frequencyLabel || '—'}</div>
          <div style={{ fontSize: 13, color: MS.ink2, marginTop: 4 }}>
            {(d.days || []).join(' · ')} {d.slot ? `· ${d.slot}` : ''}
          </div>
          <div style={{ fontSize: 12, color: MS.ink3, marginTop: 6 }}>
            <a href={`mailto:${client.email}`} style={{ color: MS.primary }}>{client.email}</a>
            {client.phone ? <span> · {client.phone}</span> : null}
          </div>
          <div style={{ fontSize: 12, color: MS.ink3, marginTop: 4 }}>Reçue le {fmtDate(d.createdAt)}</div>
        </div>
        <StatusBadge status={d.status === 'confirmed' ? 'active' : 'en_attente_entrevue'} />
      </div>

      {d.status === 'confirmed' && ivName ? (
        <div style={{ marginTop: 12, fontSize: 14, color: MS.primary, fontWeight: 600 }}>
          Assigné·e : {ivName} ({iv.institution || '—'})
        </div>
      ) : null}

      {d.status === 'pending' && actifs.length > 0 ? (
        <div style={{ marginTop: 14 }}>
          <select
            value={ivId}
            onChange={(e) => setIvId(e.target.value)}
            style={{ width: '100%', padding: '10px 12px', borderRadius: 10, border: `1px solid ${MS.line}`, fontSize: 14, marginBottom: 8 }}
          >
            <option value="">Choisir un intervenant actif…</option>
            {actifs.map((a) => (
              <option key={a.id} value={a.id}>
                {[a.prenom, a.nom].filter(Boolean).join(' ')} — {a.institution || '—'}
              </option>
            ))}
          </select>
          <button
            onClick={match}
            disabled={busy || !ivId}
            style={{ width: '100%', padding: '11px 14px', borderRadius: 10, border: 'none', background: MS.primary, color: '#fff', fontSize: 14, fontWeight: 700, cursor: busy || !ivId ? 'default' : 'pointer', opacity: busy || !ivId ? 0.55 : 1 }}
          >
            {busy ? 'Assignation…' : 'Assigner à cette famille'}
          </button>
        </div>
      ) : null}

      {d.status === 'pending' && actifs.length === 0 ? (
        <div style={{ marginTop: 12, fontSize: 13, color: MS.amberInk, background: MS.amberBg, borderRadius: 8, padding: '8px 12px' }}>
          Aucun intervenant actif disponible. Activez d'abord un candidat Sterling.
        </div>
      ) : null}

      {msg ? <div style={{ marginTop: 10, fontSize: 13, color: MS.ink2 }}>{msg}</div> : null}
    </div>
  );
}

function DemandesPanel({ pw, onLogout }) {
  const [filter, setFilter] = React.useState('pending');
  const [rows, setRows] = React.useState([]);
  const [actifs, setActifs] = React.useState([]);
  const [counts, setCounts] = React.useState({ total: 0 });
  const [loading, setLoading] = React.useState(true);
  const [error, setError] = React.useState('');
  const [flash, setFlash] = React.useState('');

  const load = React.useCallback(async () => {
    setLoading(true);
    setError('');
    try {
      const qs = filter ? `&status=${encodeURIComponent(filter)}` : '';
      const [resD, resI] = await Promise.all([
        fetch(`/api/admin?resource=demandes${qs}`, { headers: adminHeaders(pw) }),
        fetch('/api/admin?resource=intervenants&status=active', { headers: adminHeaders(pw) }),
      ]);
      if (resD.status === 401) { onLogout(); return; }
      const dataD = await resD.json().catch(() => ({}));
      const dataI = await resI.json().catch(() => ({}));
      if (!resD.ok) { setError(dataD.error || 'Erreur serveur.'); return; }
      setRows(dataD.demandes || []);
      setCounts(dataD.counts || { total: 0 });
      setActifs(dataI.intervenants || []);
    } catch (e) {
      setError('Connexion impossible.');
    } finally {
      setLoading(false);
    }
  }, [filter, pw, onLogout]);

  React.useEffect(() => { load(); }, [load]);

  const onMatched = (updated, message) => {
    setFlash(message || 'Mis à jour.');
    setRows((prev) => prev.filter((r) => r.id !== updated.id || (!filter || updated.status === filter)));
    window.setTimeout(() => setFlash(''), 4000);
    load();
  };

  const DEMANDE_FILTERS = [
    { id: 'pending', label: 'En attente' },
    { id: 'confirmed', label: 'Confirmées' },
    { id: '', label: 'Toutes' },
  ];

  return (
    <>
      <p style={{ fontSize: 14, color: MS.ink3, marginTop: 0 }}>
        {counts.total} demande{counts.total > 1 ? 's' : ''} ·
        {' '}{counts.pending || 0} en attente ·
        {' '}{counts.confirmed || 0} confirmées ·
        {' '}{actifs.length} intervenant{actifs.length > 1 ? 's' : ''} actif{actifs.length > 1 ? 's' : ''}
      </p>

      <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', margin: '16px 0 20px' }}>
        {DEMANDE_FILTERS.map((f) => {
          const active = filter === f.id;
          return (
            <button
              key={f.id || 'all'}
              onClick={() => setFilter(f.id)}
              style={{ padding: '8px 14px', borderRadius: 999, border: `1px solid ${active ? MS.primary : MS.line}`, background: active ? MS.primary : MS.surface, color: active ? '#fff' : MS.ink2, fontSize: 13, fontWeight: 600, cursor: 'pointer' }}
            >
              {f.label}
            </button>
          );
        })}
        <button onClick={load} style={{ padding: '8px 14px', borderRadius: 999, border: `1px solid ${MS.line}`, background: MS.surface, color: MS.ink3, fontSize: 13, cursor: 'pointer', marginLeft: 'auto' }}>↻ Actualiser</button>
      </div>

      {flash ? <div style={{ background: MS.greenBg, color: MS.primary, borderRadius: 10, padding: '10px 14px', fontSize: 14, marginBottom: 14 }}>{flash}</div> : null}
      {error ? <div style={{ background: '#FBE9E4', color: MS.accent, borderRadius: 10, padding: '10px 14px', fontSize: 14, marginBottom: 14 }}>{error}</div> : null}

      {loading ? (
        <div style={{ color: MS.ink3, fontSize: 14, padding: 24, textAlign: 'center' }}>Chargement…</div>
      ) : rows.length === 0 ? (
        <div style={{ background: MS.surface, border: `1px solid ${MS.line}`, borderRadius: 14, padding: 28, textAlign: 'center', color: MS.ink3 }}>
          Aucune demande dans cette catégorie.
        </div>
      ) : (
        rows.map((d) => <DemandeCard key={d.id} d={d} actifs={actifs} pw={pw} onMatched={onMatched} />)
      )}
    </>
  );
}

function CandidatsPanel({ pw, onLogout }) {
  const [filter, setFilter] = React.useState('en_attente_entrevue');
  const [rows, setRows] = React.useState([]);
  const [counts, setCounts] = React.useState({ total: 0 });
  const [loading, setLoading] = React.useState(true);
  const [error, setError] = React.useState('');
  const [flash, setFlash] = React.useState('');

  const load = React.useCallback(async () => {
    setLoading(true);
    setError('');
    try {
      const qs = filter ? `&status=${encodeURIComponent(filter)}` : '';
      const res = await fetch(`/api/admin?resource=intervenants${qs}`, { headers: adminHeaders(pw) });
      if (res.status === 401) { onLogout(); return; }
      const data = await res.json().catch(() => ({}));
      if (!res.ok) { setError(data.error || 'Erreur serveur.'); return; }
      setRows(data.intervenants || []);
      setCounts(data.counts || { total: 0 });
    } catch (e) {
      setError('Connexion impossible.');
    } finally {
      setLoading(false);
    }
  }, [filter, pw, onLogout]);

  React.useEffect(() => { load(); }, [load]);

  const onUpdated = (updated, message) => {
    setFlash(message || 'Mis à jour.');
    setRows((prev) => prev.filter((r) => r.id !== updated.id || (!filter || updated.status === filter)));
    window.setTimeout(() => setFlash(''), 4000);
    load();
  };

  return (
    <>
      <p style={{ fontSize: 14, color: MS.ink3, marginTop: 0 }}>
        {counts.total} candidature{counts.total > 1 ? 's' : ''} ·
        {' '}{counts.en_attente_entrevue || 0} en attente ·
        {' '}{counts.autorise_sterling || 0} autorisés ·
        {' '}{counts.active || 0} actifs
      </p>

      <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', margin: '16px 0 20px' }}>
        {FILTERS.map((f) => {
          const active = filter === f.id;
          return (
            <button
              key={f.id || 'all'}
              onClick={() => setFilter(f.id)}
              style={{ padding: '8px 14px', borderRadius: 999, border: `1px solid ${active ? MS.primary : MS.line}`, background: active ? MS.primary : MS.surface, color: active ? '#fff' : MS.ink2, fontSize: 13, fontWeight: 600, cursor: 'pointer' }}
            >
              {f.label}
            </button>
          );
        })}
        <button onClick={load} style={{ padding: '8px 14px', borderRadius: 999, border: `1px solid ${MS.line}`, background: MS.surface, color: MS.ink3, fontSize: 13, cursor: 'pointer', marginLeft: 'auto' }}>↻ Actualiser</button>
      </div>

      {flash ? <div style={{ background: MS.greenBg, color: MS.primary, borderRadius: 10, padding: '10px 14px', fontSize: 14, marginBottom: 14 }}>{flash}</div> : null}
      {error ? <div style={{ background: '#FBE9E4', color: MS.accent, borderRadius: 10, padding: '10px 14px', fontSize: 14, marginBottom: 14 }}>{error}</div> : null}

      {loading ? (
        <div style={{ color: MS.ink3, fontSize: 14, padding: 24, textAlign: 'center' }}>Chargement…</div>
      ) : rows.length === 0 ? (
        <div style={{ background: MS.surface, border: `1px solid ${MS.line}`, borderRadius: 14, padding: 28, textAlign: 'center', color: MS.ink3 }}>
          Aucun candidat dans cette catégorie.
        </div>
      ) : (
        rows.map((rec) => <CandidateCard key={rec.id} rec={rec} pw={pw} onUpdated={onUpdated} />)
      )}
    </>
  );
}

function AdminDashboard({ pw, onLogout }) {
  const [tab, setTab] = React.useState('candidats');

  return (
    <div style={{ minHeight: '100vh', background: MS.bg }}>
      <div style={{ maxWidth: 760, margin: '0 auto', padding: '28px 20px 64px' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 6, flexWrap: 'wrap', gap: 10 }}>
          <div style={{ fontFamily: 'Georgia, serif', fontSize: 26, color: MS.ink }}>Espace admin</div>
          <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
            <a href="#home" style={{ padding: '8px 12px', borderRadius: 10, border: `1px solid ${MS.primary}`, background: MS.greenBg, color: MS.primary, fontSize: 13, fontWeight: 600, textDecoration: 'none' }}>Prévisualiser le site</a>
            <button onClick={onLogout} style={{ background: 'none', border: `1px solid ${MS.line}`, borderRadius: 10, padding: '8px 12px', color: MS.ink3, fontSize: 13, cursor: 'pointer' }}>Déconnexion</button>
          </div>
        </div>

        <div style={{ display: 'flex', gap: 8, marginBottom: 20 }}>
          {[
            { id: 'candidats', label: 'Candidats' },
            { id: 'demandes', label: 'Demandes familles' },
          ].map((t) => {
            const active = tab === t.id;
            return (
              <button
                key={t.id}
                onClick={() => setTab(t.id)}
                style={{ padding: '10px 18px', borderRadius: 12, border: `1px solid ${active ? MS.primary : MS.line}`, background: active ? MS.primary : MS.surface, color: active ? '#fff' : MS.ink2, fontSize: 14, fontWeight: 700, cursor: 'pointer' }}
              >
                {t.label}
              </button>
            );
          })}
        </div>

        {tab === 'demandes' ? (
          <DemandesPanel pw={pw} onLogout={onLogout} />
        ) : (
          <CandidatsPanel pw={pw} onLogout={onLogout} />
        )}
      </div>
    </div>
  );
}

function AdminPage() {
  const [pw, setPw] = React.useState(() => {
    try { return sessionStorage.getItem(ADMIN_PW_KEY) || ''; } catch (e) { return ''; }
  });

  const logout = () => {
    try { sessionStorage.removeItem(ADMIN_PW_KEY); } catch (e) {}
    setPw('');
    if (typeof window.msSyncMaintenanceGate === 'function') window.msSyncMaintenanceGate();
  };

  if (!pw) return <AdminLogin onAuth={setPw} />;
  return <AdminDashboard pw={pw} onLogout={logout} />;
}

window.AdminPage = AdminPage;
