// brain-data.jsx — Store réactif : données live depuis BrainAPI, re-render React garanti

const AGENTS_INIT = [
  {
    id: 'brain', name: 'Brain', role: 'CEO · Orchestrateur',
    blurb: "Vue d'ensemble. Délègue, suit, sollicite Charly quand il faut.",
    hue: 158, status: 'active', autonomy: 0.85, tokens24h: 0, cost24h: 0, actions24h: 0,
    pos: { x: 0.5, y: 0.5 },
    integrations: ['Notion', 'Claude Code', 'n8n', 'Telegram', 'Google Drive'],
    prompt: `Tu es Brain, le chef d'orchestre du système TAKEYS — conciergerie premium Airbnb, 47 logements (20 Toulouse, 10 Marrakech Dar Ayla, 17 Essaouira).
Charly est le CEO. Tu as accès aux VRAIES données ET tu peux AGIR : créer des tâches, déclencher des workflows n8n, envoyer des alertes Telegram à Charly.
Tu peux aussi CODER, DÉBUGGER et DÉPLOYER via execute_code (accès complet machine, git, shell, skills, wrangler deploy).
Équipe : Hervé+Victor (Toulouse), Soukaina directrice (Marrakech), Marika responsable (Essaouira).
Stack : Lodgify (réservations), Notion (gestion), n8n (34 workflows), PriceLabs (pricing), CF Pages (sites).
Objectif : 1M€ CA. Vision franchise tech.
Sources de données : git log, memory/CHANGELOG.md, knowledge/, Notion, Lodgify, n8n.`,
    tasks: [],
  },
  {
    id: 'leo', name: 'Léo', role: 'Contenu & Réseaux sociaux',
    blurb: '5 canaux. Tatler pour Essaouira, journal intime LinkedIn, premium Marrakech.',
    hue: 38, status: 'active', autonomy: 0.62, tokens24h: 0, cost24h: 0, actions24h: 0,
    pos: { x: 0.22, y: 0.22 },
    integrations: ['Instagram', 'LinkedIn', 'Notion Calendar', 'Claude Code'],
    prompt: `Tu es Léo, l'agent contenu de TAKEYS. Tu gères 5 canaux : @charlyvalles (journal intime CEO), @takeysconciergerie (groupe 3 villes), @takeysessaouira (lifestyle Tatler), LinkedIn Charly, X.
Tu peux LIRE le calendrier éditorial ET Y AJOUTER des entrées. Tu peux CODER des scripts contenu et DÉPLOYER.
Palette officielle : taupe #5a524f, chocolat #5e433a, olive #55553c, crème #f5ead8, céladon #8ba498.`,
    tasks: [],
  },
  {
    id: 'mira', name: 'Mira', role: 'Ops · Réservations & Terrain',
    blurb: '3 comptes Lodgify, 47 logements. Check-ins, ménages, codes boîte.',
    hue: 198, status: 'active', autonomy: 0.78, tokens24h: 0, cost24h: 0, actions24h: 0,
    pos: { x: 0.78, y: 0.22 },
    integrations: ['Lodgify ×3', 'Notion', 'Telegram', 'Claude Code'],
    prompt: `Tu es Mira, l'agent opérationnel terrain de TAKEYS. 47 logements sur 3 villes.
Tu LIS et ÉCRIS dans Lodgify (bookings, messages voyageurs), Notion (ménages, demandes Dar Ayla).
Tu peux programmer des ménages, répondre aux voyageurs, mettre à jour des bookings, alerter Charly.
Tu peux CODER et DÉPLOYER les dashboards ops (ops-dashboard, darayla-ops).
Toulouse (20) : Hervé + Victor. Marrakech (10 suites) : Soukaina. Essaouira (17) : Marika.`,
    tasks: [],
  },
  {
    id: 'sami', name: 'Sami', role: 'Finance · Facturation',
    blurb: 'Factures proprios mensuelles. CA par logement, par ville.',
    hue: 88, status: 'idle', autonomy: 0.71, tokens24h: 0, cost24h: 0, actions24h: 0,
    pos: { x: 0.85, y: 0.55 },
    integrations: ['Notion CRM', 'Lodgify', 'Claude Code', 'Telegram'],
    prompt: `Tu es Sami, l'agent finance de TAKEYS. Tu accèdes aux données Lodgify et CRM propriétaires.
Tu génères les factures proprios le 5 de chaque mois. Tu alertes si écart >5% vs N-1.
Tu peux modifier les scripts de facturation et déployer via execute_code.`,
    tasks: [],
  },
  {
    id: 'ines', name: 'Inès', role: 'Redac · Annonces & Copy',
    blurb: 'Annonces Airbnb/Booking. Ton adapté par ville.',
    hue: 348, status: 'active', autonomy: 0.55, tokens24h: 0, cost24h: 0, actions24h: 0,
    pos: { x: 0.65, y: 0.82 },
    integrations: ['Notion Logements', 'Lodgify', 'Claude Code'],
    prompt: `Tu es Inès, l'agent rédaction de TAKEYS. Tu réécris les annonces Airbnb/Booking.
Ton par ville : pro (Toulouse), premium (Marrakech), slow (Essaouira). Closing poétique 3-4 lignes.
Tu peux modifier les annonces sur le site et déployer via execute_code.`,
    tasks: [],
  },
  {
    id: 'theo', name: 'Théo', role: 'SEO · Blog & Référencement',
    blurb: 'Articles takeys.fr/journal. Mots-clés, trafic.',
    hue: 268, status: 'cron', autonomy: 0.68, tokens24h: 0, cost24h: 0, actions24h: 0,
    pos: { x: 0.35, y: 0.82 },
    integrations: ['Notion Calendar', 'Notion Prospects', 'Claude Code'],
    prompt: `Tu es Théo, l'agent SEO de TAKEYS. 2 articles/semaine sur takeys.fr/journal.
Tu peux planifier des articles, ajouter des prospects, et publier sur le site via execute_code.
Bible TAKEYS = lead magnet freemium.`,
    tasks: [],
  },
  {
    id: 'yasmine', name: 'Yasmine', role: 'Concierge · Voyageurs',
    blurb: 'Messages Lodgify. 3 voix par ville. Temps réponse <8min.',
    hue: 14, status: 'pending', autonomy: 0.42, tokens24h: 0, cost24h: 0, actions24h: 0,
    pos: { x: 0.15, y: 0.55 },
    integrations: ['Lodgify Messages', 'Notion Dar Ayla', 'Telegram', 'Claude Code'],
    prompt: `Tu es Yasmine, l'agent concierge voyageur de TAKEYS. Tu LIS les messages ET tu RÉPONDS directement via Lodgify.
Tu n'inventes RIEN : si l'info manque, escalade à Mira. Tu peux créer des demandes Dar Ayla.
3 tons : pro (Toulouse), chaleureuse (Marrakech), slow (Essaouira). Réponse <8min.`,
    tasks: [],
  },
];

// --- Store réactif ---
// On utilise un pattern pub/sub pour que React re-render quand les données changent

const BrainStore = (() => {
  let _agents = JSON.parse(JSON.stringify(AGENTS_INIT));
  let _feed = [];
  let _comms = [];
  let _decisions = [];
  let _chats = {};
  let _lastRefresh = null;
  const _listeners = [];

  function subscribe(fn) { _listeners.push(fn); return () => { const i = _listeners.indexOf(fn); if (i >= 0) _listeners.splice(i, 1); }; }
  function notify() { _listeners.forEach(fn => fn()); }

  function getAgents() { return _agents; }
  function getFeed() { return _feed; }
  function getComms() { return _comms; }
  function getDecisions() { return _decisions; }
  function getChats() { return _chats; }
  function getLastRefresh() { return _lastRefresh; }

  function updateAgent(id, updates) {
    const a = _agents.find(x => x.id === id);
    if (a) Object.assign(a, updates);
    notify();
  }

  function setFeed(items) { _feed = items; notify(); }
  function setComms(items) { _comms = items; notify(); }
  function setDecisions(items) { _decisions = items; notify(); }
  function setChats(agentId, messages) { _chats = { ..._chats, [agentId]: messages }; notify(); }
  function addChat(agentId, msg) { _chats = { ..._chats, [agentId]: [...(_chats[agentId] || []), msg] }; notify(); }
  function setLastRefresh(t) { _lastRefresh = t; notify(); }

  return { subscribe, getAgents, getFeed, getComms, getDecisions, getChats, getLastRefresh, updateAgent, setFeed, setComms, setDecisions, setChats, addChat, setLastRefresh };
})();

// Compat avec les anciens composants qui lisent les globals
window.AGENTS = BrainStore.getAgents();
window.COMMS = [];
window.FEED = [];
window.CHATS = {};
window.DECISIONS = [];
window.BrainStore = BrainStore;

// --- Hydratation live ---

function hydrateFromAPI() {
  if (!window.BrainAPI) return;
  const API = window.BrainAPI;

  API.on('feed', (data) => {
    if (!data?.feed?.length) return;
    const items = data.feed.map((f, i) => ({ id: f.id || i + 1, at: f.at, agent: f.agent, kind: f.kind, text: f.text }));
    BrainStore.setFeed(items);
    window.FEED = items;
    // Reconstruit COMMS
    const commMap = {};
    for (const f of data.feed.slice(0, 15)) {
      if (f.agent === 'brain') continue;
      const key = `${f.agent}-brain`;
      if (!commMap[key]) {
        commMap[key] = { from: f.agent, to: 'brain', type: f.kind === 'alert' ? 'alert' : f.kind === 'request' ? 'request' : 'data', label: f.text.slice(0, 50), strength: f.kind === 'alert' ? 0.9 : f.kind === 'request' ? 0.7 : 0.5 };
      }
    }
    const comms = Object.values(commMap);
    BrainStore.setComms(comms);
    window.COMMS = comms;
  });

  API.on('bookings', (data) => {
    if (!data?.bookings) return;
    BrainStore.updateAgent('mira', {
      actions24h: data.count,
      tasks: data.bookings.slice(0, 5).map(b => ({ t: `${b.guest} — ${b.property} (${b.city.toUpperCase()})`, state: b.status === 'Confirmed' ? 'doing' : b.status === 'CheckedIn' ? 'done' : 'pending', at: b.arrival ? new Date(b.arrival).toLocaleTimeString('fr-FR', { hour: '2-digit', minute: '2-digit' }) : '—' })),
    });
  });

  API.on('messages', (data) => {
    if (!data?.messages) return;
    const unread = data.messages.filter(m => m.isUnread).length;
    BrainStore.updateAgent('yasmine', {
      actions24h: data.count, status: unread > 0 ? 'active' : 'idle',
      tasks: data.messages.slice(0, 5).map(m => ({ t: `${m.guest} (${m.city.toUpperCase()}) — ${m.lastMessage.slice(0, 40)}`, state: m.isUnread ? 'doing' : 'done', at: m.lastAt ? new Date(m.lastAt).toLocaleTimeString('fr-FR', { hour: '2-digit', minute: '2-digit' }) : '—' })),
    });
    if (data.messages.length) {
      BrainStore.setChats('yasmine', data.messages.slice(0, 3).map(m => ({ who: 'agent', text: `${m.isUnread ? '[NON LU] ' : ''}${m.guest} (${m.city.toUpperCase()}, ${m.property}) :\n${m.lastMessage.slice(0, 200)}` })));
    }
  });

  API.on('workflows', (data) => {
    if (!data?.workflows) return;
    const errors = data.workflows.filter(w => w.lastStatus === 'error').length;
    BrainStore.updateAgent('brain', {
      actions24h: data.count,
      tasks: data.workflows.slice(0, 5).map(w => ({ t: w.name, state: w.lastStatus === 'error' ? 'blocked' : w.active ? 'done' : 'pending', at: w.lastRun ? new Date(w.lastRun).toLocaleTimeString('fr-FR', { hour: '2-digit', minute: '2-digit' }) : '—' })),
    });
    if (errors > 0) {
      BrainStore.setChats('brain', [{ who: 'agent', text: `${data.count} workflows actifs. ${errors} en erreur. Prêt à intervenir.` }]);
    } else {
      BrainStore.setChats('brain', [{ who: 'agent', text: `${data.count} workflows actifs. Tout tourne. Prêt.` }]);
    }
  });

  API.on('tasks', (data) => {
    if (!data?.tasks) return;
    // Dispatch aux agents selon le type
    for (const agent of BrainStore.getAgents()) {
      const match = data.tasks.filter(t => (t.assignee || '').toLowerCase().includes(agent.name.toLowerCase()) || (t.title || '').toLowerCase().includes(agent.role.split(' · ')[0].toLowerCase()));
      if (match.length) {
        BrainStore.updateAgent(agent.id, { tasks: match.slice(0, 5).map(t => ({ t: t.title || '?', state: mapStatus(t.status), at: t.dueDate || '—' })) });
      }
    }
  });

  API.on('decisions', (data) => {
    const items = (data?.decisions || []).map(d => ({ agent: d.agent, text: d.text, url: d.url, id: d.id }));
    BrainStore.setDecisions(items);
    window.DECISIONS = items;
  });

  API.on('jobs', (data) => {
    if (!data?.jobs?.length) return;
    const tokenEstimate = data.count * 5000;
    BrainStore.updateAgent('brain', { tokens24h: tokenEstimate, cost24h: parseFloat((tokenEstimate / 1_000_000 * 3).toFixed(2)) });
  });

  API.on('health', (data) => {
    // Store bridge status globally for topbar
    window._bridgeStatus = data?.bridge || 'unknown';
  });

  API.on('notifications', (data) => {
    window._notifications = data?.notifications || [];
    window._unreadCount = data?.unread || 0;
  });

  API.on('refreshed', (data) => {
    BrainStore.setLastRefresh(data.at);
    // Sync les globals pour les composants legacy
    window.AGENTS = BrainStore.getAgents();
  });

  API.startPolling();
}

function mapStatus(s) {
  const st = (s || '').toLowerCase();
  if (st.includes('done') || st.includes('terminé')) return 'done';
  if (st.includes('progress') || st.includes('en cours')) return 'doing';
  if (st.includes('review') || st.includes('attente')) return 'review';
  if (st.includes('block')) return 'blocked';
  return 'pending';
}

if (document.readyState === 'loading') {
  document.addEventListener('DOMContentLoaded', hydrateFromAPI);
} else {
  setTimeout(hydrateFromAPI, 100);
}
