/* ============================================================
   VT — Espace SUPERVISION (admin)
   Dashboard temps réel des visites techniques (polling) + détail
   (fiche prévisite, médias R2 signés, docs client, position GPS).
   ============================================================ */
const AdminAPI = (window.VT_CONFIG && window.VT_CONFIG.api) || {};

async function adminCall(body) {
  const r = await window.VT_AUTH.authedFetch(AdminAPI.base + '/vt_admin.php', {
    method: 'POST', headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(Object.assign({ k: AdminAPI.key }, body)),
  });
  const j = await r.json().catch(() => null);
  if (!j || !j.ok) throw new Error((j && j.error) || ('HTTP ' + r.status));
  return j;
}

function fmtDT(s) {
  if (!s) return '—';
  const d = new Date(String(s).replace(' ', 'T'));
  if (isNaN(d)) return s;
  return d.toLocaleString('fr-FR', { day: '2-digit', month: '2-digit', hour: '2-digit', minute: '2-digit' });
}
function poseurShort(email) {
  if (!email) return '—';
  const m = String(email).match(/^agence[.\-]?([^@]*)@/i);
  if (m && m[1]) return 'Agence ' + m[1].replace(/[.\-_]+/g, ' ').replace(/\b\w/g, c => c.toUpperCase());
  return email.split('@')[0].replace(/[.\-_]+/g, ' ').replace(/\b\w/g, c => c.toUpperCase());
}
function StatusBadge({ s }) {
  const cfg = s === 'envoyee'
    ? { txt: 'Envoyée', bg: '#e7f6ee', fg: '#1f8a5b' }
    : { txt: '● En cours', bg: '#fdf0e0', fg: '#c07a1a' };
  return <span style={{ background: cfg.bg, color: cfg.fg, fontSize: 12, fontWeight: 800, padding: '3px 10px', borderRadius: 99, whiteSpace: 'nowrap' }}>{cfg.txt}</span>;
}
const seenKeyA = ref => 'vtchat_seen_' + ref;   // même clé que le panneau de chat → ouvrir la conversation efface l'alerte
function getSeenA(ref) { try { return parseInt(localStorage.getItem(seenKeyA(ref)) || '0', 10) || 0; } catch (e) { return 0; } }
function vtUnread(v) { return !!(v.chat && v.chat.last_poseur_id > getSeenA(v.vt_ref)); }

function MapLink({ pos, children }) {
  if (!pos) return null;
  return <a href={'https://maps.google.com/?q=' + pos.lat + ',' + pos.lng} target="_blank" rel="noreferrer" style={{ color: '#1c3a8f', fontWeight: 600 }}>{children || (pos.lat.toFixed(5) + ', ' + pos.lng.toFixed(5))}</a>;
}

/* ---------- libellés de la fiche prévisite ---------- */
const FICHE_LABELS = [
  ['total_m2', 'Total à isoler (m²)'], ['surface_hab', 'Surface habitable (m²)'], ['chauffage', 'Chauffage actuel'],
  ['ral', 'RAL (couleur)'], ['crepi_m2', 'Crépi (m²)'],
  ['perimetre_ml', '① Périmètre maison (ML)'], ['aretes_ml', '② Arêtes verticales (ML)'],
  ['ouvrants_ml', '③ Ouvrants (ML)'], ['couvertines_cm', '④ Couvertines prof. (cm)'],
  ['couronnement_ml', 'Haut. couronnement (ML)'], ['couvertines_couleur', 'Couleur couvertines'],
  ['nb_fenetres', 'Nb fenêtres'], ['fenetres_couleur', 'Couleur fenêtres'], ['fenetres_dims', 'Dims fenêtres'],
  ['volet_battant_nb', 'Volets battants'], ['volet_roulant', 'Volets roulants'],
  ['gond_diametre', 'Gonds Ø (mm)'], ['gond_nb', 'Gonds (nb)'], ['gonds', 'Gonds'],
  ['ral_valide_client', 'RAL validé avec le client'],
  ['commentaire', 'Commentaire'],
];

const SLOT_TITLES = { env: '🎥 Environnement', 'doc-cni': '🪪 CNI / Passeport', 'doc-impot': '🧾 Avis d’impôt', 'doc-domicile': '🏠 Justificatif de domicile', recap: '📋 Récapitulatif PDF (déposé au CRM + envoyé au client)', simulation: '🎨 Simulation couleur validée avec le client (photo réelle peinte)' };
function slotTitle(slot) {
  if (SLOT_TITLES[slot]) return SLOT_TITLES[slot];
  const m = slot.match(/^facade(\d+)$/);
  if (m) return '🏠 Façade ' + m[1];
  return slot;
}

/* ---------- détail d'une VT ---------- */
function AdminDetail({ id, onBack }) {
  const { useState, useEffect } = React;
  const [data, setData] = useState(null);
  const [err, setErr] = useState('');

  async function load() {
    try { setData(await adminCall({ action: 'detail', id_vt: id })); setErr(''); }
    catch (e) { setErr(String(e.message || e)); }
  }
  useEffect(() => {
    load();
    const t = setInterval(() => { load(); }, 8000);
    return () => clearInterval(t);
  }, [id]);

  if (err) return <div className="vt-wrap"><button className="btn btn-ghost" onClick={onBack}>← Retour</button><p className="muted" style={{ color: '#c0203a', marginTop: 12 }}>Erreur : {err}</p></div>;
  if (!data) return <div className="vt-wrap"><p className="muted">Chargement…</p></div>;

  const vt = data.vt, media = data.media || [];
  const bySlot = {};
  media.forEach(m => { (bySlot[m.slot] = bySlot[m.slot] || []).push(m); });
  const slots = Object.keys(bySlot).sort((a, b) => {
    const rank = s => s === 'env' ? 0 : (/^facade/.test(s) ? 1 : 2);
    return rank(a) - rank(b) || a.localeCompare(b, 'fr', { numeric: true });
  });
  const ficheRows = FICHE_LABELS.filter(([k]) => vt.fiche && String(vt.fiche[k] || '').trim() !== '');

  async function doDelete() {
    if (!window.confirm('Supprimer définitivement cette visite technique (' + vt.vt_ref + ') ?\nMédias, fiche et chat seront effacés.')) return;
    try { await adminCall({ action: 'delete', id_vt: vt.id_vt }); onBack(); }
    catch (e) { alert('Suppression impossible : ' + (e.message || e)); }
  }

  return (
    <div className="vt-wrap" style={{ maxWidth: 860 }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
        <button className="btn btn-ghost" onClick={onBack}>← Toutes les visites</button>
        <button className="btn btn-ghost" onClick={doDelete} style={{ color: '#c0203a', borderColor: '#f0c8cd', fontSize: 13 }}>🗑 Supprimer</button>
      </div>
      <div className="card" style={{ marginTop: 14 }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', gap: 10, flexWrap: 'wrap', alignItems: 'center' }}>
          <div>
            <div style={{ fontWeight: 800, fontSize: 18, color: '#0d1c4d' }}>{vt.client || 'Client'} <span className="muted" style={{ fontWeight: 500 }}>· chantier {vt.id_project}</span></div>
            <div className="muted" style={{ marginTop: 4 }}>{vt.adresse || 'Adresse non renseignée'}</div>
          </div>
          <StatusBadge s={vt.status} />
        </div>
        <div className="muted" style={{ marginTop: 10, lineHeight: 1.7 }}>
          👷 {poseurShort(vt.poseur)} <span style={{ opacity: .55 }}>({vt.poseur})</span><br />
          📍 Arrivée : {vt.arrival ? <>{fmtDT(vt.arrival.at)} · <MapLink pos={vt.arrival} />{vt.arrival.accuracy ? ' (±' + Math.round(vt.arrival.accuracy) + ' m)' : ''}</> : 'non captée'}<br />
          🕐 Démarrée {fmtDT(vt.created_at)}{vt.sent_at ? <> · envoyée {fmtDT(vt.sent_at)}</> : <> · dernière activité {fmtDT(vt.updated_at)}</>} · réf {vt.vt_ref}
        </div>
      </div>

      {window.VTChatPanel && (
        <div className="card" style={{ marginTop: 14 }}>
          <div style={{ fontWeight: 800, marginBottom: 8 }}>💬 Chat avec le poseur</div>
          <window.VTChatPanel vtRef={vt.vt_ref} mySide="admin" height={300} />
        </div>
      )}

      {ficheRows.length > 0 && (
        <div className="card" style={{ marginTop: 14 }}>
          <div style={{ fontWeight: 800, marginBottom: 10 }}>📐 Fiche de prévisite
            {vt.status === 'en_cours' && <span style={{ marginLeft: 8, fontSize: 11.5, fontWeight: 800, color: '#c07a1a', background: '#fdf0e0', padding: '2px 9px', borderRadius: 99 }}>✍️ en cours de saisie — mise à jour en direct</span>}
          </div>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill,minmax(210px,1fr))', gap: '8px 18px' }}>
            {ficheRows.map(([k, label]) => (
              <div key={k} style={k === 'commentaire' || k === 'fenetres_dims' ? { gridColumn: '1 / -1' } : null}>
                <div style={{ fontSize: 11.5, fontWeight: 700, color: '#8792a8', textTransform: 'uppercase', letterSpacing: '.3px' }}>{label}</div>
                <div style={{ fontWeight: 600, color: '#22304d', whiteSpace: 'pre-wrap' }}>{String(vt.fiche[k])}</div>
              </div>
            ))}
          </div>
        </div>
      )}
      {vt.status === 'envoyee' && ficheRows.length === 0 && (
        <div className="card" style={{ marginTop: 14 }}><span className="muted">Fiche de prévisite vide.</span></div>
      )}

      {slots.map(slot => (
        <div className="card" key={slot} style={{ marginTop: 14 }}>
          <div style={{ fontWeight: 800, marginBottom: 10 }}>{slotTitle(slot)} <span className="muted" style={{ fontWeight: 500 }}>· {bySlot[slot].length} fichier(s)</span></div>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill,minmax(150px,1fr))', gap: 10 }}>
            {bySlot[slot].map(m => (
              <div key={m.id_media} style={{ border: '1px solid #e5e9f0', borderRadius: 10, overflow: 'hidden', background: '#f7f9fc' }}>
                {m.kind === 'photo' && m.url && (
                  <a href={m.url} target="_blank" rel="noreferrer"><img src={m.url} style={{ width: '100%', aspectRatio: '4/3', objectFit: 'cover', display: 'block' }} loading="lazy" /></a>
                )}
                {m.kind === 'video' && m.url && (
                  <video src={m.url} controls preload="metadata" style={{ width: '100%', aspectRatio: '4/3', objectFit: 'cover', display: 'block', background: '#000' }} />
                )}
                {m.kind === 'doc' && (
                  <a href={m.url || '#'} target="_blank" rel="noreferrer" style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', aspectRatio: '4/3', fontSize: 34, textDecoration: 'none' }}>📄</a>
                )}
                <div style={{ padding: '6px 8px', fontSize: 11.5 }} className="muted">
                  {m.taken_at ? fmtDT(m.taken_at) : ''}{m.pos ? <> · <MapLink pos={m.pos}>GPS</MapLink></> : ''}
                  {m.size ? <> · {(m.size / 1024 / 1024).toFixed(1)} Mo</> : ''}
                </div>
              </div>
            ))}
          </div>
        </div>
      ))}
      {media.length === 0 && <div className="card" style={{ marginTop: 14 }}><span className="muted">Aucun média reçu pour le moment{vt.status === 'en_cours' ? ' — la visite est en cours.' : '.'}</span></div>}

      <p className="muted" style={{ marginTop: 14, fontSize: 12 }}>Les liens médias sont signés et expirent après 1 h — rechargez la page pour les renouveler.</p>
    </div>
  );
}

/* ---------- dashboard ---------- */
function AdminSpace() {
  const { useState, useEffect, useRef } = React;
  const [vts, setVts] = useState(null);
  const [err, setErr] = useState('');
  const [filter, setFilter] = useState('');       // '' | en_cours | envoyee
  const [q, setQ] = useState('');
  const [sel, setSel] = useState(null);           // id_vt sélectionnée
  const qRef = useRef(q); qRef.current = q;
  const fRef = useRef(filter); fRef.current = filter;

  async function load() {
    try {
      const j = await adminCall({ action: 'list', status: fRef.current || undefined, q: qRef.current || undefined });
      setVts(j.vts); setErr('');
    } catch (e) { setErr(String(e.message || e)); }
  }
  useEffect(() => {
    load();
    const t = setInterval(load, 10000);
    return () => clearInterval(t);
  }, []);
  useEffect(() => { load(); }, [filter]);
  useEffect(() => { const t = setTimeout(load, 350); return () => clearTimeout(t); }, [q]);

  const unreadVts = (vts || []).filter(vtUnread);
  useEffect(() => {
    document.title = (unreadVts.length ? '(' + unreadVts.length + ') 💬 ' : '') + 'Visite Technique — Groupe Verlaine';
  }, [unreadVts.length]);

  if (sel) return <AdminDetail id={sel} onBack={() => { setSel(null); load(); }} />;

  const chips = [['', 'Toutes'], ['en_cours', 'En cours'], ['envoyee', 'Envoyées']];
  const enCours = (vts || []).filter(v => v.status === 'en_cours').length;
  const lastUnread = unreadVts.slice().sort((a, b) => (b.chat.last_poseur_id - a.chat.last_poseur_id))[0];

  return (
    <div className="vt-wrap" style={{ maxWidth: 860 }}>
      <span className="pill pill-admin">Espace supervision</span>
      <h1 style={{ marginTop: 10 }}>Visites techniques</h1>
      <p className="sub">{vts === null ? 'Chargement…' : (enCours > 0 ? enCours + ' visite(s) en cours sur le terrain — actualisation automatique.' : 'Aucune visite en cours — actualisation automatique.')}</p>

      {lastUnread && (
        <div onClick={() => setSel(lastUnread.id_vt)} style={{
          marginTop: 14, background: 'linear-gradient(100deg,#e11d33,#b3122a)', color: '#fff', borderRadius: 14,
          padding: '13px 16px', cursor: 'pointer', display: 'flex', gap: 12, alignItems: 'center',
          boxShadow: '0 12px 30px -12px rgba(225,29,51,.55)', animation: 'vtPulse 1.6s ease infinite',
        }}>
          <span style={{ fontSize: 24 }}>💬</span>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontWeight: 800, fontSize: 14.5 }}>
              Message du technicien — {poseurShort(lastUnread.poseur)} · {lastUnread.client || ('chantier ' + lastUnread.id_project)}
              {unreadVts.length > 1 && <span style={{ opacity: .85, fontWeight: 600 }}> (+{unreadVts.length - 1} autre{unreadVts.length > 2 ? 's' : ''} conversation{unreadVts.length > 2 ? 's' : ''})</span>}
            </div>
            <div style={{ fontSize: 13.5, opacity: .92, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', marginTop: 2 }}>
              « {lastUnread.chat.text} »
            </div>
          </div>
          <span style={{ fontSize: 12.5, fontWeight: 800, background: 'rgba(255,255,255,.18)', padding: '7px 13px', borderRadius: 99, whiteSpace: 'nowrap' }}>Répondre ›</span>
        </div>
      )}

      <div style={{ display: 'flex', gap: 8, margin: '14px 0', flexWrap: 'wrap', alignItems: 'center' }}>
        {chips.map(([v, label]) => (
          <button key={v} onClick={() => setFilter(v)} className="btn" style={{
            padding: '7px 14px', borderRadius: 99, fontSize: 13.5, fontWeight: 700, cursor: 'pointer',
            border: '1.5px solid ' + (filter === v ? '#1c3a8f' : '#dfe4ec'),
            background: filter === v ? '#1c3a8f' : '#fff', color: filter === v ? '#fff' : '#40506b',
          }}>{label}</button>
        ))}
        <input placeholder="🔎 Client, adresse, poseur, n° chantier…" value={q} onChange={e => setQ(e.target.value)}
          style={{ flex: '1 1 220px', padding: '9px 13px', border: '1.5px solid #dfe4ec', borderRadius: 99, fontSize: 14 }} />
      </div>

      {err && <p className="muted" style={{ color: '#c0203a' }}>Erreur : {err}</p>}
      {vts !== null && vts.length === 0 && <div className="card" style={{ textAlign: 'center', padding: '30px 16px' }}><span className="muted">Aucune visite technique{filter || q ? ' pour ce filtre' : ' pour le moment'}.</span></div>}

      {(vts || []).map(v => (
        <div className="card" key={v.id_vt} onClick={() => setSel(v.id_vt)}
          style={{ marginBottom: 10, cursor: 'pointer', display: 'flex', gap: 12, alignItems: 'center' }}>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontWeight: 800, color: '#0d1c4d', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
              {v.client || 'Client ?'} <span className="muted" style={{ fontWeight: 500 }}>· {v.id_project}</span>
            </div>
            <div className="muted" style={{ fontSize: 13, marginTop: 3, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
              {v.adresse || '—'}
            </div>
            <div className="muted" style={{ fontSize: 12.5, marginTop: 3 }}>
              👷 {poseurShort(v.poseur)} · 📷 {v.n_photos} · 🎥 {v.n_videos} · 📄 {v.n_docs} · {v.status === 'envoyee' ? 'envoyée ' + fmtDT(v.sent_at) : 'démarrée ' + fmtDT(v.created_at)}
            </div>
          </div>
          {vtUnread(v) && <span style={{ background: '#e11d33', color: '#fff', fontSize: 11.5, fontWeight: 800, padding: '4px 10px', borderRadius: 99, whiteSpace: 'nowrap', animation: 'vtPulse 1.6s ease infinite' }}>💬 nouveau</span>}
          <StatusBadge s={v.status} />
          <span style={{ color: '#a9b2c4', fontSize: 20 }}>›</span>
        </div>
      ))}
    </div>
  );
}
window.AdminSpace = AdminSpace;
