/* global React, th, td, clickTd, tdStyle */
// ============================================================
// Comptes Instagram — section dédiée sous "iPhone physique", 100% locale
// (même DB/API que "Stockage comptes" (/api/instagram/accounts) mais sans
// aucun champ/logique MoreLogin — juste les comptes créés sur les iPhones
// physiques : email, IG, 2FA, conteneur, lien redirect...).
// Design (th/td/clickTd/tdStyle/IgTagStatusPicker) partagé avec "Stockage
// comptes" (instagram.jsx, chargé avant ce fichier) — même look, mêmes
// interactions copier/coller, sans reprendre ses champs MoreLogin.
// ============================================================
const { useState, useEffect, useCallback, useMemo } = React;

// Reprise locale des couleurs/options de IgTagStatusPicker (const de instagram.jsx, pas
// accessible depuis ce fichier) — SEULE différence : "Create" s'affiche "ACTIF" en vert ici,
// car sur un compte iPhone déjà créé "Create" n'a pas de sens (contrairement à Stockage comptes,
// où le statut peut vraiment être "en cours de création"). Ne touche pas au tableau MoreLogin.
const IGACC_STATUS_COLORS = {
  "Launched": { bg: "#2f6fed", fg: "#ffffff" }, "ADS": { bg: "#1f9d55", fg: "#ffffff" },
  "Need_Ads": { bg: "#8a5cf6", fg: "#ffffff" }, "Create": { bg: "#1f9d55", fg: "#ffffff" },
  "Ban": { bg: "#d64545", fg: "#ffffff" }, "Ban def": { bg: "#8f1f1f", fg: "#ffffff" },
  "Warm1": { bg: "#f3b8c4", fg: "#5c1f2e" }, "Warm2": { bg: "#f6cdd6", fg: "#5c1f2e" },
  "Warm3": { bg: "#d8c9cd", fg: "#4a3a3d" }, "Recovered warm up": { bg: "#5fd6d0", fg: "#0a3d3a" },
  "kill": { bg: "#b32424", fg: "#ffffff" },
};
const IGACC_STATUS_LABELS = { "Create": "ACTIF" };
const IGACC_STATUS_OPTIONS = ["Launched", "ADS", "Need_Ads", "Create", "Ban", "Ban def", "Warm1", "Warm2", "Warm3", "Recovered warm up", "kill"];
function IgaccTagStatusPicker(props) {
  const value = props.value || "Create";
  const onChange = props.onChange;
  const [open, setOpen] = React.useState(false);
  const boxRef = React.useRef(null);
  React.useEffect(function () {
    if (!open) return;
    function onOutside(e) { if (boxRef.current && !boxRef.current.contains(e.target)) setOpen(false); }
    document.addEventListener("mousedown", onOutside);
    return function () { document.removeEventListener("mousedown", onOutside); };
  }, [open]);
  const c = IGACC_STATUS_COLORS[value] || { bg: "#333", fg: "#ccc" };
  return React.createElement("div", { ref: boxRef, style: { position: "relative", display: "inline-block" } },
    React.createElement("button", {
      onClick: function (e) { e.stopPropagation(); setOpen(!open); },
      style: { background: c.bg, color: c.fg, border: "none", borderRadius: 6, padding: "4px 10px", fontSize: 10.5, fontWeight: 700, cursor: "pointer", fontFamily: "'JetBrains Mono', monospace", whiteSpace: "nowrap" }
    }, IGACC_STATUS_LABELS[value] || value),
    open && React.createElement("div", {
      style: { position: "absolute", top: "calc(100% + 4px)", left: 0, zIndex: 500, background: "#161616", border: "1px solid #2a2a2a", borderRadius: 8, padding: 6, display: "flex", flexDirection: "column", gap: 4, minWidth: 150, boxShadow: "0 8px 24px rgba(0,0,0,.5)" }
    },
      IGACC_STATUS_OPTIONS.map(function (opt) {
        const oc = IGACC_STATUS_COLORS[opt];
        return React.createElement("div", {
          key: opt,
          onClick: function (e) { e.stopPropagation(); setOpen(false); if (onChange) onChange(opt); },
          style: { background: oc.bg, color: oc.fg, borderRadius: 6, padding: "5px 10px", fontSize: 11, fontWeight: 700, cursor: "pointer", fontFamily: "'JetBrains Mono', monospace" }
        }, IGACC_STATUS_LABELS[opt] || opt);
      })
    )
  );
}

const IGACC_FIELDS = [
  { k: "email", l: "MAILS", ph: "ex: xxx@outlook.com" },
  { k: "passmail", l: "PASSMAIL", ph: "mot de passe email" },
  { k: "username", l: "IG USERNAME", ph: "ex: john.doe123", required: true },
  { k: "password", l: "PASS IG", ph: "" },
  { k: "phone", l: "PHONE", ph: "ex: +33 6 12 34 56 78" },
  { k: "model", l: "MODEL", ph: "ex: iPhone 8 Plus" },
  { k: "link", l: "LINK", ph: "https://instagram.com/..." },
  { k: "page_fb", l: "PAGE FB", ph: "" },
  { k: "code_2fa", l: "2FA KEY", ph: "ex: JBSWY3DPEHPK3PXP" },
  { k: "backup_code", l: "BACKUP", ph: "codes de secours" },
  { k: "container_name", l: "CONTENEUR (IPHONE)", ph: "ex: tulipe" },
  { k: "link_redirect", l: "LIEN REDIRECT", ph: "https://..." },
  { k: "instagram_url", l: "PROFIL INSTAGRAM", ph: "https://www.instagram.com/username/" },
  { k: "bio", l: "BIO", ph: "texte affiché sous le nom dans la carte (Mode grille)", area: true },
  { k: "notes", l: "NOTES", ph: "", area: true },
];
const IGACC_BLANK = { email: "", passmail: "", username: "", password: "", phone: "", model: "", link: "", page_fb: "", code_2fa: "", backup_code: "", container_name: "", link_redirect: "", instagram_url: "", bio: "", notes: "", tag_status: "Create", twofa_enabled: false };

// ── Style "carte compte" (avatar + pastille conteneur + horodatage relatif) ──
// Local à cette page uniquement : on ne touche pas à th/td/clickTd/tdStyle
// (partagés avec "Stockage comptes") pour ne pas changer l'autre tableau.
const IGACC_AVATAR_COLORS = ["#5b8def", "#a970ff", "#ff6b9d", "#ffb648", "#4dd4ac", "#ff7a59", "#57c7ff", "#c792ea"];
function igaccHash(s) { let h = 0; for (let i = 0; i < s.length; i++) h = (h * 31 + s.charCodeAt(i)) >>> 0; return h; }
function igaccAvatarColor(seed) { return IGACC_AVATAR_COLORS[igaccHash(seed || "?") % IGACC_AVATAR_COLORS.length]; }
function igaccRelTime(s) {
  if (!s) return "-";
  const d = new Date(String(s).replace(" ", "T"));
  if (isNaN(d.getTime())) return String(s).slice(0, 16);
  const min = Math.floor((Date.now() - d.getTime()) / 60000);
  if (min < 1) return "à l'instant";
  if (min < 60) return "il y a " + min + " min";
  const h = Math.floor(min / 60);
  if (h < 24) return "il y a " + h + " h";
  return "il y a " + Math.floor(h / 24) + " j";
}
function igaccContainerPill(name, onClick) {
  // même gabarit (padding/bordure/fontSize) rempli ou vide -> évite que les cartes avec un
  // vrai nom de conteneur soient plus hautes que celles à "-" et décalent tout ce qui suit
  // (stats, vignettes, footer) dans la même ligne de la grille.
  if (!name) return React.createElement("span", { style: { display: "inline-block", border: "1px solid transparent", borderRadius: 999, padding: "3px 11px", fontSize: 11, fontWeight: 700, color: "var(--faint)", whiteSpace: "nowrap" } }, "-");
  return React.createElement("span", {
    onClick: onClick,
    style: { display: "inline-block", background: "rgba(188,140,255,.14)", color: "#bc8cff", border: "1px solid rgba(188,140,255,.28)", borderRadius: 999, padding: "3px 11px", fontSize: 11, fontWeight: 700, whiteSpace: "nowrap", cursor: onClick ? "pointer" : "default" }
  }, name);
}
function igaccTypePill(kind) {
  if (!kind || kind === "-") return React.createElement("span", { style: { color: "var(--faint)", fontSize: 12 } }, "-");
  return React.createElement("span", { style: { fontSize: 10.5, fontWeight: 700, color: "var(--muted)", background: "var(--surface-3)", border: "1px solid var(--border)", borderRadius: 6, padding: "2px 7px" } }, kind);
}
// Vraie photo de profil si le compte en a une (livrée par le bloc "Trenduply — Récupérer
// média" kind=avatar, cf. automation_builder.jsx / colonne avatar_file) ; sinon repli sur le
// cercle coloré "initiale du username" (et repli aussi si le fichier a été déplacé/supprimé).
// Quand une identité Trenduply est connue (avatar_identity), une pastille 🎭 sur la photo
// indique de quelle persona elle vient (survol = nom complet).
function IgaccAvatar(props) {
  const a = props.account;
  const [failed, setFailed] = React.useState(false);
  const size = 32;
  const badge = a.avatar_identity
    ? React.createElement("span", {
        title: "Avatar Trenduply : " + a.avatar_identity,
        style: {
          position: "absolute", bottom: -2, right: -2, width: 15, height: 15, borderRadius: "50%",
          background: "#c9a9ff", border: "1.5px solid var(--surface)", display: "flex",
          alignItems: "center", justifyContent: "center", fontSize: 8
        }
      }, "🎭")
    : null;
  const img = (a.avatar_file && !failed)
    ? React.createElement("img", {
        src: "/api/media/file?path=" + encodeURIComponent("Trenduply/" + a.avatar_file),
        onError: function () { setFailed(true); },
        style: { width: size, height: size, borderRadius: "50%", flex: "0 0 auto", objectFit: "cover", background: "var(--surface-3)" }
      })
    : React.createElement("div", {
        style: { width: size, height: size, borderRadius: "50%", flex: "0 0 auto", background: igaccAvatarColor(a.username), display: "flex", alignItems: "center", justifyContent: "center", fontSize: 13, fontWeight: 800, color: "#0a0a0a" }
      }, (a.username || "?").slice(0, 1).toUpperCase());
  return React.createElement("div", { style: { position: "relative", flex: "0 0 auto", width: size, height: size } }, img, badge);
}

// Abonnés / vues : "-" tant qu'aucun relevé n'existe (colonnes prêtes côté DB, mais pas encore
// alimentées — le bloc de lecture OCR du profil IG reste à construire avec un iPhone connecté).
function igaccStatPill(icon, val, tone) {
  if (val === null || val === undefined || val === "") return React.createElement("span", { style: { color: "var(--faint)", fontSize: 12 } }, "-");
  const views = tone === "views";
  return React.createElement("span", {
    style: {
      display: "inline-flex", alignItems: "center", gap: 4, fontSize: 11.5, fontWeight: 700, borderRadius: 999, padding: "3px 10px", whiteSpace: "nowrap",
      background: views ? "rgba(201,169,255,.14)" : "var(--surface-3)", color: views ? "#c9a9ff" : "var(--text)",
      border: "1px solid " + (views ? "rgba(201,169,255,.28)" : "var(--border)")
    }
  }, icon + " " + Number(val).toLocaleString());
}
function igaccViewsCell(val, at) {
  if (val === null || val === undefined) return React.createElement("span", { style: { color: "var(--faint)", fontSize: 12 } }, "-");
  return React.createElement("div", null,
    igaccStatPill("▶", val, "views"),
    at ? React.createElement("div", { style: { fontSize: 9.5, color: "var(--faint)", marginTop: 3 } }, "🗓 " + igaccRelTime(at)) : null
  );
}

// ── Mode grille : une carte par compte (photo, bio, stats profil, derniers posts) ──
// Les stats (publications/suivi(e)s) viennent du scraping profil (cookie visionneur) ; les
// vignettes viennent des posts réels marqués par "Marquer reel posté" (ig_posts, visuel 1re
// frame). Les vues d'un post restent "-" tant que "Trenduply — Stats publication" ne les a pas
// renseignées pour ce video_id.
function igaccStatBlock(label, val) {
  return React.createElement("div", { style: { textAlign: "center", flex: 1 } },
    React.createElement("div", { style: { fontSize: 18, fontWeight: 800, color: (val === null || val === undefined) ? "var(--faint)" : "var(--text)" } }, (val === null || val === undefined) ? "-" : Number(val).toLocaleString()),
    React.createElement("div", { style: { fontSize: 9, color: "var(--faint)", letterSpacing: ".06em", textTransform: "uppercase", marginTop: 2 } }, label)
  );
}
function igaccThumb(post) {
  const src = post.thumb || post.file;
  return React.createElement("div", { key: post.id, style: { position: "relative", flex: 1, aspectRatio: "1", borderRadius: 8, background: "var(--surface-3)", overflow: "hidden" } },
    src && React.createElement("img", {
      src: "/api/media/file?path=" + encodeURIComponent("Trenduply/" + src),
      style: { width: "100%", height: "100%", objectFit: "cover", display: "block" },
      onError: function (e) { e.target.style.display = "none"; }
    }),
    React.createElement("span", {
      title: post.posted_at ? igaccRelTime(post.posted_at) : "",
      style: { position: "absolute", left: 5, bottom: 5, background: "rgba(0,0,0,.65)", color: "#fff", fontSize: 10, fontWeight: 700, borderRadius: 999, padding: "2px 7px" }
    }, "▶ " + ((post.views === null || post.views === undefined) ? "-" : Number(post.views).toLocaleString()))
  );
}
function igaccEmptyThumb(key) {
  return React.createElement("div", { key: "empty-" + key, style: { aspectRatio: "1", borderRadius: 8, background: "var(--surface-2)", border: "1px dashed var(--border-2)" } });
}
function IgaccCard(props) {
  const a = props.account;
  const banned = a.status === "Banni";
  const posts = props.posts || [];
  const deviceLabel = props.deviceLabel || "";
  const selectMode = props.selectMode;
  const selected = !!props.selected;
  return React.createElement("div", {
    onClick: selectMode ? function () { props.onToggleSelect(a.username); } : undefined,
    style: {
      background: selected ? "rgba(91,141,239,.08)" : "var(--surface)",
      border: "1px solid " + (selected ? "#5b8def" : (banned ? "rgba(248,81,73,.35)" : "var(--border)")),
      borderRadius: 12, padding: 14, display: "flex", flexDirection: "column", gap: 10,
      cursor: selectMode ? "pointer" : "default"
    }
  },
    React.createElement("div", { style: { display: "flex", alignItems: "flex-start", gap: 9 } },
      React.createElement(IgaccAvatar, { account: a }),
      React.createElement("div", { style: { flex: 1, minWidth: 0, cursor: selectMode ? "pointer" : "pointer" }, onClick: selectMode ? undefined : function (e) { e.stopPropagation(); props.onEdit(a); } },
        React.createElement("div", { style: { fontWeight: 700, fontSize: 13, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" } }, "@" + a.username),
        React.createElement("div", { style: { fontSize: 10.5, color: "var(--faint)", marginTop: 1 } }, a.nom || "—")
      ),
      React.createElement("div", { style: { display: "flex", flexDirection: "column", alignItems: "flex-end", gap: 4 } },
        deviceLabel && React.createElement("span", {
          title: "iPhone assigné",
          style: { background: "rgba(91,141,239,.12)", color: "#5b8def", border: "1px solid rgba(91,141,239,.3)", borderRadius: 6, padding: "2px 7px", fontSize: 9.5, fontWeight: 700, whiteSpace: "nowrap" }
        }, "📱 " + deviceLabel),
        banned
          ? React.createElement("span", { style: { background: "rgba(248,81,73,.14)", color: "#f85149", border: "1px solid rgba(248,81,73,.3)", borderRadius: 6, padding: "3px 8px", fontSize: 10, fontWeight: 700, whiteSpace: "nowrap" } }, "BANNI")
          : igaccContainerPill(a.container_name)
      ),
      selectMode && React.createElement("span", {
        onClick: function (e) { e.stopPropagation(); props.onToggleSelect(a.username); },
        style: {
          width: 20, height: 20, borderRadius: 6, flex: "0 0 auto", cursor: "pointer",
          background: selected ? "#5b8def" : "transparent", border: "1.5px solid " + (selected ? "#5b8def" : "var(--border-2)"),
          color: "#fff", fontSize: 12, fontWeight: 800, display: "flex", alignItems: "center", justifyContent: "center"
        }
      }, selected ? "✓" : "")
    ),
    React.createElement("div", { style: { fontSize: 11.5, color: "var(--faint)", lineHeight: 1.4, minHeight: "32px", whiteSpace: "pre-line", display: "-webkit-box", WebkitLineClamp: 2, WebkitBoxOrient: "vertical", overflow: "hidden" } }, a.bio || ""),
    React.createElement("div", { style: { display: "flex", borderTop: "1px solid var(--border)", borderBottom: "1px solid var(--border)", padding: "8px 0" } },
      igaccStatBlock("Publications", a.posts_count),
      igaccStatBlock("Abonnés", a.followers),
      igaccStatBlock("Suivi(e)s", a.following_count)
    ),
    React.createElement("div", { style: { display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 6 } },
      [0, 1, 2, 3, 4, 5].map(function (i) { return i < posts.length ? igaccThumb(posts[i]) : igaccEmptyThumb(i); })
    ),
    React.createElement("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" } },
      React.createElement("a", {
        href: a.instagram_url || ("https://www.instagram.com/" + encodeURIComponent(a.username) + "/"),
        target: "_blank", rel: "noopener noreferrer",
        style: { color: "#5b8def", fontSize: 11.5, fontWeight: 600, textDecoration: "none" }
      }, "🔗 Voir"),
      React.createElement("div", { style: { fontSize: 10, color: "var(--faint)" } }, igaccRelTime(a.created_at))
    )
  );
}
function IgaccGrid(props) {
  const accounts = props.accounts;
  const postsByUser = props.postsByUser || {};
  const deviceByUdid = props.deviceByUdid || {};
  if (!accounts.length) return React.createElement("div", { style: { textAlign: "center", padding: 48, color: "var(--faint)", fontSize: 13 } }, "Aucun compte");
  return React.createElement("div", { style: { display: "grid", gridTemplateColumns: "repeat(4, minmax(0, 1fr))", gap: 12 } },
    accounts.map(function (a, i) {
      // repli : udid connu mais pas (encore) labellisé dans "devices" (tel jamais connecté cette
      // session) -> on affiche quand même les 6 derniers caractères, convention déjà utilisée pour
      // les tels dans les logs moteur (engine_logs/h264_<6 car>.log) plutôt que de masquer le badge.
      const dLabel = deviceByUdid[a.device_udid] || (a.device_udid ? a.device_udid.slice(-6) : "");
      return React.createElement(IgaccCard, {
        key: a.id || i, account: a, posts: postsByUser[a.username] || [], deviceLabel: dLabel,
        onEdit: props.onEdit, onDelete: props.onDelete,
        selectMode: props.selectMode, selected: (props.selected || {})[a.username], onToggleSelect: props.onToggleSelect
      });
    })
  );
}

function ComptesInstagramPage() {
  const [accounts, setAccounts] = useState([]);
  const [loading, setLoading] = useState(true);
  const [showModal, setShowModal] = useState(false);
  const [editUsername, setEditUsername] = useState(null); // null = création
  const [form, setForm] = useState(IGACC_BLANK);
  const [saving, setSaving] = useState(false);
  const [err, setErr] = useState("");
  const [copied, setCopied] = useState(null);
  const [hoverRow, setHoverRow] = useState(null);
  const [view, setView] = useState("list"); // "list" | "grid"
  const [refreshing, setRefreshing] = useState(false);
  const [refreshMsg, setRefreshMsg] = useState("");
  const [statusFilter, setStatusFilter] = useState("all"); // "all" | "actif" | "banni"
  const [postsByUser, setPostsByUser] = useState({});
  const [deviceByUdid, setDeviceByUdid] = useState({});
  const [selectMode, setSelectMode] = useState(false); // Mode grille : sélection multiple -> suppression groupée
  const [selected, setSelected] = useState({}); // { username: true }
  // Masque les colonnes sensibles (Compte, Mails, Phone, Pass IG, 2FA) — utile pour
  // partager l'écran sans exposer d'identifiants réels. Rien n'est persisté : redémarre
  // démasqué à chaque ouverture de page, par sécurité.
  const [masked, setMasked] = useState(false);

  // Libellés des iPhones (device_udid -> label) pour le badge "device assigné" en Mode grille.
  const loadDevices = useCallback(function () {
    fetch("/api/devices").then(function (r) { return r.json(); })
      .then(function (d) {
        const map = {};
        (d.devices || []).forEach(function (dv) { map[dv.udid] = dv.label || dv.devicename || ""; });
        setDeviceByUdid(map);
      }).catch(function () {});
  }, []);

  const load = useCallback(function () {
    setLoading(true);
    fetch("/api/instagram/accounts").then(function (r) { return r.json(); })
      .then(function (d) { setAccounts(d.accounts || []); setLoading(false); })
      .catch(function () { setLoading(false); });
  }, []);

  // Derniers posts (visuel 1re frame + vues) groupés par compte, pour les vignettes du Mode grille.
  const loadPosts = useCallback(function () {
    fetch("/api/instagram/posts?limit=3").then(function (r) { return r.json(); })
      .then(function (d) { setPostsByUser(d || {}); })
      .catch(function () {});
  }, []);

  // Filtre BANNI/ACTIF, puis comptes "Banni" en tout premier (tri stable) — pareil dans les 2 vues.
  const sortedAccounts = useMemo(function () {
    const filtered = accounts.filter(function (a) {
      if (statusFilter === "banni") return a.status === "Banni";
      if (statusFilter === "actif") return a.status !== "Banni";
      return true;
    });
    return filtered.sort(function (a, b) { return (a.status === "Banni" ? 1 : 0) - (b.status === "Banni" ? 1 : 0); });
  }, [accounts, statusFilter]);

  const refreshStats = useCallback(async function () {
    setRefreshing(true); setRefreshMsg("");
    try {
      const r = await fetch("/api/instagram/accounts/refresh_profile_stats", { method: "POST" });
      const j = await r.json();
      setRefreshMsg(j.ok + " ok" + (j.failed && j.failed.length ? ", " + j.failed.length + " échec(s)" : ""));
      load(); loadPosts();
    } catch (e) {
      setRefreshMsg("Erreur : " + e.message);
    }
    setRefreshing(false);
  }, [load, loadPosts]);

  useEffect(function () { load(); loadPosts(); loadDevices(); }, [load, loadPosts, loadDevices]);

  const copy = useCallback(function (text, id) {
    if (!text || text === "-") return;
    try { navigator.clipboard.writeText(text); } catch (e) {}
    setCopied(id);
    setTimeout(function () { setCopied(null); }, 1500);
  }, []);

  const openCreate = useCallback(function () {
    setEditUsername(null); setForm(IGACC_BLANK); setErr(""); setShowModal(true);
  }, []);
  const openEdit = useCallback(function (a) {
    setEditUsername(a.username);
    setForm(Object.assign({}, IGACC_BLANK, a, { twofa_enabled: !!a.twofa_enabled }));
    setErr(""); setShowModal(true);
  }, []);

  const save = useCallback(async function () {
    const uname = (form.username || "").trim();
    if (!uname) { setErr("Username requis"); return; }
    setSaving(true); setErr("");
    try {
      const body = Object.assign({}, form, { username: uname, twofa_enabled: form.twofa_enabled ? 1 : 0 });
      if (editUsername) {
        await fetch("/api/instagram/accounts/" + encodeURIComponent(editUsername), {
          method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body)
        });
      } else {
        const r = await fetch("/api/instagram/accounts", {
          method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body)
        });
        const j = await r.json();
        if (j.error) { setErr(j.error); setSaving(false); return; }
      }
      setSaving(false); setShowModal(false); load();
    } catch (e) { setErr(String(e)); setSaving(false); }
  }, [form, editUsername, load]);

  const remove = useCallback(async function (uname, skipConfirm) {
    // skipConfirm : mode grille sur un compte "Banni" -> suppression directe, pas de popup
    // (le compte est déjà confirmé mort côté Instagram, inutile de redemander).
    if (!skipConfirm && !window.confirm("Supprimer @" + uname + " ?")) return;
    await fetch("/api/instagram/accounts/" + encodeURIComponent(uname), { method: "DELETE" });
    load();
  }, [load]);

  const updateTagStatus = useCallback(async function (uname, v) {
    setAccounts(function (prev) { return prev.map(function (x) { return x.username === uname ? Object.assign({}, x, { tag_status: v }) : x; }); });
    await fetch("/api/instagram/accounts/" + encodeURIComponent(uname), {
      method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ tag_status: v })
    });
  }, []);

  const toggleSelect = useCallback(function (uname) {
    setSelected(function (prev) {
      const next = Object.assign({}, prev);
      if (next[uname]) delete next[uname]; else next[uname] = true;
      return next;
    });
  }, []);

  const selectedCount = Object.keys(selected).length;

  const toggleSelectMode = useCallback(function () {
    setSelectMode(function (v) { return !v; });
    setSelected({});
  }, []);

  const removeSelected = useCallback(async function () {
    const unames = Object.keys(selected);
    if (!unames.length) return;
    if (!window.confirm("Supprimer " + unames.length + " compte(s) sélectionné(s) ?")) return;
    await Promise.all(unames.map(function (u) { return fetch("/api/instagram/accounts/" + encodeURIComponent(u), { method: "DELETE" }); }));
    setSelected({}); setSelectMode(false); load();
  }, [selected, load]);

  // Masquage des colonnes sensibles (cf. état `masked`) : remplace par des points, sauf "-"
  // (rien à cacher). Appliqué à la valeur AVANT clickTd -> tant que masqué, on copie aussi
  // les points (pas la vraie valeur) — cohérent avec l'intention (rien de réel à l'écran).
  function mask(v) { return masked && v && v !== "-" ? "••••••••" : v; }

  const labelStyle = { fontSize: 10, color: "#888", fontWeight: 700, textTransform: "uppercase", letterSpacing: ".06em", marginBottom: 4, fontFamily: "'JetBrains Mono', monospace" };
  const inputStyle = { width: "100%", boxSizing: "border-box", background: "#111", border: "1px solid #222", borderRadius: 6, color: "#e5e5e5", fontSize: 12, padding: "7px 10px", fontFamily: "'JetBrains Mono', monospace" };

  return React.createElement("div", { style: { padding: "16px 24px" } },
    React.createElement("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 16 } },
      React.createElement("div", { style: { display: "flex", alignItems: "center", gap: 10 } },
        React.createElement("div", { style: { fontSize: 16, fontWeight: 800, color: "#e5e5e5", fontFamily: "'JetBrains Mono', monospace" } }, "📱 Comptes Instagram · " + accounts.length),
        React.createElement("button", {
          onClick: function () { setMasked(function (v) { return !v; }); },
          title: masked ? "Afficher les infos sensibles (compte, mails, phone, pass IG, 2FA)" : "Masquer les infos sensibles (compte, mails, phone, pass IG, 2FA)",
          style: { background: masked ? "var(--surface-3)" : "transparent", border: "1px solid " + (masked ? "var(--border-2)" : "var(--border)"), color: masked ? "var(--text)" : "var(--faint)", borderRadius: 999, width: 30, height: 30, display: "flex", alignItems: "center", justifyContent: "center", fontSize: 14, cursor: "pointer" }
        }, masked ? "🙈" : "👁️")
      ),
      React.createElement("div", { style: { display: "flex", alignItems: "center", gap: 10 } },
        refreshMsg && React.createElement("span", { style: { fontSize: 11, color: "var(--faint)" } }, refreshMsg),
        view === "grid" && selectMode && selectedCount > 0 && React.createElement("button", {
          onClick: removeSelected,
          style: { background: "rgba(248,81,73,.14)", border: "1px solid rgba(248,81,73,.35)", borderRadius: 999, color: "#f85149", fontSize: 12.5, fontWeight: 700, padding: "9px 16px", cursor: "pointer" }
        }, "🗑️ Supprimer (" + selectedCount + ")"),
        view === "grid" && React.createElement("button", {
          onClick: toggleSelectMode,
          style: {
            background: selectMode ? "var(--surface-3)" : "transparent", border: "1px solid " + (selectMode ? "var(--border-2)" : "var(--border)"),
            color: selectMode ? "var(--text)" : "var(--faint)", borderRadius: 999, fontSize: 12.5, fontWeight: 700, padding: "9px 16px", cursor: "pointer"
          }
        }, selectMode ? "✕ Annuler la sélection" : "☑️ Sélectionner"),
        React.createElement("button", {
          onClick: refreshStats, disabled: refreshing,
          style: { background: "var(--surface-3)", border: "1px solid var(--border-2)", borderRadius: 999, color: "var(--text)", fontSize: 12.5, fontWeight: 700, padding: "9px 16px", cursor: refreshing ? "default" : "pointer", opacity: refreshing ? .6 : 1 }
        }, refreshing ? "⏳ Rafraîchissement…" : "🔄 Rafraîchir les stats"),
        React.createElement("button", {
          onClick: openCreate,
          style: { background: "#238636", border: "none", borderRadius: 999, color: "#fff", fontSize: 12.5, fontWeight: 700, padding: "9px 18px", cursor: "pointer" }
        }, "➕ Ajouter un compte")
      )
    ),
    React.createElement("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 14, flexWrap: "wrap", gap: 10 } },
      React.createElement("div", { style: { display: "flex", gap: 6 } },
        ["list", "grid"].map(function (v) {
          return React.createElement("button", {
            key: v,
            onClick: function () { setView(v); },
            style: {
              background: view === v ? "var(--surface-3)" : "transparent", border: "1px solid " + (view === v ? "var(--border-2)" : "var(--border)"),
              color: view === v ? "var(--text)" : "var(--faint)", borderRadius: 999, padding: "6px 14px", fontSize: 11.5, fontWeight: 700, cursor: "pointer"
            }
          }, v === "list" ? "☰ Mode liste" : "▦ Mode grille");
        })
      ),
      React.createElement("div", { style: { display: "flex", gap: 6 } },
        [
          ["all", "Tous", accounts.length],
          ["actif", "Actif", accounts.filter(function (a) { return a.status !== "Banni"; }).length],
          ["banni", "Banni", accounts.filter(function (a) { return a.status === "Banni"; }).length]
        ].map(function (f) {
          const active = statusFilter === f[0];
          return React.createElement("button", {
            key: f[0],
            onClick: function () { setStatusFilter(f[0]); },
            style: {
              background: active ? (f[0] === "banni" ? "rgba(248,81,73,.14)" : "var(--surface-3)") : "transparent",
              border: "1px solid " + (active ? (f[0] === "banni" ? "rgba(248,81,73,.35)" : "var(--border-2)") : "var(--border)"),
              color: active ? (f[0] === "banni" ? "#f85149" : "var(--text)") : "var(--faint)",
              borderRadius: 999, padding: "6px 14px", fontSize: 11.5, fontWeight: 700, cursor: "pointer"
            }
          }, f[1] + " (" + f[2] + ")");
        })
      )
    ),
    view === "grid" && (loading
      ? React.createElement("div", { style: { textAlign: "center", padding: 48, color: "var(--faint)", fontSize: 13 } }, "Chargement…")
      : React.createElement(IgaccGrid, { accounts: sortedAccounts, postsByUser: postsByUser, deviceByUdid: deviceByUdid, onEdit: openEdit, onDelete: remove, selectMode: selectMode, selected: selected, onToggleSelect: toggleSelect })
    ),
    view === "list" && React.createElement("div", { style: { borderRadius: 12, border: "1px solid var(--border)", overflow: "hidden", background: "var(--surface)" } },
      React.createElement("div", { style: { overflowX: "auto" } },
        React.createElement("table", { style: { width: "100%", borderCollapse: "collapse" } },
          React.createElement("thead", null,
            React.createElement("tr", null,
              th("STATUS"), th("COMPTE"), th("MODEL"), th("CONTAINER"), th("LINK"), th("CRÉATION"), th("PROFIL IG"), th("PUBLICATIONS"), th("ABONNÉS"), th("VUES DERNIER"), th("VUES AVANT-DERNIER"), th("MAILS"), th("PASS IG"), th("PHONE"), th("2FA KEY"), th("2FA"), th("AJOUTÉ"), th("")
            )
          ),
          React.createElement("tbody", null,
            loading
              ? React.createElement("tr", null, React.createElement("td", { colSpan: 18, style: { textAlign: "center", padding: 32, color: "var(--faint)", fontSize: 13 } }, "Chargement…"))
              : sortedAccounts.length === 0
                ? React.createElement("tr", null, React.createElement("td", { colSpan: 18, style: { textAlign: "center", padding: 32, color: "var(--faint)", fontSize: 13 } }, "Aucun compte"))
                : sortedAccounts.map(function (a, i) {
                  return React.createElement("tr", {
                    key: a.id || i,
                    style: { borderTop: "1px solid var(--border)", background: hoverRow === i ? "var(--surface-2)" : "transparent", transition: "background .12s" },
                    onMouseEnter: function () { setHoverRow(i); },
                    onMouseLeave: function () { setHoverRow(null); }
                  },
                    React.createElement("td", { style: tdStyle, onClick: function (e) { e.stopPropagation(); } },
                      a.status === "Banni"
                        ? React.createElement("span", {
                            title: "Compte introuvable sur Instagram (supprimé/renommé)",
                            style: { background: "rgba(248,81,73,.14)", color: "#f85149", border: "1px solid rgba(248,81,73,.3)", borderRadius: 6, padding: "4px 10px", fontSize: 10.5, fontWeight: 700, textDecoration: "line-through", whiteSpace: "nowrap" }
                          }, "BANNI")
                        : React.createElement(IgaccTagStatusPicker, {
                            value: a.tag_status || "Create",
                            onChange: function (v) { updateTagStatus(a.username, v); }
                          })
                    ),
                    React.createElement("td", { style: Object.assign({}, tdStyle, { padding: "11px 10px", cursor: "pointer" }), onClick: function () { openEdit(a); } },
                      React.createElement("div", { style: { display: "flex", alignItems: "center", gap: 9 } },
                        React.createElement(IgaccAvatar, { account: a }),
                        React.createElement("div", null,
                          React.createElement("a", {
                            href: "https://www.instagram.com/" + encodeURIComponent(a.username) + "/",
                            target: "_blank", rel: "noopener noreferrer",
                            title: "Ouvrir le profil Instagram",
                            onClick: function (e) { e.stopPropagation(); },
                            style: { color: a.status === "Banni" ? "#f85149" : "var(--text)", textDecoration: a.status === "Banni" ? "line-through" : "none", fontWeight: 700, fontSize: 12.5 }
                          }, masked ? "@••••••••" : "@" + a.username),
                          React.createElement("div", { style: { fontSize: 10.5, color: "var(--faint)", marginTop: 1 } }, masked ? "••••••••" : (a.nom || "—"))
                        )
                      )
                    ),
                    td(a.model || "-"),
                    React.createElement("td", { style: Object.assign({}, tdStyle, { padding: "11px 10px" }), onClick: function () { openEdit(a); } }, igaccContainerPill(a.container_name)),
                    React.createElement("td", { style: Object.assign({}, tdStyle, { padding: "11px 10px" }) },
                      React.createElement("a", {
                        href: a.link || a.link_redirect || ("https://yourlittleflower.com/" + a.username),
                        target: "_blank", rel: "noopener noreferrer",
                        onClick: function (e) { e.stopPropagation(); },
                        style: { color: "#5b8def", fontSize: 11.5, textDecoration: "none" }
                      }, "🔗 Voir")
                    ),
                    React.createElement("td", { style: Object.assign({}, tdStyle, { padding: "11px 10px" }) }, igaccTypePill(a.email ? "MAIL" : (a.phone ? "NUM" : "-"))),
                    React.createElement("td", { style: Object.assign({}, tdStyle, { padding: "11px 10px" }) },
                      React.createElement("a", {
                        href: a.instagram_url || ("https://www.instagram.com/" + encodeURIComponent(a.username) + "/"),
                        target: "_blank", rel: "noopener noreferrer",
                        onClick: function (e) { e.stopPropagation(); },
                        style: { color: "#5b8def", fontSize: 11.5, textDecoration: "none" }
                      }, "🔗 Voir")
                    ),
                    React.createElement("td", { style: Object.assign({}, tdStyle, { padding: "11px 10px" }) }, igaccStatPill("📸", a.posts_count, "followers")),
                    React.createElement("td", { style: Object.assign({}, tdStyle, { padding: "11px 10px" }) }, igaccStatPill("👤", a.followers, "followers")),
                    React.createElement("td", { style: Object.assign({}, tdStyle, { padding: "11px 10px" }) }, igaccViewsCell(a.views_last, a.views_last_at)),
                    React.createElement("td", { style: Object.assign({}, tdStyle, { padding: "11px 10px" }) }, igaccViewsCell(a.views_prev, a.views_prev_at)),
                    clickTd(mask(a.email || "-"), "ig-mail-" + i, copied, copy),
                    clickTd(mask(a.password || "-"), "ig-pass-" + i, copied, copy),
                    clickTd(mask(a.phone || "-"), "ig-phone-" + i, copied, copy),
                    clickTd(mask(a.code_2fa || "-"), "ig-2fa-" + i, copied, copy),
                    React.createElement("td", { style: tdStyle }, a.code_2fa ? React.createElement("span", { style: { color: "#4caf50" } }, "oui") : React.createElement("span", { style: { color: "var(--faint)" } }, "non")),
                    React.createElement("td", { className: "mono", style: Object.assign({}, tdStyle, { color: "var(--muted)" }), title: (a.created_at || "").slice(0, 16) }, igaccRelTime(a.created_at)),
                    React.createElement("td", { style: tdStyle },
                      a.status === "Banni"
                        ? null
                        : React.createElement("button", {
                            onClick: function (e) { e.stopPropagation(); remove(a.username); },
                            title: "Supprimer",
                            style: { width: 26, height: 26, borderRadius: "50%", background: "rgba(248,81,73,.10)", border: "1px solid rgba(248,81,73,.25)", color: "#f85149", cursor: "pointer", fontSize: 12, display: "flex", alignItems: "center", justifyContent: "center" }
                          }, "✕")
                    )
                  );
                })
          )
        )
      )
    ),
    showModal && React.createElement("div", {
      style: { position: "fixed", inset: 0, background: "rgba(0,0,0,.7)", zIndex: 9999, display: "grid", placeItems: "center", padding: 20 },
      onClick: function (e) { if (e.target === e.currentTarget && !saving) setShowModal(false); }
    },
      React.createElement("div", { style: { background: "#0e0e0e", border: "1px solid #222", borderRadius: 14, padding: 24, width: 420, maxHeight: "88vh", overflowY: "auto" } },
        React.createElement("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 16 } },
          React.createElement("span", { style: { fontWeight: 800, fontSize: 14, color: "#e5e5e5", fontFamily: "'JetBrains Mono', monospace" } }, editUsername ? "✏️ @" + editUsername : "➕ Ajouter un compte"),
          React.createElement("button", { onClick: function () { if (!saving) setShowModal(false); }, style: { background: "none", border: "none", color: "#555", fontSize: 18, cursor: "pointer" } }, "✕")
        ),
        err && React.createElement("div", { style: { marginBottom: 12, padding: "8px 12px", borderRadius: 8, fontSize: 11.5, background: "rgba(244,67,54,.12)", color: "#f44336", border: "1px solid rgba(244,67,54,.3)" } }, err),
        IGACC_FIELDS.map(function (f) {
          return React.createElement("div", { key: f.k, style: { marginBottom: 12 } },
            React.createElement("div", { style: labelStyle }, f.l),
            f.area
              ? React.createElement("textarea", {
                value: form[f.k] || "", placeholder: f.ph, rows: 3,
                onChange: function (e) { const v = e.target.value; setForm(function (prev) { return Object.assign({}, prev, { [f.k]: v }); }); },
                style: Object.assign({}, inputStyle, { resize: "vertical" })
              })
              : React.createElement("input", {
                value: form[f.k] || "", placeholder: f.ph, disabled: f.k === "username" && !!editUsername,
                onChange: function (e) { const v = e.target.value; setForm(function (prev) { return Object.assign({}, prev, { [f.k]: v }); }); },
                style: inputStyle
              })
          );
        }),
        React.createElement("label", { style: { display: "flex", alignItems: "center", gap: 6, fontSize: 12, color: "#8b949e", marginBottom: 16 } },
          React.createElement("input", {
            type: "checkbox", checked: !!form.twofa_enabled,
            onChange: function (e) { const v = e.target.checked; setForm(function (prev) { return Object.assign({}, prev, { twofa_enabled: v }); }); }
          }),
          "2FA activée"
        ),
        React.createElement("button", {
          onClick: save, disabled: saving,
          style: { width: "100%", background: "#238636", border: "none", borderRadius: 8, color: "#fff", fontSize: 13, fontWeight: 700, padding: "10px 0", cursor: saving ? "default" : "pointer", opacity: saving ? .6 : 1 }
        }, saving ? "Sauvegarde…" : "Enregistrer")
      )
    )
  );
}

window.ComptesInstagramPage = ComptesInstagramPage;
