/* global React, Icon, Button, Badge, ProgressBar, DATA */
// ============================================================
// Télécommande (composant clé) + journal + Mes tâches
// ============================================================
function Remote({ act, busyBtn, dead, actions, fps, setFps, compact, device }) {
  const { useState } = React;
  useLang();
  const [text, setText] = useState("");
  const send = () => { if (!text.trim()) return; act("Saisie texte", "kb", text); setText(""); };

  return (
    <div style={{ display: "grid", gap: compact ? 10 : 14 }}>
      {dead && (
        <div style={{ display: "flex", alignItems: "center", gap: 9, padding: "10px 13px", borderRadius: 11, background: "rgba(245,185,66,.1)", border: "1px solid rgba(245,185,66,.25)", color: "var(--busy)", fontSize: 12.5 }}>
          {React.createElement(Icon.lock, { size: 16 })} Contrôles indisponibles — device {dead ? "verrouillé / hors-ligne" : ""}.
        </div>
      )}

      {/* qualité du flux — FPS */}
      <FpsControl fps={fps} setFps={setFps} dead={dead} />

      {/* D-pad / swipe */}
      <RemoteCard title={t("navigation")} icon="apps">
        {compact ? (
          /* compact (split) : croix centrée + scroll en dessous, sans la colonne d'aide */
          <div style={{ display: "grid", gap: 8, justifyItems: "center" }}>
            <div style={{ display: "grid", gridTemplateColumns: "repeat(3,46px)", gridTemplateRows: "repeat(3,46px)", gap: 5 }}>
              <span />
              <Pad id="down" icon="down" label="Bas" act={act} busyBtn={busyBtn} dead={dead} cross />
              <span />
              <Pad id="right" icon="right" label="Droite" act={act} busyBtn={busyBtn} dead={dead} cross />
              <Pad id="refresh" icon="refresh" act={act} busyBtn={busyBtn} dead={false} cross center />
              <Pad id="left" icon="left" label="Gauche" act={act} busyBtn={busyBtn} dead={dead} cross />
              <span />
              <Pad id="up" icon="up" label="Haut" act={act} busyBtn={busyBtn} dead={dead} cross />
              <span />
            </div>
            <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 6, width: "100%" }}>
              <Pad id="scrollUp" icon="scrollUp" label="Scroll ↑" act={act} busyBtn={busyBtn} dead={dead} wide />
              <Pad id="scrollDown" icon="scrollDown" label="Scroll ↓" act={act} busyBtn={busyBtn} dead={dead} wide />
            </div>
          </div>
        ) : (
          <div style={{ display: "grid", gridTemplateColumns: "1fr auto 1fr", gap: 12, alignItems: "center" }}>
            <div style={{ display: "grid", gap: 8 }}>
              <Pad id="scrollUp" icon="scrollUp" label="Scroll ↑" act={act} busyBtn={busyBtn} dead={dead} wide />
              <Pad id="scrollDown" icon="scrollDown" label="Scroll ↓" act={act} busyBtn={busyBtn} dead={dead} wide />
            </div>
            {/* croix */}
            <div style={{ display: "grid", gridTemplateColumns: "repeat(3,46px)", gridTemplateRows: "repeat(3,46px)", gap: 5, justifyContent: "center" }}>
              <span />
              <Pad id="down" icon="down" label="Bas" act={act} busyBtn={busyBtn} dead={dead} cross />
              <span />
              <Pad id="right" icon="right" label="Droite" act={act} busyBtn={busyBtn} dead={dead} cross />
              <Pad id="refresh" icon="refresh" act={act} busyBtn={busyBtn} dead={false} cross center />
              <Pad id="left" icon="left" label="Gauche" act={act} busyBtn={busyBtn} dead={dead} cross />
              <span />
              <Pad id="up" icon="up" label="Haut" act={act} busyBtn={busyBtn} dead={dead} cross />
              <span />
            </div>
            <div style={{ fontSize: 11, color: "var(--faint)", lineHeight: 1.5 }} className="mono">
              ← → ↑ ↓<br />swipe directionnel.<br />centre = refresh.
            </div>
          </div>
        )}
      </RemoteCard>

      {/* saisie texte — au-dessus de Système */}
      <RemoteCard title={t("text_input")} icon="keyboard">
        <div style={{ display: "flex", gap: 9, flexWrap: "wrap" }}>
          <input value={text} onChange={e => setText(e.target.value)} onKeyDown={e => e.key === "Enter" && send()} disabled={dead}
            placeholder={t("text_placeholder")} style={{ flex: 1, padding: "11px 13px", background: "var(--bg-2)", border: "1px solid var(--border-2)", borderRadius: 9, color: "var(--text)", fontSize: 13, outline: "none", opacity: dead ? .45 : 1 }} />
          <Button variant="primary" icon="send" onClick={send} disabled={dead}>{t("send")}</Button>
        </div>
        <div className="mono" style={{ fontSize: 10.5, color: "var(--faint)", marginTop: 8 }}>saisit dans le champ actuellement focus · clavier AZERTY virtuel optionnel</div>
      </RemoteCard>

      {/* médias : envoyer photo/vidéo préparée au téléphone */}
      {device && <MediaCard device={device} />}

      {/* navigation système */}
      <RemoteCard title={t("system")} icon="home" collapsible startOpen={false}>
        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 9 }}>
          <BigBtn id="back" icon="back" label="Back" act={act} busyBtn={busyBtn} dead={dead} />
          <BigBtn id="home" icon="home" label="Home" act={act} busyBtn={busyBtn} dead={dead} />
        </div>
      </RemoteCard>

      {/* apps */}
      <RemoteCard title={t("launch_app")} icon="apps" collapsible startOpen={false} right={<button style={{ display: "flex", alignItems: "center", gap: 5, background: "none", border: "1px dashed var(--border-2)", borderRadius: 8, padding: "5px 9px", color: "var(--muted)", fontSize: 11.5 }}>{React.createElement(Icon.plus, { size: 13 })} {t("add")}</button>}>
        <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 9 }}>
          {DATA.APPS.map(a => (
            <button key={a.id} disabled={dead} onClick={() => act(`Ouvrir ${a.name}`, a.id, a.bundle)} style={{
              display: "flex", flexDirection: "column", alignItems: "center", gap: 7, padding: "12px 6px", borderRadius: 12,
              background: busyBtn === a.id ? "var(--accent-soft)" : "var(--surface-2)", border: "1px solid var(--border)",
              opacity: dead ? .45 : 1, transition: "all .12s", color: "var(--text)" }}
              onMouseEnter={e => !dead && (e.currentTarget.style.borderColor = "var(--border-2)")}
              onMouseLeave={e => (e.currentTarget.style.borderColor = "var(--border)")}>
              <span style={{ width: 38, height: 38, borderRadius: 10, background: a.color, display: "grid", placeItems: "center", color: "#fff", fontWeight: 700, fontSize: 15 }}>{a.glyph}</span>
              <span style={{ fontSize: 11, fontWeight: 600 }}>{a.name}</span>
            </button>
          ))}
        </div>
      </RemoteCard>
    </div>
  );
}

function RemoteCard({ title, icon, right, children, collapsible, startOpen = true }) {
  const [open, setOpen] = React.useState(startOpen);
  return (
    <div style={{ background: "var(--surface)", border: "1px solid var(--border)", borderRadius: "var(--r-lg)", padding: 15 }}>
      <div onClick={collapsible ? () => setOpen(o => !o) : undefined}
        style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: open ? 13 : 0, cursor: collapsible ? "pointer" : "default", userSelect: "none" }}>
        <div style={{ display: "flex", alignItems: "center", gap: 8, color: "var(--muted)" }}>
          {collapsible && <span style={{ display: "grid", color: "var(--faint)", transform: open ? "none" : "rotate(-90deg)", transition: "transform .16s" }}>{React.createElement(Icon.chevDown, { size: 15 })}</span>}
          {Icon[icon] ? React.createElement(Icon[icon], { size: 15 }) : null}
          <span style={{ fontSize: 11.5, fontWeight: 700, letterSpacing: ".06em", textTransform: "uppercase" }}>{title}</span>
        </div>
        {right}
      </div>
      {(!collapsible || open) && children}
    </div>
  );
}

function Pad({ id, icon, label, act, busyBtn, dead, cross, center, wide }) {
  const on = busyBtn === id;
  const disabled = dead && id !== "refresh";
  return (
    <button disabled={disabled} onClick={() => act(label || cap(id), id, null)} style={{
      display: "flex", alignItems: "center", justifyContent: "center", gap: 6,
      height: cross ? 46 : 38, width: wide ? "100%" : undefined, borderRadius: cross ? 12 : 9,
      background: on ? "var(--accent)" : center ? "var(--surface-3)" : "var(--surface-2)",
      color: on ? "#06281c" : center ? "var(--accent)" : "var(--text)",
      border: "1px solid " + (center ? "var(--accent-line)" : "var(--border)"),
      opacity: disabled ? .4 : 1, transition: "all .1s", fontSize: 11.5, fontWeight: 600,
      animation: on ? "btnFlash .36s ease" : "none" }}
      onMouseEnter={e => !disabled && !on && (e.currentTarget.style.background = "var(--surface-3)")}
      onMouseLeave={e => !on && (e.currentTarget.style.background = center ? "var(--surface-3)" : "var(--surface-2)")}>
      {React.createElement(Icon[icon], { size: cross ? 19 : 16 })}{wide && label}
    </button>
  );
}

function BigBtn({ id, icon, label, act, busyBtn, dead }) {
  const on = busyBtn === id;
  return (
    <button disabled={dead} onClick={() => act(label, id, null)} style={{
      display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", gap: 7, padding: "14px 6px",
      borderRadius: 13, background: on ? "var(--accent)" : "var(--surface-2)", color: on ? "#06281c" : "var(--text)",
      border: "1px solid " + (on ? "transparent" : "var(--border)"), opacity: dead ? .4 : 1, transition: "all .12s",
      animation: on ? "btnFlash .36s ease" : "none" }}
      onMouseEnter={e => !dead && !on && (e.currentTarget.style.borderColor = "var(--border-2)")}
      onMouseLeave={e => !on && (e.currentTarget.style.borderColor = "var(--border)")}>
      {React.createElement(Icon[icon], { size: 22 })}
      <span style={{ fontSize: 11.5, fontWeight: 600 }}>{label}</span>
    </button>
  );
}

function cap(s) { return s.charAt(0).toUpperCase() + s.slice(1); }

// ---- Contrôle FPS (taux de rafraîchissement du flux) ----
const MAX_FPS = 30;
function fpsQuality(fps) {
  if (fps <= 5) return { label: "Éco · net · bande passante mini", tone: "var(--accent-2)" };
  if (fps <= 12) return { label: "Fluide", tone: "var(--accent)" };
  if (fps <= 20) return { label: "Recommandé · pilotage fluide", tone: "var(--accent)" };
  return { label: "Max · 30 fps · pilotage temps réel", tone: "var(--busy)" };
}
function FpsControl({ fps, setFps, dead }) {
  const q = fpsQuality(fps);
  const pct = ((fps - 1) / (MAX_FPS - 1)) * 100;
  const recPct = ((20 - 1) / (MAX_FPS - 1)) * 100;
  return (
    <RemoteCard title={t("refresh_rate")} icon="play" collapsible startOpen={false}
      right={<span className="num" style={{ fontSize: 13, fontWeight: 700, color: dead ? "var(--faint)" : q.tone }}>{dead ? "0" : fps} <span style={{ fontSize: 10, color: "var(--faint)", fontWeight: 600 }}>FPS</span></span>}>
      <div style={{ opacity: dead ? .45 : 1, pointerEvents: dead ? "none" : "auto" }}>
        <div style={{ position: "relative", height: 22, display: "flex", alignItems: "center" }}>
          {/* repère recommandé */}
          <span style={{ position: "absolute", left: `${recPct}%`, top: 0, bottom: 0, width: 2, background: "var(--accent-line)", transform: "translateX(-1px)" }} />
          <span style={{ position: "absolute", left: `${recPct}%`, top: -4, transform: "translateX(-50%)", fontSize: 8.5, color: "var(--accent)", fontFamily: "var(--mono)" }}>20</span>
          <input type="range" min={1} max={MAX_FPS} step={1} value={fps} onChange={(e) => setFps(+e.target.value)}
            style={{ width: "100%", accentColor: q.tone, background: "transparent", cursor: "pointer", margin: 0 }} />
        </div>
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginTop: 6 }}>
          <span style={{ fontSize: 11.5, color: q.tone, fontWeight: 600 }}>{q.label}</span>
          <div style={{ display: "flex", gap: 5 }}>
            {[5, 15, 20, 30].map(p => (
              <button key={p} onClick={() => setFps(p)} style={{ padding: "3px 9px", fontSize: 11, fontWeight: 600, borderRadius: 7, border: "1px solid " + (fps === p ? "var(--accent-line)" : "var(--border)"),
                background: fps === p ? "var(--accent-soft)" : "var(--surface-2)", color: fps === p ? "var(--accent)" : "var(--muted)", fontFamily: "var(--mono)" }}>{p}</button>
            ))}
          </div>
        </div>
        <div className="mono" style={{ fontSize: 10, color: "var(--faint)", marginTop: 8 }}>FPS bas = plus net · FPS haut = plus fluide (image un peu réduite). Jusqu'à 30 fps pour un pilotage temps réel.</div>
      </div>
    </RemoteCard>
  );
}

// ---- Mes tâches (côté opérateur) ----
function MyTasks({ device, user, compact }) {
  const { useState, useEffect } = React;
  const store = (window.useTasks ? useTasks() : { list: () => [] });
  const all = store.list ? store.list() : [];
  // tâches RÉELLES pour ce device OU assignées à cet opérateur
  const uid = user && user.id;
  const mine = all.filter(t => (device && t.device_udid === device.udid) || (uid && t.assignee === uid));
  const active = mine[0] || null;

  // étapes : depuis la SOP liée si dispo, sinon le titre seul
  const sopList = (window.SopStore ? SopStore.list() : []);
  useEffect(() => { if (window.SopStore) SopStore.reload(); }, []);
  const sop = active && active.sop_id ? sopList.find(s => s.id === active.sop_id) : null;
  const steps = sop && sop.steps && sop.steps.length ? sop.steps : (active ? [active.title] : []);

  const [checked, setChecked] = useState([]);
  useEffect(() => { setChecked(steps.map((_, i) => i < (active ? (active.progress || 0) : 0))); /* eslint-disable-next-line */ }, [active && active.id, steps.length]);

  if (!active) return (
    <div style={{ background: "var(--surface)", border: "1px solid var(--border)", borderRadius: "var(--r-lg)", padding: 20, textAlign: "center", color: "var(--faint)" }}>
      {React.createElement(Icon.clipboard, { size: 26 })}
      <div style={{ marginTop: 10, fontSize: 13 }}>{t("no_task_device")}</div>
    </div>
  );

  const doneCount = checked.filter(Boolean).length;
  const toggle = (i) => setChecked(c => {
    const nc = c.map((v, j) => j === i ? !v : v);
    const done = nc.filter(Boolean).length;
    // on enregistre l'avancement réel sur la tâche (visible côté admin)
    if (window.Backend) window.Backend.patchTask(active.id, { progress: done, total: steps.length, status: done >= steps.length ? "done" : "todo" });
    return nc;
  });

  return (
    <div style={{ display: "grid", gap: 14 }}>
      <div style={{ background: "var(--surface)", border: "1px solid var(--border)", borderRadius: "var(--r-lg)", padding: 16 }}>
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 4 }}>
          <div style={{ fontWeight: 700, fontSize: 14.5 }}>{active.title}</div>
          <Badge tone={doneCount === steps.length ? "green" : "amber"}>{doneCount}/{steps.length}</Badge>
        </div>
        <div className="mono" style={{ fontSize: 11, color: "var(--faint)", marginBottom: 12 }}>sur {device.tag}{active.due ? " · " + active.due : ""}</div>
        <ProgressBar value={doneCount} total={steps.length} tone={doneCount === steps.length ? "green" : "amber"} />
        <div style={{ display: "grid", gap: 7, marginTop: 14 }}>
          {steps.map((s, i) => (
            <label key={i} style={{ display: "flex", alignItems: "center", gap: 11, padding: "10px 12px", borderRadius: 10,
              background: checked[i] ? "var(--accent-soft)" : "var(--surface-2)", border: "1px solid " + (checked[i] ? "var(--accent-line)" : "var(--border)"),
              cursor: "pointer", transition: "all .14s" }}>
              <span onClick={() => toggle(i)} style={{ width: 20, height: 20, borderRadius: 6, flex: "none", display: "grid", placeItems: "center",
                background: checked[i] ? "var(--accent)" : "transparent", border: "1.6px solid " + (checked[i] ? "var(--accent)" : "var(--border-2)"), color: "#06281c" }}>
                {checked[i] && React.createElement(Icon.check, { size: 13, sw: 3 })}
              </span>
              <span style={{ fontSize: 13, textDecoration: checked[i] ? "line-through" : "none", color: checked[i] ? "var(--muted)" : "var(--text)" }}>{s}</span>
            </label>
          ))}
        </div>
      </div>

      {!compact && mine.length > 1 && <div style={{ background: "var(--surface)", border: "1px solid var(--border)", borderRadius: "var(--r-lg)", padding: 16 }}>
        <div style={{ fontSize: 11.5, fontWeight: 700, letterSpacing: ".06em", textTransform: "uppercase", color: "var(--muted)", marginBottom: 12 }}>{t("other_tasks")}</div>
        <div style={{ display: "grid", gap: 9 }}>
          {mine.slice(1).map(t => (
            <div key={t.id} style={{ display: "flex", alignItems: "center", gap: 11 }}>
              <span style={{ width: 8, height: 8, borderRadius: 99, background: t.status === "done" ? "var(--accent)" : t.status === "overdue" ? "var(--danger)" : "var(--faint)" }} />
              <span style={{ fontSize: 12.5, flex: 1 }}>{t.title}</span>
              <span className="mono" style={{ fontSize: 10.5, color: "var(--faint)" }}>{t.progress}/{t.total}</span>
            </div>
          ))}
        </div>
      </div>}
    </div>
  );
}

// ---- Journal d'actions (affiché à gauche du téléphone) ----
function ActionLog({ actions }) {
  return (
    <RemoteCard title={t("actions_journal")} icon="list" right={<span className="mono" style={{ fontSize: 11, color: "var(--accent)" }}>● live</span>}>
      <div style={{ display: "grid", gap: 2, maxHeight: 300, overflow: "auto" }}>
        {actions.map((a, i) => (
          <div key={i} style={{ display: "flex", alignItems: "center", gap: 10, padding: "6px 4px", fontSize: 12, opacity: i === 0 ? 1 : 0.72 - i * 0.04 }}>
            <span className="num" style={{ fontSize: 10.5, color: "var(--faint)", flex: "none" }}>{a.at}</span>
            <span style={{ width: 5, height: 5, borderRadius: 99, background: a.t === "ready" ? "var(--accent-2)" : "var(--accent)", flex: "none" }} />
            <span style={{ fontWeight: 600 }}>{a.label}</span>
            {a.meta && <span className="mono" style={{ fontSize: 10.5, color: "var(--faint)", marginLeft: "auto" }}>{a.meta}</span>}
          </div>
        ))}
      </div>
    </RemoteCard>
  );
}

Object.assign(window, { Remote, RemoteCard, Pad, BigBtn, MyTasks, ActionLog, FpsControl });
