// Schedule (week view) + Screens + Stats
const { HOURS: SC_HOURS, DAYS: SC_DAYS, SCHEDULE_BLOCKS: SC_BLOCKS, SCREENS: SC_SCREENS, STATS_BARS: SC_BARS, STATS_TOP: SC_TOP } = window.DATA;

// Pastel color pairs for schedule blocks (bg, border, text)
const PASTEL = {
  "#F5A623": { bg: "#FEF3C7", border: "#FCD34D", text: "#92400E" },  // amber
  "#60A5FA": { bg: "#DBEAFE", border: "#93C5FD", text: "#1E40AF" },  // blue
  "#A78BFA": { bg: "#EDE9FE", border: "#C4B5FD", text: "#5B21B6" },  // purple
  "#34D399": { bg: "#D1FAE5", border: "#86EFAC", text: "#047857" },  // green
  "#F87171": { bg: "#FEE2E2", border: "#FCA5A5", text: "#B91C1C" },  // red
};

// =========== SCHEDULE ===========
function ScheduleBlockModal({ playlists, initial, onSubmit, onCancel, onDelete }) {
  const [playlist, setPlaylist] = React.useState(initial?.playlist || playlists[0]?.id);
  const [day, setDay] = React.useState(initial?.day ?? 0);
  const [h, setH] = React.useState(initial?.h ?? 0);
  const [span, setSpan] = React.useState(initial?.span ?? 2);

  if (playlists.length === 0) {
    return (
      <div className="modal-backdrop" onClick={onCancel}>
        <div className="modal" onClick={e => e.stopPropagation()}>
          <div className="modal__header">
            <div className="modal__title">Planifier un créneau</div>
            <button className="btn btn--sm btn--icon btn--ghost" onClick={onCancel}><Icon.X size={14} /></button>
          </div>
          <div className="modal__body">
            <div className="empty-state">
              <Icon.Playlist size={28} />
              <div className="empty-state__title">Aucune playlist</div>
              <div className="empty-state__sub">Créez d'abord une playlist depuis le menu Playlists.</div>
            </div>
          </div>
        </div>
      </div>
    );
  }

  return (
    <div className="modal-backdrop" onClick={onCancel}>
      <div className="modal" onClick={e => e.stopPropagation()}>
        <div className="modal__header">
          <div className="modal__title">{initial ? "Éditer le créneau" : "Planifier un créneau"}</div>
          <button className="btn btn--sm btn--icon btn--ghost" onClick={onCancel}><Icon.X size={14} /></button>
        </div>
        <div className="modal__body">
          <div className="form-field">
            <label>Playlist</label>
            <div className="playlist-radio-list">
              {playlists.map(p => (
                <button
                  key={p.id}
                  type="button"
                  className={"playlist-radio" + (playlist === p.id ? " is-active" : "")}
                  onClick={() => setPlaylist(p.id)}
                >
                  <span className="playlist-radio__strip" style={{ background: p.color }} />
                  <div style={{ flex: 1, textAlign: "left" }}>
                    <div style={{ fontSize: 12.5, fontWeight: 600 }}>{p.name}</div>
                    <div style={{ fontSize: 11, color: "var(--text-muted)" }}>{p.schedule}</div>
                  </div>
                  {playlist === p.id && <Icon.Check size={14} />}
                </button>
              ))}
            </div>
          </div>

          <div className="form-field">
            <label>Jour</label>
            <div className="day-row">
              {SC_DAYS.map((d, i) => (
                <button
                  key={i}
                  type="button"
                  className={"day-btn" + (day === i ? " is-active" : "")}
                  onClick={() => setDay(i)}
                >
                  {d.split(" ")[0]}
                </button>
              ))}
            </div>
          </div>

          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12 }}>
            <div className="form-field">
              <label>Début</label>
              <select className="form-input" value={h} onChange={e => setH(Number(e.target.value))}>
                {SC_HOURS.map((hr, i) => <option key={i} value={i}>{hr}</option>)}
              </select>
            </div>
            <div className="form-field">
              <label>Durée</label>
              <select className="form-input" value={span} onChange={e => setSpan(Number(e.target.value))}>
                {[1, 2, 3, 4, 5, 6, 7, 8].map(s => (
                  <option key={s} value={s}>{s} heure{s > 1 ? "s" : ""}</option>
                ))}
              </select>
            </div>
          </div>

          <div className="form-help">
            Créneau : <strong>{SC_DAYS[day]}</strong> de <strong>{SC_HOURS[h]}</strong> à <strong>{SC_HOURS[Math.min(h + span, SC_HOURS.length - 1)] || "20h"}</strong>
          </div>

          <div className="modal__actions">
            {onDelete && <button className="btn btn--danger" onClick={onDelete} style={{ marginRight: "auto" }}>
              <Icon.Trash size={12} /> Supprimer
            </button>}
            <button className="btn" onClick={onCancel}>Annuler</button>
            <button className="btn btn--primary" onClick={() => onSubmit({ playlist, day, h, span, color: playlists.find(p => p.id === playlist)?.color || "#F5A623" })}>
              {initial ? "Enregistrer" : "Planifier"}
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}

function Schedule({ playlists = [], scheduleBlocks = [], setScheduleBlocks, pushActivity }) {
  const [showModal, setShowModal] = React.useState(false);
  const [editingBlock, setEditingBlock] = React.useState(null); // index in scheduleBlocks
  const [confirmDel, setConfirmDel] = React.useState(null);
  const [toast, setToast] = React.useState(null);
  const flashToast = (text, icon) => { setToast({ text, icon }); setTimeout(() => setToast(null), 2400); };

  // Resolve schedule blocks: only show blocks whose playlist still exists
  const liveBlocks = scheduleBlocks
    .map((b, idx) => {
      const p = playlists.find(x => x.id === b.playlist);
      return p ? { ...b, idx, label: p.name, color: p.color, active: p.active } : null;
    })
    .filter(Boolean);

  // Unique playlists referenced in the schedule
  const legendPlaylists = Array.from(new Set(liveBlocks.map(b => b.playlist)))
    .map(id => playlists.find(p => p.id === id))
    .filter(Boolean);

  const handleSubmit = (data) => {
    if (editingBlock !== null) {
      setScheduleBlocks(prev => prev.map((b, i) => i === editingBlock ? { ...b, ...data } : b));
      const pl = playlists.find(p => p.id === data.playlist);
      pushActivity?.({ action: "a modifié le créneau", target: pl?.name || "Créneau", type: "schedule" });
      flashToast("Créneau mis à jour", <Icon.Check size={13} />);
    } else {
      setScheduleBlocks(prev => [...prev, data]);
      const pl = playlists.find(p => p.id === data.playlist);
      pushActivity?.({ action: "a planifié", target: pl?.name || "Créneau", type: "schedule" });
      flashToast("Créneau planifié", <Icon.Check size={13} />);
    }
    setShowModal(false);
    setEditingBlock(null);
  };

  const handleDelete = (idx) => {
    const block = scheduleBlocks[idx];
    const pl = playlists.find(p => p.id === block?.playlist);
    setScheduleBlocks(prev => prev.filter((_, i) => i !== idx));
    setConfirmDel(null);
    pushActivity?.({ action: "a supprimé le créneau", target: pl?.name || "Créneau", type: "alert" });
    flashToast("Créneau supprimé", <Icon.Trash size={13} />);
  };

  return (
    <div className="pane">
      <header className="pane__header">
        <div className="pane__title-group">
          <span className="pane__crumb">Régie · Calendrier</span>
          <h1 className="pane__title">Planning de diffusion</h1>
        </div>
        <div className="pane__actions">
          <div className="btn-group">
            <button className="btn btn--sm"><Icon.ChevronLeft size={12} /></button>
            <button className="btn btn--sm" style={{ padding: "4px 12px" }}>Aujourd'hui</button>
            <button className="btn btn--sm"><Icon.ChevronRight size={12} /></button>
          </div>
          <div className="btn-group">
            <button className="btn btn--sm">Jour</button>
            <button className="btn btn--sm is-active">Semaine</button>
            <button className="btn btn--sm">Mois</button>
          </div>
          <button className="btn"><Icon.Download /> Exporter</button>
          <button className="btn btn--primary" onClick={() => { setEditingBlock(null); setShowModal(true); }}><Icon.Plus /> Planifier</button>
        </div>
      </header>

      <div className="pane__body">
        <div style={{ display: "flex", alignItems: "center", gap: 12, marginBottom: 12 }}>
          <h2 style={{ fontFamily: "var(--font-display)", fontSize: 16, fontWeight: 700, margin: 0 }}>
            Semaine du 18 au 22 mai 2026
          </h2>
          <span className="badge badge--accent">Bordeaux · Tous écrans</span>
          <div style={{ marginLeft: "auto", display: "flex", gap: 6 }}>
            <button className="btn btn--sm btn--ghost"><Icon.Filter size={12} /> Filtrer par écran</button>
          </div>
        </div>

        <div className="schedule-grid">
          {/* Header row */}
          <div className="schedule-header" style={{ background: "var(--bg-deep)" }}>
            <div style={{ fontSize: 10, color: "var(--text-muted)", textTransform: "uppercase", letterSpacing: 0.06 }}>UTC+2</div>
          </div>
          {SC_DAYS.map((d, di) => {
            const today = di === 0;
            return (
              <div key={d} className={"schedule-header" + (today ? " schedule-header--today" : "")}>
                {d}
                <div className="schedule-header__sub">{today ? "Aujourd'hui" : ""}</div>
              </div>
            );
          })}

          {/* Hour rows */}
          {SC_HOURS.map((h, hi) => (
            <React.Fragment key={h}>
              <div className="schedule-hour">{h}</div>
              {SC_DAYS.map((_, di) => (
                <div key={di} className="schedule-cell">
                  {/* Blocks rendered absolutely positioned over the cell stack */}
                </div>
              ))}
            </React.Fragment>
          ))}

          {/* Blocks rendered as overlay using grid placement */}
          {liveBlocks.map((b, i) => {
            const colStart = b.day + 2;
            const rowStart = b.h + 2;
            const rowEnd = rowStart + b.span;
            const p = PASTEL[b.color] || { bg: "#F3F4F6", border: "#D1D5DB", text: "#374151" };
            return (
              <div
                key={i}
                className="schedule-block"
                style={{
                  gridColumn: `${colStart} / ${colStart + 1}`,
                  gridRow: `${rowStart} / ${rowEnd}`,
                  position: "relative",
                  left: 0, right: 0,
                  background: p.bg,
                  borderColor: p.border,
                  color: p.text,
                  borderLeftWidth: 3,
                  borderLeftColor: b.color,
                }}
                onClick={() => { setEditingBlock(b.idx); setShowModal(true); }}
                title="Cliquer pour éditer"
              >
                <div className="schedule-block__title">
                  {b.label}
                  {b.active && <span style={{ marginLeft: 5, display: "inline-block", width: 5, height: 5, borderRadius: "50%", background: "var(--live)", verticalAlign: "middle" }} />}
                </div>
                <div className="schedule-block__meta">
                  {SC_HOURS[b.h]} – {SC_HOURS[Math.min(b.h + b.span, SC_HOURS.length - 1)] || "20h"}
                </div>
              </div>
            );
          })}

          {/* "Now" indicator on Monday at 09h45 (offset into row index 2) */}
          <div className="schedule-now-line" style={{ top: 136 }} />
        </div>

        {/* Legend */}
        <div className="schedule-legend">
          {legendPlaylists.map(p => (
            <span key={p.id} className="schedule-legend__item">
              <span className="schedule-legend__dot" style={{ background: p.color }} /> {p.name}
              {p.active && <span className="badge badge--live" style={{ marginLeft: 4 }}>LIVE</span>}
            </span>
          ))}
          {legendPlaylists.length === 0 && (
            <span style={{ color: "var(--text-muted)", fontSize: 12 }}>Aucune playlist planifiée.</span>
          )}
        </div>
      </div>

      {/* Planning modal */}
      {showModal && (
        <ScheduleBlockModal
          playlists={playlists}
          initial={editingBlock !== null ? scheduleBlocks[editingBlock] : null}
          onSubmit={handleSubmit}
          onCancel={() => { setShowModal(false); setEditingBlock(null); }}
          onDelete={editingBlock !== null ? () => setConfirmDel(editingBlock) : null}
        />
      )}

      <window.ConfirmDialog
        open={confirmDel !== null}
        title="Supprimer ce créneau ?"
        message="Le créneau sera retiré du planning. Cette action est irréversible."
        danger
        onConfirm={() => { handleDelete(confirmDel); setShowModal(false); setEditingBlock(null); }}
        onCancel={() => setConfirmDel(null)}
      />
      <window.Toast msg={toast} />
    </div>
  );
}

// =========== SCREENS ===========
function ScreenPreview({ s, activePlaylist }) {
  if (s.status === "offline") {
    return (
      <div className="screen-card__preview screen-card__preview--offline">
        <Icon.Power size={24} />
        <div style={{ fontSize: 11, fontWeight: 700 }}>Aucune connexion</div>
        <div style={{ fontSize: 10, color: "var(--text-muted)", fontFamily: "var(--font-mono)" }}>{s.ip}</div>
      </div>
    );
  }
  if (s.status === "idle") {
    return (
      <div className="screen-card__preview" style={{
        background: "#1A1F2C",
        display: "flex", alignItems: "center", justifyContent: "center",
        flexDirection: "column", gap: 6,
        color: "rgba(255,255,255,0.5)"
      }}>
        <Icon.Pause size={20} />
        <div style={{ fontSize: 11, fontWeight: 500 }}>En veille</div>
        <span className="screen-card__status">
          <span className="screen-card__status-dot" style={{ background: "#D97706" }} /> Inactif
        </span>
      </div>
    );
  }
  // Online — show a mini 2x2 quadrant preview (what the giant screen displays)
  // If no active playlist, show "waiting" state
  if (!activePlaylist) {
    return (
      <div className="screen-card__preview" style={{
        background: "#0F1421",
        display: "flex", alignItems: "center", justifyContent: "center",
        flexDirection: "column", gap: 6,
        color: "rgba(255,255,255,0.5)"
      }}>
        <Icon.Broadcast size={20} />
        <div style={{ fontSize: 11, fontWeight: 500 }}>En attente</div>
        <span className="screen-card__status" style={{ background: "rgba(255,255,255,0.95)" }}>
          <span className="screen-card__status-dot" style={{ background: "#16A34A" }} /> En ligne
        </span>
        <div className="screen-card__resolution">{s.resolution}</div>
      </div>
    );
  }
  const firstA = activePlaylist.zones?.A?.[0];
  const firstB = activePlaylist.zones?.B?.[0];
  const firstC = activePlaylist.zones?.C?.[0];
  const firstD = activePlaylist.zones?.D?.[0];
  return (
    <div className="screen-card__preview">
      <div style={{
        position: "absolute", inset: 0,
        display: "grid",
        gridTemplateColumns: "1fr 1fr",
        gridTemplateRows: "1fr 1fr",
        gap: 1,
      }}>
        <div style={{ background: "#161C2D", padding: 10, paddingTop: 28, overflow: "hidden" }}>
          <div style={{ fontFamily: "var(--font-display)", fontSize: 10, fontWeight: 600, color: "#fff", lineHeight: 1.15, letterSpacing: "-0.01em", display: "-webkit-box", WebkitLineClamp: 2, WebkitBoxOrient: "vertical", overflow: "hidden" }}>
            {firstA?.title || "—"}
          </div>
        </div>
        <div style={{ background: "#1A1F2C", display: "flex", alignItems: "center", justifyContent: "center", flexDirection: "column", padding: 4 }}>
          <div style={{ fontFamily: "var(--font-display)", fontSize: 18, fontWeight: 700, color: "#fff", letterSpacing: "-0.03em", lineHeight: 1 }}>
            {firstB ? (firstB.type === "kpi" ? "247" : firstB.duration) : "—"}
          </div>
          <div style={{ fontSize: 7, color: "rgba(255,255,255,0.45)", textAlign: "center", lineHeight: 1.2, marginTop: 2, padding: "0 4px" }}>
            {firstB?.title?.slice(0, 24) || "—"}
          </div>
        </div>
        <div style={{ background: "linear-gradient(180deg, #34384A 0%, #1A1F2C 100%)", display: "flex", alignItems: "flex-end", padding: 6 }}>
          <div style={{ fontSize: 7, color: "rgba(255,255,255,0.7)", lineHeight: 1.2 }}>{firstC?.title?.slice(0, 22) || "—"}</div>
        </div>
        <div style={{ background: "#0F1825", padding: 6 }}>
          <div style={{ fontSize: 7, color: "#7DD3FC", fontWeight: 600 }}>{firstD?.type === "soc" ? "@elsia" : firstD?.type === "met" ? "Météo" : (firstD?.title || "—").slice(0, 14)}</div>
          <div style={{ fontSize: 7, color: "rgba(255,255,255,0.7)", marginTop: 2, lineHeight: 1.3 }}>{firstD?.title?.slice(0, 26) || "—"}</div>
        </div>
      </div>
      <span className="screen-card__status">
        <span className="screen-card__status-dot" style={{ background: "#16A34A" }} /> En ligne
      </span>
      <div className="screen-card__resolution">{s.resolution}</div>
    </div>
  );
}

function Screens({ activePlaylist, screens = [], setScreens, pushActivity }) {
  const [showModal, setShowModal] = React.useState(false);
  const [editingScreen, setEditingScreen] = React.useState(null);
  const [confirmDel, setConfirmDel] = React.useState(null);
  const [toast, setToast] = React.useState(null);
  const flashToast = (text, icon) => { setToast({ text, icon }); setTimeout(() => setToast(null), 2400); };

  const onlineCount = screens.filter(s => s.status === "online").length;
  const idleCount = screens.filter(s => s.status === "idle").length;
  const offlineCount = screens.filter(s => s.status === "offline").length;
  const broadcastingCount = activePlaylist ? onlineCount : 0;
  const availabilityPct = screens.length > 0 ? Math.round((onlineCount + idleCount) / screens.length * 100) : 0;

  const toggleStatus = (id) => {
    setScreens(prev => prev.map(s => {
      if (s.id !== id) return s;
      const next = s.status === "online" ? "idle" : s.status === "idle" ? "offline" : "online";
      pushActivity?.({
        who: "Système",
        action: next === "online" ? "a connecté" : next === "idle" ? "a mis en veille" : "a déconnecté",
        target: s.name,
        type: next === "offline" ? "alert" : next === "idle" ? "pause" : "play"
      });
      return { ...s, status: next, uptime: next === "offline" ? "—" : s.uptime };
    }));
  };

  const restartAll = () => {
    setScreens(prev => prev.map(s => ({ ...s, status: s.status === "offline" ? s.status : "online" })));
    pushActivity?.({ who: "Système", action: "a redémarré", target: "tous les écrans", type: "play" });
    flashToast("Écrans redémarrés", <Icon.Check size={13} />);
  };

  const handleSubmit = (data) => {
    if (editingScreen) {
      setScreens(prev => prev.map(s => s.id === editingScreen.id ? { ...s, ...data } : s));
      pushActivity?.({ action: "a modifié l'écran", target: data.name, type: "upload" });
      flashToast("Écran mis à jour", <Icon.Check size={13} />);
      if (window.ELSIA_API && editingScreen.id.startsWith("s_")) {
        window.ELSIA_API.updateScreen(editingScreen.id, data).catch(err => console.error("[api] updateScreen:", err));
      }
    } else {
      const tempId = "s" + Date.now();
      const newScreen = {
        id: tempId, ...data,
        status: "online",
        playing: "—",
        uptime: "0h 00m",
        brightness: 70,
      };
      setScreens(prev => [...prev, newScreen]);
      pushActivity?.({ action: "a connecté un nouvel écran", target: data.name, type: "publish" });
      flashToast(`Écran « ${data.name} » connecté`, <Icon.Check size={13} />);
      if (window.ELSIA_API) {
        window.ELSIA_API.createScreen(data)
          .then(persisted => {
            setScreens(prev => prev.map(s => s.id === tempId ? { ...persisted, playing: "—", uptime: "0h 00m" } : s));
          })
          .catch(err => console.error("[api] createScreen:", err));
      }
    }
    setShowModal(false);
    setEditingScreen(null);
  };

  const handleDelete = (id) => {
    const s = screens.find(x => x.id === id);
    setScreens(prev => prev.filter(x => x.id !== id));
    setConfirmDel(null);
    pushActivity?.({ action: "a retiré l'écran", target: s?.name || "Écran", type: "alert" });
    flashToast("Écran retiré", <Icon.Trash size={13} />);
    if (window.ELSIA_API && id.startsWith("s_")) {
      window.ELSIA_API.deleteScreen(id).catch(err => console.error("[api] deleteScreen:", err));
    }
  };

  return (
    <div className="pane">
      <header className="pane__header">
        <div className="pane__title-group">
          <span className="pane__crumb">Régie · Parc d'écrans</span>
          <h1 className="pane__title">Écrans</h1>
        </div>
        <div className="pane__actions">
          <div className="search">
            <Icon.Search />
            <input placeholder="Rechercher un écran…" />
          </div>
          <button className="btn" onClick={restartAll}><Icon.Power /> Redémarrer tout</button>
          <button className="btn btn--primary" onClick={() => { setEditingScreen(null); setShowModal(true); }}><Icon.Plus /> Connecter un écran</button>
        </div>
      </header>

      <div className="pane__body">
        {/* Overview stats */}
        <div className="kpi-row" style={{ gridTemplateColumns: "repeat(4, 1fr)" }}>
          <Kpi label="Écrans connectés" value={`${onlineCount + idleCount} / ${screens.length}`} sub={`${availabilityPct} % disponibles`} icon={Icon.Monitor} />
          <Kpi label="Diffusion active" value={String(broadcastingCount)} sub={activePlaylist ? activePlaylist.name : "Aucune playlist"} icon={Icon.Broadcast} />
          <Kpi label="En veille" value={String(idleCount)} sub="inactifs mais connectés" icon={Icon.Pause} />
          <Kpi label="Hors ligne" value={String(offlineCount)} sub={offlineCount > 0 ? "à diagnostiquer" : "tout va bien"} icon={Icon.AlertTriangle} />
        </div>

        {screens.length === 0 ? (
          <div className="empty-state" style={{ padding: 48 }}>
            <Icon.Monitor size={32} />
            <div className="empty-state__title">Aucun écran connecté</div>
            <div className="empty-state__sub">Connectez votre premier écran pour commencer à diffuser.</div>
            <button className="btn btn--primary" onClick={() => setShowModal(true)}>
              <Icon.Plus size={12} /> Connecter un écran
            </button>
          </div>
        ) : (
          <div className="screens-grid">
            {screens.map(s => (
              <div key={s.id} className="screen-card">
                <ScreenPreview s={s} activePlaylist={activePlaylist} />
                <div className="screen-card__body">
                  <div className="screen-card__name">
                    {s.name}
                    <div style={{ display: "flex", gap: 2 }}>
                      <button className="btn btn--sm btn--icon btn--ghost" onClick={() => { setEditingScreen(s); setShowModal(true); }} title="Éditer">
                        <Icon.Edit size={12} />
                      </button>
                      <button className="btn btn--sm btn--icon btn--ghost" onClick={() => setConfirmDel(s.id)} title="Retirer">
                        <Icon.Trash size={12} />
                      </button>
                    </div>
                  </div>
                  <div className="screen-card__location">{s.location} · {s.ip}</div>
                  <div className="screen-card__playing">
                    {s.status === "online" ? (
                      activePlaylist ? (
                        <><Icon.Play size={12} style={{ color: "var(--success)" }} /> <span>{activePlaylist.name}</span></>
                      ) : (
                        <><Icon.Pause size={12} style={{ color: "var(--text-muted)" }} /> <span style={{ color: "var(--text-muted)" }}>En attente — aucune playlist</span></>
                      )
                    ) : s.status === "idle" ? (
                      <><Icon.Pause size={12} style={{ color: "var(--warning)" }} /> <span style={{ color: "var(--text-muted)" }}>En veille</span></>
                    ) : (
                      <><Icon.AlertTriangle size={12} style={{ color: "var(--danger)" }} /> <span style={{ color: "var(--danger)" }}>Hors ligne</span></>
                    )}
                  </div>
                  <div style={{ display: "flex", justifyContent: "space-between", fontSize: 11, color: "var(--text-muted)" }}>
                    <span>Uptime · <span className="mono">{s.uptime}</span></span>
                    <span>Luminosité · <span className="mono">{s.brightness}%</span></span>
                  </div>
                  <div className="screen-card__actions">
                    <button className="btn btn--sm" style={{ flex: 1 }}><Icon.Eye size={12} /> Aperçu</button>
                    <button className="btn btn--sm" style={{ flex: 1 }} onClick={() => { setEditingScreen(s); setShowModal(true); }}>
                      <Icon.Settings size={12} /> Régler
                    </button>
                    <button className="btn btn--sm btn--icon" onClick={() => toggleStatus(s.id)} title="Changer l'état">
                      <Icon.Power size={12} />
                    </button>
                  </div>
                </div>
              </div>
            ))}
          </div>
        )}
      </div>

      {showModal && editingScreen && (
        <ScreenFormModal
          initial={editingScreen}
          onSubmit={handleSubmit}
          onCancel={() => { setShowModal(false); setEditingScreen(null); }}
        />
      )}
      {showModal && !editingScreen && (
        <ScreenPairingModal
          onCancel={() => setShowModal(false)}
          onClaimed={(screen) => {
            setScreens(prev => [...prev.filter(s => s.id !== screen.id), screen]);
            setShowModal(false);
            pushActivity?.({ action: "a connecté", target: screen.name, type: "publish" });
            flashToast(`Écran « ${screen.name} » connecté`, <Icon.Check size={13} />);
          }}
        />
      )}
      <window.ConfirmDialog
        open={!!confirmDel}
        title="Retirer cet écran ?"
        message="L'écran sera déconnecté et retiré du parc. Cette action est irréversible."
        danger
        onConfirm={() => handleDelete(confirmDel)}
        onCancel={() => setConfirmDel(null)}
      />
      <window.Toast msg={toast} />
    </div>
  );
}

function ScreenPairingModal({ onCancel, onClaimed }) {
  const [code, setCode] = React.useState("");
  const [name, setName] = React.useState("");
  const [loc, setLoc] = React.useState("");
  const [error, setError] = React.useState(null);
  const [submitting, setSubmitting] = React.useState(false);

  const fullInstallCmd = `curl -fsSL ${window.location.origin}/client/install-screen-ubuntu.sh | sudo SERVER_URL=${window.location.origin} bash`;

  const handleSubmit = async (e) => {
    e?.preventDefault();
    setError(null);
    const cleaned = code.toUpperCase().replace(/[^A-Z2-9]/g, "");
    if (cleaned.length !== 6) {
      setError("Le code doit faire 6 caractères.");
      return;
    }
    setSubmitting(true);
    try {
      const r = await fetch("/api/pairing/claim", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ code: cleaned, name: name.trim(), location: loc.trim() }),
      });
      const j = await r.json();
      if (!r.ok) throw new Error(j.error || `HTTP ${r.status}`);
      onClaimed(j.screen);
    } catch (err) {
      setError(err.message || "Code invalide ou expiré.");
    } finally {
      setSubmitting(false);
    }
  };

  const copyCmd = () => {
    navigator.clipboard.writeText(fullInstallCmd).catch(() => {});
  };

  return (
    <div className="modal-backdrop" onClick={onCancel}>
      <div className="modal modal--lg" onClick={e => e.stopPropagation()}>
        <div className="modal__header">
          <div className="modal__title">Connecter un écran</div>
          <button className="btn btn--sm btn--icon btn--ghost" onClick={onCancel}><Icon.X size={14} /></button>
        </div>
        <div className="modal__body">
          {/* Bloc d'aide install */}
          <div style={{ background: "var(--bg-subtle)", border: "1px solid var(--border)", borderRadius: 10, padding: 14, marginBottom: 16 }}>
            <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 8 }}>
              <Icon.Monitor size={14} style={{ color: "var(--accent)" }} />
              <strong style={{ fontSize: 12.5 }}>Sur le PC qui pilote l'écran (Ubuntu Server)</strong>
            </div>
            <div style={{ fontSize: 11.5, color: "var(--text-muted)", marginBottom: 8 }}>
              Colle cette commande une seule fois sur la machine. Au démarrage suivant, un code à 6 chiffres s'affichera sur l'écran physique.
            </div>
            <div style={{ position: "relative", background: "#0A0E17", border: "1px solid var(--border)", borderRadius: 6, padding: "8px 36px 8px 12px", fontFamily: "var(--font-mono)", fontSize: 11, color: "#67E8F9", wordBreak: "break-all" }}>
              {fullInstallCmd}
              <button className="btn btn--sm btn--icon btn--ghost" onClick={copyCmd} style={{ position: "absolute", top: 4, right: 4 }} title="Copier">
                <Icon.Folder size={11} />
              </button>
            </div>
          </div>

          {/* Formulaire */}
          <form onSubmit={handleSubmit}>
            <div className="form-field">
              <label>Code affiché sur l'écran</label>
              <input
                className="form-input mono"
                style={{ textTransform: "uppercase", fontSize: 24, letterSpacing: "0.25em", textAlign: "center", padding: "12px 16px", fontWeight: 700 }}
                value={code}
                onChange={e => setCode(e.target.value.toUpperCase().replace(/[^A-Z2-9]/g, "").slice(0, 6))}
                placeholder="XXXXXX"
                autoFocus
                maxLength={6}
              />
              <div className="form-help">6 caractères, sans espace. Insensible à la casse.</div>
            </div>

            <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12 }}>
              <div className="form-field">
                <label>Nom de l'écran (optionnel)</label>
                <input className="form-input" placeholder="Ex. Open space — Plafond" value={name} onChange={e => setName(e.target.value)} />
                <div className="form-help">Par défaut : hostname du PC</div>
              </div>
              <div className="form-field">
                <label>Emplacement (optionnel)</label>
                <input className="form-input" placeholder="Ex. Bordeaux · Étage 2" value={loc} onChange={e => setLoc(e.target.value)} />
              </div>
            </div>

            {error && (
              <div style={{ padding: "8px 12px", background: "rgba(248,113,113,0.1)", border: "1px solid var(--danger)", borderRadius: 6, color: "var(--danger)", fontSize: 12, marginBottom: 12 }}>
                {error}
              </div>
            )}

            <div className="modal__actions">
              <button type="button" className="btn" onClick={onCancel}>Annuler</button>
              <button type="submit" className="btn btn--primary" disabled={submitting || code.length !== 6}>
                {submitting ? "Connexion…" : <><Icon.Check size={12} /> Appairer l'écran</>}
              </button>
            </div>
          </form>
        </div>
      </div>
    </div>
  );
}

function ScreenFormModal({ initial, onSubmit, onCancel }) {
  const [name, setName] = React.useState(initial?.name || "");
  const [location, setLocation] = React.useState(initial?.location || "");
  const [resolution, setResolution] = React.useState(initial?.resolution || "1920 × 1080");
  const [ip, setIp] = React.useState(initial?.ip || "");
  const [brightness, setBrightness] = React.useState(initial?.brightness || 70);
  const RESOLUTIONS = ["1920 × 1080", "2560 × 1440", "3840 × 2160", "1366 × 768", "1280 × 720"];

  const submit = () => {
    if (!name.trim()) return;
    onSubmit({
      name: name.trim(),
      location: location.trim() || "Site principal",
      resolution,
      ip: ip.trim() || `10.0.${Math.floor(Math.random() * 9) + 1}.${Math.floor(Math.random() * 250) + 5}`,
      brightness,
    });
  };

  return (
    <div className="modal-backdrop" onClick={onCancel}>
      <div className="modal" onClick={e => e.stopPropagation()}>
        <div className="modal__header">
          <div className="modal__title">{initial ? "Éditer l'écran" : "Connecter un écran"}</div>
          <button className="btn btn--sm btn--icon btn--ghost" onClick={onCancel}><Icon.X size={14} /></button>
        </div>
        <div className="modal__body">
          <div className="form-field">
            <label>Nom de l'écran</label>
            <input className="form-input" placeholder="Ex. Open space — Plafond principal" value={name} onChange={e => setName(e.target.value)} autoFocus />
          </div>
          <div className="form-field">
            <label>Emplacement</label>
            <input className="form-input" placeholder="Ex. Bordeaux · Étage 2" value={location} onChange={e => setLocation(e.target.value)} />
          </div>
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12 }}>
            <div className="form-field">
              <label>Résolution</label>
              <select className="form-input" value={resolution} onChange={e => setResolution(e.target.value)}>
                {RESOLUTIONS.map(r => <option key={r} value={r}>{r}</option>)}
              </select>
            </div>
            <div className="form-field">
              <label>Adresse IP</label>
              <input className="form-input mono" placeholder="10.0.x.x" value={ip} onChange={e => setIp(e.target.value)} />
            </div>
          </div>
          <div className="form-field">
            <label>Luminosité ({brightness} %)</label>
            <input type="range" min="0" max="100" value={brightness} onChange={e => setBrightness(Number(e.target.value))} style={{ width: "100%" }} />
          </div>
          <div className="modal__actions">
            <button className="btn" onClick={onCancel}>Annuler</button>
            <button className="btn btn--primary" onClick={submit} disabled={!name.trim()}>
              {initial ? "Enregistrer" : "Connecter"}
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}

// =========== STATS ===========
function Stats({ playlists = [], activity = [], mediaFiles = [], screens = [] }) {
  // Real counts derived from state
  const playEvents = activity.filter(a => a.type === "play");
  const totalDiffusions = playEvents.length;
  const uniqueMediasInPlaylists = new Set(
    playlists.flatMap(p => Object.values(p.zones || {}).flatMap(arr => (arr || []).map(it => it.mediaId)))
  ).size;
  const onlineCount = screens.filter(s => s.status === "online").length;
  const idleCount   = screens.filter(s => s.status === "idle").length;
  const availability = screens.length > 0 ? ((onlineCount + idleCount) / screens.length * 100).toFixed(1) : "—";

  // Bar chart : 7 derniers jours basés sur l'activité réelle
  const DAY_LABELS_SHORT = ["Dim", "Lun", "Mar", "Mer", "Jeu", "Ven", "Sam"];
  const sevenDays = (() => {
    const today = new Date(); today.setHours(0, 0, 0, 0);
    const out = [];
    for (let i = 6; i >= 0; i--) {
      const d = new Date(today); d.setDate(d.getDate() - i);
      // Compte les events play sur ce jour (basés sur le timestamp Unix dans activity)
      // Note : activity.time est une string formatée ; pas de raw timestamp dispo ici, donc 0 pour l'instant
      out.push({ day: `${DAY_LABELS_SHORT[d.getDay()]} ${d.getDate()}`, value: 0 });
    }
    return out;
  })();
  const max = Math.max(1, ...sevenDays.map(b => b.value));

  // Top content : basé sur les playlists existantes, parts à 0 tant qu'il n'y a pas de diffusions trackées
  const topContent = playlists.slice(0, 6).map((p) => ({
    label: p.name,
    value: 0,
    share: 0,
    color: p.color,
  }));

  // Heatmap : toutes à 0 tant qu'on n'a pas de tracking par jour×heure
  const HEAT_DAYS = ["Lun", "Mar", "Mer", "Jeu", "Ven", "Sam", "Dim"];
  const heatCells = HEAT_DAYS.map(() => Array.from({ length: 24 }, () => 0));

  const heatColor = v => {
    if (v < 0.05) return "var(--bg-subtle)";
    const a = Math.min(0.95, 0.12 + v * 0.85);
    return `rgba(42, 49, 66, ${a})`;
  };

  return (
    <div className="pane">
      <header className="pane__header">
        <div className="pane__title-group">
          <span className="pane__crumb">Régie · Analytics</span>
          <h1 className="pane__title">Statistiques</h1>
        </div>
        <div className="pane__actions">
          <div className="btn-group">
            <button className="btn btn--sm">7 j</button>
            <button className="btn btn--sm is-active">30 j</button>
            <button className="btn btn--sm">90 j</button>
            <button className="btn btn--sm">Année</button>
          </div>
          <button className="btn"><Icon.Download /> Rapport PDF</button>
        </div>
      </header>

      <div className="pane__body">
        <div className="kpi-row">
          <Kpi label="Diffusions de la session" value={String(totalDiffusions)} sub="événements 'play' capturés" trend={{ dir: "up", value: "· live" }} icon={Icon.Broadcast} />
          <Kpi label="Médias diffusés" value={`${uniqueMediasInPlaylists} / ${mediaFiles.length}`} sub={`${Math.round(uniqueMediasInPlaylists / Math.max(mediaFiles.length, 1) * 100)} % de la bibliothèque`} icon={Icon.Folder} />
          <Kpi label="Disponibilité parc" value={`${availability} %`} sub={`${onlineCount} / ${screens.length} en ligne`} icon={Icon.Wifi} />
          <Kpi label="Heures de diffusion" value={totalDiffusions > 0 ? `${(totalDiffusions * 5 / 60).toFixed(1)} h` : "— h"} sub={totalDiffusions > 0 ? "estimées (5 min/diff)" : "aucune diffusion encore"} icon={Icon.Clock} />
        </div>

        <div className="stats-grid">
          {/* Bar chart */}
          <div className="card">
            <div className="card__header">
              <div className="card__title">Diffusions par jour</div>
              <span className="card__title-sub">7 derniers jours</span>
            </div>
            <div className="bar-chart">
              <div className="bar-chart__grid">
                {[0, 0.25, 0.5, 0.75, 1].map(p => (
                  <div key={p} className="bar-chart__grid-line" style={{ bottom: `${p * 100}%` }} />
                ))}
              </div>
              {sevenDays.map((b, i) => {
                const isWeekend = i >= 5;
                return (
                  <div key={b.day} className="bar-chart__col">
                    <div className="bar-chart__bar-wrap">
                      <div
                        className={"bar-chart__bar" + (isWeekend ? " bar-chart__bar--muted" : "")}
                        style={{ height: `${(b.value / max) * 100}%` }}
                      >
                        <span className="bar-chart__value">{b.value}</span>
                      </div>
                    </div>
                    <div className="bar-chart__label">{b.day}</div>
                  </div>
                );
              })}
            </div>
          </div>

          {/* Top content */}
          <div className="card">
            <div className="card__header">
              <div className="card__title">Contenus les plus diffusés</div>
              <button className="btn btn--sm btn--ghost">Voir tout</button>
            </div>
            <div className="top-list">
              {topContent.map((t, i) => (
                <div key={i} className="top-list__row">
                  <div className="top-list__head">
                    <span className="top-list__label" style={{ display: "flex", alignItems: "center", gap: 8 }}>
                      <span style={{ width: 8, height: 8, borderRadius: 2, background: t.color, flexShrink: 0 }} />
                      {t.label}
                    </span>
                    <span className="top-list__value">{t.value.toLocaleString("fr-FR")}</span>
                  </div>
                  <div className="top-list__bar"><div style={{ width: `${t.share * 2.6}%`, background: t.color }} /></div>
                  <div className="top-list__share">{t.share} % des diffusions</div>
                </div>
              ))}
            </div>
          </div>
        </div>

        {/* Heatmap */}
        <div className="card">
          <div className="card__header">
            <div className="card__title">Heatmap — Diffusion par heure et jour</div>
            <span className="card__title-sub">moyenne sur les 30 derniers jours</span>
          </div>
          <div style={{ padding: 16, overflowX: "auto" }}>
            <div className="heatmap">
              <div></div>
              {Array.from({ length: 24 }, (_, h) => (
                <div key={h} className="heatmap__hour">{h}h</div>
              ))}
              {HEAT_DAYS.map((d, di) => (
                <React.Fragment key={d}>
                  <div className="heatmap__label">{d}</div>
                  {heatCells[di].map((v, hi) => (
                    <div
                      key={hi}
                      className="heatmap__cell"
                      style={{ background: heatColor(v) }}
                      title={`${d} ${hi}h · ${Math.round(v * 100)}%`}
                    />
                  ))}
                </React.Fragment>
              ))}
            </div>
            <div style={{ display: "flex", alignItems: "center", gap: 8, marginTop: 14, fontSize: 11, color: "var(--text-muted)" }}>
              <span>Moins</span>
              {[0.05, 0.2, 0.4, 0.6, 0.8, 0.95].map(v => (
                <div key={v} style={{ width: 18, height: 18, borderRadius: 3, background: heatColor(v) }} />
              ))}
              <span>Plus</span>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

window.Schedule = Schedule;
window.Screens = Screens;
window.Stats = Stats;
