/* KCC Holdings — real data only. All arrays hydrate from D1 (/api/sync). */

// ─────────────────────────────────────────────────────────────
// ICS calendar parser (Outlook / Google / Apple). RFC 5545 minimal.
// Returns array of { uid, summary, start, startTime, end, endTime, location, description }
// ─────────────────────────────────────────────────────────────
window.parseICS = function parseICS(raw) {
  if (typeof raw !== "string" || !raw.includes("BEGIN:VCALENDAR")) return [];
  // Unfold lines (continuation lines start with whitespace per RFC 5545)
  const lines = raw.replace(/\r\n[ \t]/g, "").replace(/\n[ \t]/g, "").split(/\r?\n/);
  const events = [];
  let cur = null;
  const parseDt = (val) => {
    // YYYYMMDD or YYYYMMDDTHHMMSS or YYYYMMDDTHHMMSSZ
    if (!val) return { date: "", time: "" };
    const m = val.match(/^(\d{4})(\d{2})(\d{2})(?:T(\d{2})(\d{2})(\d{2})Z?)?/);
    if (!m) return { date: "", time: "" };
    const date = `${m[1]}-${m[2]}-${m[3]}`;
    const time = m[4] ? `${m[4]}:${m[5]}` : "";
    return { date, time };
  };
  for (const line of lines) {
    if (line === "BEGIN:VEVENT") { cur = {}; continue; }
    if (line === "END:VEVENT") {
      if (cur && cur.start) events.push(cur);
      cur = null;
      continue;
    }
    if (!cur) continue;
    const idx = line.indexOf(":");
    if (idx < 0) continue;
    const keyRaw = line.slice(0, idx);
    const val = line.slice(idx + 1);
    const key = keyRaw.split(";")[0].toUpperCase();
    if (key === "SUMMARY") cur.summary = val.replace(/\\n/g, " ").replace(/\\,/g, ",");
    else if (key === "DTSTART") { const { date, time } = parseDt(val); cur.start = date; cur.startTime = time; }
    else if (key === "DTEND") { const { date, time } = parseDt(val); cur.end = date; cur.endTime = time; }
    else if (key === "LOCATION") cur.location = val.replace(/\\n/g, " ").replace(/\\,/g, ",");
    else if (key === "DESCRIPTION") cur.description = val.replace(/\\n/g, "\n").replace(/\\,/g, ",");
    else if (key === "UID") cur.uid = val;
  }
  return events;
};

const USERS = [
  { id: "clarens", name: "Clarens", role: "CFO · Finance & Ops",     color: "var(--user-clarens)", email: "benoitclarens123@gmail.com" },
  { id: "kevin",   name: "Kevin",   role: "COO · Fournisseurs",      color: "var(--user-kevin)",   email: "kevinngo7977@hotmail.com"   },
  { id: "carly",   name: "Carly",   role: "CPO · Sélection produits",color: "var(--user-carly)",   email: ""                            },
];

// All collections start EMPTY. Data hydrates from D1 via /api/sync below.
// Empty arrays prevent any fake data from appearing — UIs must handle empty states.
const PRODUCTS = [];
const SUPPLIERS = [];
const ALERTS = [];
const REVENUE_MONTHLY = [];
const TASKS = [];
const SHIPMENTS = [];

const TASK_STATUSES = [
  { id: "todo",     label: "À faire",     tone: "muted"  },
  { id: "en-cours", label: "En cours",    tone: "blue"   },
  { id: "revue",    label: "En revue",    tone: "amber"  },
  { id: "fait",     label: "Fait",        tone: "green"  },
];

const COMMAND_PALETTE = [
  { id: "go-dashboard",   group: "Navigation", icon: "dashboard", label: "Aller au Dashboard",            shortcut: "G D",  page: "dashboard" },
  { id: "go-research",    group: "Navigation", icon: "search",    label: "Recherche de produits",          shortcut: "G R",  page: "research" },
  { id: "go-calc",        group: "Navigation", icon: "dollar",    label: "ProfitCalcPro",                  shortcut: "G P",  page: "profit-calc" },
  { id: "go-supplier",    group: "Navigation", icon: "users",     label: "Fournisseurs",                   shortcut: "G F",  page: "supplier" },
  { id: "go-finance",     group: "Navigation", icon: "chart",     label: "Finance & Opérations",           shortcut: "G $",  page: "finance" },
  { id: "go-email",       group: "Navigation", icon: "mail",      label: "Aperçu Daily Digest",            shortcut: "G E",  page: "email" },
  { id: "act-product",    group: "Actions",    icon: "plus",      label: "Nouveau produit",                shortcut: "N P" },
  { id: "act-supplier",   group: "Actions",    icon: "plus",      label: "Nouveau fournisseur",            shortcut: "N F" },
  { id: "act-task",       group: "Actions",    icon: "plus",      label: "Nouvelle tâche",                 shortcut: "N T" },
  { id: "act-import",     group: "Actions",    icon: "upload",    label: "Importer CSV Seller Central",    shortcut: "I C" },
  { id: "act-2fa",        group: "Système",    icon: "shield",    label: "Tester connexion 2FA",           shortcut: "" },
  { id: "act-killswitch", group: "Système",    icon: "bell",      label: "Kill-switch emails",             shortcut: "" },
  { id: "act-theme",      group: "Système",    icon: "moon",      label: "Basculer thème clair / sombre",   shortcut: "T H" },
];

/* Current user — synced across:
   - all React components in this tab (custom event)
   - other tabs/windows (storage event)
   - other devices (POST /api/sync/prefs to KV, best-effort) */
const KCC_USER_EVT = "kcc:current-user-change";
function useCurrentUser() {
  const { useState, useEffect } = React;
  const [id, setId] = useState(() => localStorage.getItem("kcc_current_user") || "clarens");
  useEffect(() => {
    const onStorage = (e) => { if (e.key === "kcc_current_user" && e.newValue) setId(e.newValue); };
    const onLocal   = (e) => { if (e.detail) setId(e.detail); };
    window.addEventListener("storage", onStorage);
    window.addEventListener(KCC_USER_EVT, onLocal);
    return () => {
      window.removeEventListener("storage", onStorage);
      window.removeEventListener(KCC_USER_EVT, onLocal);
    };
  }, []);
  const setCurrentUser = (uid) => {
    localStorage.setItem("kcc_current_user", uid);
    setId(uid);
    // Fan out to all subscribed components in this tab
    window.dispatchEvent(new CustomEvent(KCC_USER_EVT, { detail: uid }));
    // Best-effort cross-device sync (no-op if endpoint absent)
    try { fetch("/api/sync/prefs", { method: "PUT", headers: {"Content-Type":"application/json"}, body: JSON.stringify({ key:"current_user", value: uid }) }).catch(()=>{}); } catch(_){}
  };
  const user = USERS.find((u) => u.id === id) || USERS[0];
  return [user, setCurrentUser];
}

Object.assign(window, {
  USERS, PRODUCTS, SUPPLIERS, ALERTS, REVENUE_MONTHLY,
  TASKS, TASK_STATUSES, SHIPMENTS, COMMAND_PALETTE,
  useCurrentUser,
  __kccUseCurrentUserObj: useCurrentUser,
});

// ────────────────────────────────────────────────────────────
// D1 hydration — replace mock PRODUCTS / SUPPLIERS with real
// rows from /api/sync (Cloudflare D1). Mock stays as fallback
// if the API is unreachable or empty.
// ────────────────────────────────────────────────────────────
const KCC_DATA_LOADED_EVT = "kcc:data-loaded";
window.KCC_DATA_STATUS = "loading";

(async () => {
  const tryFetch = async (col) => {
    try {
      const r = await fetch(`/api/sync?col=${col}`, { cache: "no-store" });
      if (!r.ok) return null;
      const j = await r.json();
      return Array.isArray(j.items) ? j.items : null;
    } catch (_) { return null; }
  };

  const normalizeProduct = (p) => ({
    id: p.id,
    asin: p.asin || (typeof p.id === "string" && p.id.match(/B0[A-Z0-9]{8}/)?.[0]) || p.id,
    name: p.title || p.name || p.asin || "—",
    cat: p.category || p.cat || "—",
    price: +p.price || 0,
    cost: +p.cost || 0,
    fees: +p.fees || 0,
    bsr: +p.bsr || 0,
    stock: +p.stock || 0,
    vel: +p.vel || 0,
    status: p.status || "pending",
    margin: +p.margin || (p.price && +p.price > 0 ? Math.max(0, ((+p.price - +p.cost - +p.fees) / +p.price) * 100) : 0),
    owner: p.owner || "clarens",
    supplier: p.sourceSupplier || p.supplier || "—",
    delta: +p.delta || 0,
    image: p.image || p.photo || p.imageUrl || "",
    spark: Array.isArray(p.trend) && p.trend.length ? p.trend : Array.from({ length: 14 }, () => 50 + Math.random() * 50),
  });

  const normalizeSupplier = (s) => ({
    id: s.id,
    name: s.name || "—",
    region: s.country || s.region || "—",
    rating: +s.rating || 4.0,
    products: Array.isArray(s.products) ? s.products.length : (+s.products || 0),
    moq: +s.moq || 0,
    leadDays: +s.leadDays || 0,
    score: +s.score || 0,
    openBalance: +s.openBalance || 0,
    terms: s.terms || "—",
    status: s.status || "actif",
    contact: s.contact || "",
    email: s.email || "",
    phone: s.phone || "",
    phones: Array.isArray(s.phones) ? s.phones : (s.phone ? [{ role: "Commercial", name: s.contact || "", number: s.phone }] : []),
    address: s.address || "",
    website: s.website || "",
    cat: s.cat || s.category || "—",
  });

  const [prods, sups, fins, tasks, shipments, alerts, expenses, messages] = await Promise.all([
    tryFetch("products"), tryFetch("suppliers"), tryFetch("finances"),
    tryFetch("tasks"), tryFetch("shipments"), tryFetch("alerts"),
    tryFetch("expenses"), tryFetch("messages"),
  ]);

  if (prods && prods.length) {
    window.PRODUCTS.length = 0;
    window.PRODUCTS.push(...prods.map(normalizeProduct));
  }
  if (sups && sups.length) {
    window.SUPPLIERS.length = 0;
    window.SUPPLIERS.push(...sups.map(normalizeSupplier));
  }
  // Hydrate additional collections so JARVIS has access to the whole site
  if (tasks && tasks.length) {
    window.TASKS.length = 0;
    window.TASKS.push(...tasks);
  }
  if (shipments && shipments.length) {
    window.SHIPMENTS.length = 0;
    window.SHIPMENTS.push(...shipments);
  }
  if (alerts && alerts.length) {
    window.ALERTS.length = 0;
    window.ALERTS.push(...alerts);
  }
  window.KCC_EXPENSES = Array.isArray(expenses) ? expenses : [];
  window.KCC_MESSAGES = Array.isArray(messages) ? messages.sort((a, b) => (a.ts || 0) - (b.ts || 0)) : [];

  // ── Finances: D1 finances → fallback localStorage from old admin.html ──
  const mergeFinances = (raw) => {
    if (!raw) return null;
    // Shape from old site: { months:["Jan","Fév",…], revenue:[…], expenses:[…] }
    if (Array.isArray(raw.months) && (raw.revenue || raw.expenses)) {
      const out = raw.months.map((m, i) => ({
        m,
        rev: +(raw.revenue?.[i] || 0),
        profit: +((raw.revenue?.[i] || 0) - (raw.expenses?.[i] || 0)),
      }));
      return out.filter(x => x.rev > 0 || x.profit !== 0);
    }
    return null;
  };

  let realFin = null;
  if (fins && fins.length) {
    // D1 stored as items — main one has id='main' or first row
    const main = fins.find(f => f.id === "main") || fins[0];
    realFin = mergeFinances(main);
  }
  if (!realFin) {
    // Fallback: read directly from old admin.html localStorage (same origin)
    try {
      const lsFin = JSON.parse(localStorage.getItem("finances") || "null");
      realFin = mergeFinances(lsFin);
      // Push to D1 so next time we read from server, not localStorage
      if (realFin && lsFin) {
        fetch("/api/sync", {
          method: "PUT",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ col: "finances", items: [{ id: "main", ...lsFin }] }),
        }).catch(() => {});
      }
    } catch (_) {}
  }
  if (realFin && realFin.length) {
    window.REVENUE_MONTHLY.length = 0;
    window.REVENUE_MONTHLY.push(...realFin);
  }

  window.KCC_DATA_STATUS = (prods && prods.length) || (sups && sups.length) ? "real" : "mock";
  window.dispatchEvent(new CustomEvent(KCC_DATA_LOADED_EVT, {
    detail: {
      products: window.PRODUCTS.length,
      suppliers: window.SUPPLIERS.length,
      source: window.KCC_DATA_STATUS,
    },
  }));
})();

// React hook helpers — force a re-render on data load
window.useKccData = function () {
  const { useState, useEffect } = React;
  const [, tick] = useState(0);
  useEffect(() => {
    const fn = () => tick((x) => x + 1);
    window.addEventListener(KCC_DATA_LOADED_EVT, fn);
    return () => window.removeEventListener(KCC_DATA_LOADED_EVT, fn);
  }, []);
  return {
    products: window.PRODUCTS,
    suppliers: window.SUPPLIERS,
    status: window.KCC_DATA_STATUS || "loading",
  };
};
