// Admin dashboard for the local-first BBQ app.

function StatCard({ label, value, hint }) {
  return (
    <div className="card" style={{ padding: 18 }}>
      <div className="mono" style={{ fontSize: 11, color: 'var(--coral)', letterSpacing: '0.16em', textTransform: 'uppercase' }}>{label}</div>
      <div className="serif" style={{ fontSize: 34, color: 'var(--green-900)', lineHeight: 1, marginTop: 8 }}>{value}</div>
      {hint && <div style={{ fontSize: 12, color: 'var(--ink-2)', marginTop: 8 }}>{hint}</div>}
    </div>
  );
}

function AdminTable({ columns, rows, empty }) {
  return (
    <div style={{ overflowX: 'auto' }}>
      <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 13 }}>
        <thead>
          <tr>
            {columns.map((c) => (
              <th key={c.key} style={{ textAlign: 'left', padding: '8px 10px', borderBottom: '1px solid var(--line)', color: 'var(--ink-2)', fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.12em' }}>{c.label}</th>
            ))}
          </tr>
        </thead>
        <tbody>
          {rows.length === 0 && (
            <tr>
              <td colSpan={columns.length} style={{ padding: 16, color: 'var(--ink-2)', textAlign: 'center' }}>{empty}</td>
            </tr>
          )}
          {rows.map((row, i) => (
            <tr key={row.id || i}>
              {columns.map((c) => (
                <td key={c.key} style={{ padding: '9px 10px', borderBottom: '1px solid var(--line)', verticalAlign: 'top' }}>{c.render ? c.render(row) : row[c.key]}</td>
              ))}
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

function downloadAdminJson(filename, rows) {
  const blob = new Blob([JSON.stringify(rows, null, 2)], { type: 'application/json;charset=utf-8' });
  const url = URL.createObjectURL(blob);
  const link = document.createElement('a');
  link.href = url;
  link.download = filename;
  link.click();
  URL.revokeObjectURL(url);
}

function registeredParticipantRows(rsvps) {
  return (rsvps || []).flatMap((rsvp) => {
    const baseId = rsvp.id || rsvp.email || rsvp.lastName || 'rsvp';
    const ages = String(rsvp.kidAges || '').split(',').map((age) => age.trim()).filter(Boolean);
    const buildRows = (kind, label, count, names, paysContribution) =>
      Array.from({ length: Math.max(0, parseInt(count, 10) || 0) }, (_, index) => {
        const name = String((names || [])[index] || '').trim();
        return {
          id: `${baseId}-${kind}-${index}`,
          name: name || (kind === 'adult' && index === 0 ? rsvp.lastName : 'Nom non renseigné'),
          category: label,
          age: kind === 'kid' ? ages[index] || '—' : '—',
          household: rsvp.lastName || '—',
          email: rsvp.email || '—',
          phone: rsvp.phone || '—',
          contribution: paysContribution ? `${BBQ_EVENT.contributionPerAdult} €` : 'Gratuit',
        };
      });
    return [
      ...buildRows('adult', 'Adulte', rsvp.adults, rsvp.participantAdults, true),
      ...buildRows('teen', 'Ado', rsvp.teens, rsvp.participantTeens, true),
      ...buildRows('kid', 'Enfant', rsvp.kids, rsvp.participantKids, false),
    ];
  });
}

function AdminPage({ state, actions, currentUserName = '' }) {
  const [exportOpen, setExportOpen] = useState(false);
  const [selectedLoginIds, setSelectedLoginIds] = useState([]);
  const [selectedActivityIds, setSelectedActivityIds] = useState([]);
  const rsvps = (state.rsvps || []).filter((rsvp) => !rsvp.cancelledAt);
  const potluckRows = (state.potluck || []).filter((entry) => !entry.retiredAt);
  const volunteerSignupRows = (state.volunteerSignups || []).filter((signup) => !signup.retiredAt);
  const totalGuests = rsvps.reduce((sum, r) => sum + (parseInt(r.totalGuests, 10) || 0), 0);
  const payingGuests = rsvps.reduce((sum, r) => sum + (parseInt(r.adults, 10) || 0) + (parseInt(r.teens, 10) || 0), 0);
  const contributionTotal = rsvps.reduce((sum, r) => sum + (parseInt(r.contributionTotal, 10) || 0), 0);
  const participantRows = registeredParticipantRows(rsvps);
  const allergyRows = rsvps.filter((r) => (r.allergies || '').trim() || r.dietary !== 'Aucune restriction');
  const votes = state.foodTallies || {};
  const loginRows = [...(state.loginRecords || [])]
    .filter((record) => !record.retiredAt)
    .sort((a, b) => new Date(b.timestamp) - new Date(a.timestamp));
  const activityRows = [...(state.activityRecords || [])]
    .filter((record) => !record.retiredAt)
    .sort((a, b) => new Date(b.timestamp) - new Date(a.timestamp));
  const selectedLoginRows = loginRows.filter((record) => selectedLoginIds.includes(record.id));
  const selectedActivityRows = activityRows.filter((record) => selectedActivityIds.includes(record.id));
  const loginExportRows = selectedLoginRows.length > 0 ? selectedLoginRows : loginRows;
  const activityExportRows = selectedActivityRows.length > 0 ? selectedActivityRows : activityRows;
  const announcementRows = [...(state.announcements || [])]
    .filter((announcement) => !announcement.retiredAt)
    .sort((a, b) => Number(!!b.pinned) - Number(!!a.pinned));
  const exportEvent = { ...BBQ_EVENT };
  delete exportEvent.adminPassword;
  delete exportEvent.familyPassword;
  const exportData = JSON.stringify({
    event: exportEvent,
    generatedAt: new Date().toISOString(),
    rsvps,
    potluck: potluckRows,
    volunteerSignups: volunteerSignupRows,
    participants: participantRows,
    reminders: state.reminderPrefs,
    foodTallies: state.foodTallies,
    announcements: state.announcements,
    uploadedMemories: state.uploadedMemories,
    loginRecords: loginRows,
    activityRecords: activityRows,
  }, null, 2);

  const voteSummary = Object.entries(votes).flatMap(([group, tallies]) =>
    Object.entries(tallies).map(([choice, count]) => ({ id: `${group}-${choice}`, group, choice, count }))
  ).sort((a, b) => b.count - a.count);
  const toggleSelectedId = (setter, id, selected) => {
    if (!id) return;
    setter((current) => {
      if (!selected) return current.filter((item) => item !== id);
      return current.includes(id) ? current : [...current, id];
    });
  };

  return (
    <div>
      <PageHero title="Tableau admin" sub="Vue locale des inscriptions, repas, bénévoles et points à finaliser." kind="green" label="Organisation BBQ" src="assets/generated/admin-hero.png" />

      <div className="container" style={{ paddingBottom: 36 }}>
        <div className="admin-grid">
          <StatCard label="Foyers inscrits" value={rsvps.length} hint={`${totalGuests} invités au total`} />
          <StatCard label="Participants payants" value={payingGuests} hint={`${BBQ_EVENT.contributionPerAdult} € par adulte/ado`} />
          <StatCard label="Contribution prévue" value={`${contributionTotal} €`} hint="Hors frais de paiement" />
          <StatCard label="Photos ajoutées" value={(state.uploadedMemories || []).length} hint="Synchronisées en production" />
          <StatCard label="Activités" value={activityRows.length} hint="Visites et actions du site" />
        </div>

        <div style={{ display: 'grid', gridTemplateColumns: '1.5fr 1fr', gap: 18, marginTop: 20 }}>
          <div className="card">
            <div style={{ display: 'flex', justifyContent: 'space-between', gap: 12, alignItems: 'center', marginBottom: 12 }}>
              <div>
                <div className="serif" style={{ fontSize: 22, color: 'var(--green-900)' }}>RSVP reçus</div>
                <div style={{ fontSize: 12, color: 'var(--ink-2)' }}>Liste de travail pour les organisateurs.</div>
              </div>
              <button className="btn btn-white" onClick={() => setExportOpen(!exportOpen)}>{exportOpen ? 'Masquer export' : 'Exporter JSON'}</button>
            </div>
            <AdminTable
              empty="Aucun RSVP pour le moment."
              columns={[
                { key: 'lastName', label: 'Foyer' },
                { key: 'email', label: 'Email' },
                { key: 'count', label: 'Invités', render: (r) => `${r.adults} adultes · ${r.teens} ados · ${r.kids} enfants` },
                { key: 'total', label: 'Total', render: (r) => `${r.contributionTotal || 0} €` },
                { key: 'action', label: 'Action', render: (r) => (
                  <button
                    className="btn btn-coral"
                    style={{ padding: '8px 12px', whiteSpace: 'nowrap' }}
                    onClick={() => {
                      if (window.confirm(`Annuler l'inscription de ${r.lastName || 'ce foyer'} ?`)) {
                        actions.cancelRSVP(r.id, currentUserName);
                      }
                    }}
                  >
                    Annuler
                  </button>
                ) },
              ]}
              rows={rsvps}
            />
            {exportOpen && (
              <textarea className="textarea mono" readOnly value={exportData} style={{ minHeight: 220, marginTop: 14, fontSize: 11 }} />
            )}
          </div>

          <div className="card">
            <div className="serif" style={{ fontSize: 22, color: 'var(--green-900)', marginBottom: 12 }}>Allergies & régimes</div>
            <AdminTable
              empty="Aucune restriction signalée."
              columns={[
                { key: 'lastName', label: 'Foyer' },
                { key: 'allergies', label: 'Allergies', render: (r) => r.allergies || '—' },
                { key: 'dietary', label: 'Régime' },
              ]}
              rows={allergyRows}
            />
          </div>
        </div>

        <div className="card" style={{ marginTop: 20 }}>
          <div className="serif" style={{ fontSize: 22, color: 'var(--green-900)', marginBottom: 6 }}>Participants inscrits</div>
          <div style={{ fontSize: 12, color: 'var(--ink-2)', marginBottom: 12 }}>Liste de toutes les personnes déclarées dans les inscriptions.</div>
          <AdminTable
            empty="Aucun participant inscrit."
            columns={[
              { key: 'name', label: 'Nom' },
              { key: 'category', label: 'Catégorie' },
              { key: 'age', label: 'Âge' },
              { key: 'household', label: 'Foyer' },
              { key: 'email', label: 'Email contact' },
              { key: 'phone', label: 'Téléphone' },
              { key: 'contribution', label: 'Contribution' },
            ]}
            rows={participantRows}
          />
        </div>

        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 18, marginTop: 20 }}>
          <div className="card">
            <div className="serif" style={{ fontSize: 22, color: 'var(--green-900)', marginBottom: 12 }}>Auberge espagnole</div>
            <AdminTable
              empty="Aucun plat réservé."
              columns={[
                { key: 'who', label: 'Qui' },
                { key: 'dish', label: 'Plat' },
                { key: 'kind', label: 'Type' },
                { key: 'servings', label: 'Portions' },
              ]}
              rows={potluckRows}
            />
          </div>

          <div className="card">
            <div className="serif" style={{ fontSize: 22, color: 'var(--green-900)', marginBottom: 12 }}>Bénévoles</div>
            <AdminTable
              empty="Aucune inscription bénévole."
              columns={[
                { key: 'role', label: 'Rôle' },
                { key: 'time', label: 'Horaire' },
                { key: 'filled', label: 'Statut', render: (r) => `${r.filled}/${r.need}` },
              ]}
              rows={state.volunteerRoles || []}
            />
          </div>
        </div>

        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 18, marginTop: 20 }}>
          <div className="card" style={{ gridColumn: '1 / -1' }}>
            <div className="serif" style={{ fontSize: 22, color: 'var(--green-900)', marginBottom: 6 }}>Annonces</div>
            <div style={{ fontSize: 12, color: 'var(--ink-2)', marginBottom: 12 }}>Choisissez l'annonce épinglée ou retirez une annonce de la page publique.</div>
            <AdminTable
              empty="Aucune annonce publiée."
              columns={[
                { key: 'status', label: 'Statut', render: (r) => r.pinned ? <span style={{ color: 'var(--gold)', display: 'inline-flex', alignItems: 'center', gap: 6, fontWeight: 700 }}><Icon.Pin s={12} /> Épinglée</span> : 'Normale' },
                { key: 'name', label: 'Auteur' },
                { key: 'date', label: 'Date' },
                { key: 'text', label: 'Message', render: (r) => <div style={{ maxWidth: 620, lineHeight: 1.45 }}>{r.text}</div> },
                { key: 'action', label: 'Action', render: (r) => (
                  <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
                    <button
                      className={r.pinned ? 'btn btn-white' : 'btn btn-ghost'}
                      style={{ padding: '8px 12px', whiteSpace: 'nowrap' }}
                      onClick={() => actions.setPinnedAnnouncement(r.id, !r.pinned, currentUserName)}
                    >
                      {r.pinned ? 'Désépingler' : 'Épingler'}
                    </button>
                    <button
                      className="btn btn-coral"
                      style={{ padding: '8px 12px', whiteSpace: 'nowrap' }}
                      onClick={() => {
                        if (window.confirm('Supprimer cette annonce de la page publique ?')) {
                          actions.retireAnnouncement(r.id, currentUserName);
                        }
                      }}
                    >
                      Supprimer
                    </button>
                  </div>
                ) },
              ]}
              rows={announcementRows}
            />
          </div>

          <div className="card" style={{ gridColumn: '1 / -1' }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', gap: 12, alignItems: 'flex-start', marginBottom: 12 }}>
              <div>
                <div className="serif" style={{ fontSize: 22, color: 'var(--green-900)', marginBottom: 6 }}>Connexions</div>
                <div style={{ fontSize: 12, color: 'var(--ink-2)' }}>Journal local des accès. IP et pays sont capturés côté navigateur quand le service externe répond.</div>
              </div>
              <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', justifyContent: 'flex-end' }}>
                <button className="btn btn-white" style={{ padding: '8px 12px', whiteSpace: 'nowrap' }} onClick={() => downloadAdminJson('bbq-connexions.json', loginExportRows)}>
                  Exporter JSON{selectedLoginRows.length > 0 ? ` (${selectedLoginRows.length})` : ''}
                </button>
                <button
                  className="btn btn-coral"
                  style={{ padding: '8px 12px', whiteSpace: 'nowrap' }}
                  disabled={selectedLoginRows.length === 0}
                  onClick={() => {
                    if (window.confirm(`Supprimer ${selectedLoginRows.length} connexion${selectedLoginRows.length === 1 ? '' : 's'} sélectionnée${selectedLoginRows.length === 1 ? '' : 's'} ?`)) {
                      actions.retireLogs('loginRecords', currentUserName, selectedLoginRows.map((record) => record.id));
                      setSelectedLoginIds([]);
                    }
                  }}
                >
                  Supprimer sélection
                </button>
              </div>
            </div>
            <AdminTable
              empty="Aucune connexion enregistrée."
              columns={[
                { key: 'select', label: <label className="checkbox" style={{ margin: 0 }}><input type="checkbox" checked={loginRows.length > 0 && selectedLoginRows.length === loginRows.length} onChange={(e) => setSelectedLoginIds(e.target.checked ? loginRows.map((record) => record.id).filter(Boolean) : [])} /> Tout</label>, render: (r) => <input type="checkbox" aria-label={`Sélectionner ${r.name || 'connexion'}`} checked={selectedLoginIds.includes(r.id)} disabled={!r.id} onChange={(e) => toggleSelectedId(setSelectedLoginIds, r.id, e.target.checked)} /> },
                { key: 'name', label: 'Nom' },
                { key: 'access', label: 'Accès' },
                { key: 'date', label: 'Date' },
                { key: 'time', label: 'Heure' },
                { key: 'ip', label: 'IP' },
                { key: 'country', label: 'Pays' },
                { key: 'browser', label: 'Navigateur' },
                { key: 'os', label: 'OS' },
              ]}
              rows={loginRows}
            />
          </div>

          <div className="card" style={{ gridColumn: '1 / -1' }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', gap: 12, alignItems: 'flex-start', marginBottom: 12 }}>
              <div>
                <div className="serif" style={{ fontSize: 22, color: 'var(--green-900)', marginBottom: 6 }}>Activité du site</div>
                <div style={{ fontSize: 12, color: 'var(--ink-2)' }}>Dernières actions enregistrées : pages visitées, inscriptions, uploads, téléchargements, préférences et bénévoles.</div>
              </div>
              <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', justifyContent: 'flex-end' }}>
                <button className="btn btn-white" style={{ padding: '8px 12px', whiteSpace: 'nowrap' }} onClick={() => downloadAdminJson('bbq-activite-site.json', activityExportRows)}>
                  Exporter JSON{selectedActivityRows.length > 0 ? ` (${selectedActivityRows.length})` : ''}
                </button>
                <button
                  className="btn btn-coral"
                  style={{ padding: '8px 12px', whiteSpace: 'nowrap' }}
                  disabled={selectedActivityRows.length === 0}
                  onClick={() => {
                    if (window.confirm(`Supprimer ${selectedActivityRows.length} activité${selectedActivityRows.length === 1 ? '' : 's'} sélectionnée${selectedActivityRows.length === 1 ? '' : 's'} ?`)) {
                      actions.retireLogs('activityRecords', currentUserName, selectedActivityRows.map((record) => record.id));
                      setSelectedActivityIds([]);
                    }
                  }}
                >
                  Supprimer sélection
                </button>
              </div>
            </div>
            <AdminTable
              empty="Aucune activité enregistrée."
              columns={[
                { key: 'select', label: <label className="checkbox" style={{ margin: 0 }}><input type="checkbox" checked={activityRows.length > 0 && selectedActivityRows.length === activityRows.length} onChange={(e) => setSelectedActivityIds(e.target.checked ? activityRows.map((record) => record.id).filter(Boolean) : [])} /> Tout</label>, render: (r) => <input type="checkbox" aria-label={`Sélectionner ${r.label || 'activité'}`} checked={selectedActivityIds.includes(r.id)} disabled={!r.id} onChange={(e) => toggleSelectedId(setSelectedActivityIds, r.id, e.target.checked)} /> },
                { key: 'name', label: 'Nom' },
                { key: 'label', label: 'Action' },
                { key: 'pageLabel', label: 'Page' },
                { key: 'detail', label: 'Détail', render: (r) => r.detail || '—' },
                { key: 'date', label: 'Date' },
                { key: 'time', label: 'Heure' },
                { key: 'browser', label: 'Navigateur' },
                { key: 'os', label: 'OS' },
              ]}
              rows={activityRows}
            />
          </div>

          <div className="card">
            <div className="serif" style={{ fontSize: 22, color: 'var(--green-900)', marginBottom: 12 }}>Votes repas</div>
            <AdminTable
              empty="Aucun vote enregistré."
              columns={[
                { key: 'group', label: 'Catégorie' },
                { key: 'choice', label: 'Choix' },
                { key: 'count', label: 'Votes' },
              ]}
              rows={voteSummary}
            />
          </div>

          <div className="card">
            <div className="serif" style={{ fontSize: 22, color: 'var(--green-900)', marginBottom: 8 }}>Mémoire pour plus tard</div>
            <div style={{ fontSize: 12, color: 'var(--ink-2)', marginBottom: 12 }}>Les décisions production à reprendre quand on connectera de vrais services.</div>
            <div style={{ display: 'grid', gap: 10 }}>
              {BBQ_PRODUCTION_NOTES.map((note) => (
                <div key={note.title} style={{ border: '1px solid var(--line)', borderRadius: 8, padding: 10, background: 'var(--cream)' }}>
                  <div style={{ fontWeight: 700, color: 'var(--green-900)', fontSize: 13 }}>{note.title}</div>
                  <div style={{ color: 'var(--ink-2)', fontSize: 12, lineHeight: 1.45 }}>{note.detail}</div>
                </div>
              ))}
            </div>
            <div className="h-divider" />
            <button className="btn btn-ghost" onClick={() => actions.resetLocalData()}>Réinitialiser les données locales</button>
          </div>
        </div>
      </div>
      <Leaves />
    </div>
  );
}

window.AdminPage = AdminPage;
