/* ============================================================================
 * FLUXO ZAP · React Hooks
 * ----------------------------------------------------------------------------
 * Hooks de dados que abstraem fetch + cache + realtime. As telas consomem
 * estes hooks ao invés de fetchar direto.
 *
 *   const { data, loading, error, refetch } = useLeads({ stage: 'novo' });
 *   const { data } = useLead(123);
 *   useRealtime('message.received', (msg) => { ... });
 *
 * Cache em memória — pra produção considere SWR ou React Query.
 * ========================================================================= */

const _cache = new Map();
const _subscribers = new Map();

const cacheKey = (path, params) => path + JSON.stringify(params || {});

const setCacheAndNotify = (key, data) => {
  _cache.set(key, { data, ts: Date.now() });
  const subs = _subscribers.get(key);
  if (subs) subs.forEach(cb => cb(data));
};

const subscribe = (key, cb) => {
  if (!_subscribers.has(key)) _subscribers.set(key, new Set());
  _subscribers.get(key).add(cb);
  return () => _subscribers.get(key).delete(cb);
};

/** Hook genérico de query com cache + dedup */
const useQuery = (key, fetcher, deps = []) => {
  const [state, setState] = React.useState(() => {
    const cached = _cache.get(key);
    return cached
      ? { data: cached.data, loading: false, error: null }
      : { data: null, loading: true, error: null };
  });

  const run = React.useCallback(async () => {
    setState(s => ({ ...s, loading: true, error: null }));
    try {
      const data = await fetcher();
      setCacheAndNotify(key, data);
      setState({ data, loading: false, error: null });
    } catch (error) {
      setState({ data: null, loading: false, error });
    }
  }, deps);

  React.useEffect(() => {
    const cached = _cache.get(key);
    const stale = !cached || (Date.now() - cached.ts) > window.FluxoConfig.STALE_TIME_MS;
    if (stale) run();
    const unsub = subscribe(key, (data) => setState(s => ({ ...s, data })));
    return unsub;
  }, [key]);

  return { ...state, refetch: run };
};

// ── DASHBOARD ──────────────────────────────────────────────────────────────
const useDashboardKpis = (range = '7d') =>
  useQuery(cacheKey('dashboard.kpis', { range }), () => FluxoEndpoints.dashboard.kpis(range), [range]);

const useDashboardFunnel = (range = '7d') =>
  useQuery(cacheKey('dashboard.funnel', { range }), () => FluxoEndpoints.dashboard.funnel(range), [range]);

const useDashboardHeatmap = (range = '30d') =>
  useQuery(cacheKey('dashboard.heatmap', { range }), () => FluxoEndpoints.dashboard.heatmap(range), [range]);

const useAiLive = () =>
  useQuery(cacheKey('ai.live'), () => FluxoEndpoints.dashboard.aiLive());

// ── LEADS ──────────────────────────────────────────────────────────────────
const useLeads = (filters = {}) =>
  useQuery(cacheKey('leads', filters), () => FluxoEndpoints.leads.list(filters), [JSON.stringify(filters)]);

const useLead = (id) =>
  useQuery(cacheKey('lead', { id }), () => FluxoEndpoints.leads.get(id), [id]);

const useLeadTimeline = (id) =>
  useQuery(cacheKey('lead.timeline', { id }), () => FluxoEndpoints.leads.timeline(id), [id]);

const useLeadInsights = (id) =>
  useQuery(cacheKey('lead.insights', { id }), () => FluxoEndpoints.leads.aiInsights(id), [id]);

// Mutations
const useUpdateLead = () => {
  const [pending, setPending] = React.useState(false);
  const run = React.useCallback(async (id, patch) => {
    setPending(true);
    try {
      const updated = await FluxoEndpoints.leads.update(id, patch);
      // Invalida caches relacionados
      setCacheAndNotify(cacheKey('lead', { id }), updated);
      _cache.delete(cacheKey('leads', {}));
      return updated;
    } finally { setPending(false); }
  }, []);
  return [run, { pending }];
};

const useMoveLeadStage = () => {
  return React.useCallback(async (id, stage) => {
    // 1. Atualização Otimista: atualiza a lista geral de leads na hora
    const listKey = cacheKey('leads', {});
    const cachedList = _cache.get(listKey);
    if (cachedList && cachedList.data) {
      const isObject = !Array.isArray(cachedList.data);
      const arr = isObject ? cachedList.data.data : cachedList.data;
      if (Array.isArray(arr)) {
        const newArr = arr.map(l => String(l.id) === String(id) ? { ...l, stage } : l);
        const newData = isObject ? { ...cachedList.data, data: newArr } : newArr;
        setCacheAndNotify(listKey, newData);
      }
    }

    // 2. Chamada real na API
    const updated = await FluxoEndpoints.leads.moveStage(id, stage);
    setCacheAndNotify(cacheKey('lead', { id }), updated);
    return updated;
  }, []);
};

// ── NOTAS INTERNAS ──────────────────────────────────────────────────────────
const useNotes = (leadId) => {
  return useQuery(cacheKey('notes', { leadId }), () => FluxoEndpoints.leads.listNotes(leadId), [leadId]);
};

const useAddNote = () => {
  return React.useCallback(async (leadId, body) => {
    const newNote = await FluxoEndpoints.leads.addNote(leadId, body);
    const key = cacheKey('notes', { leadId });
    const cur = _cache.get(key)?.data || [];
    setCacheAndNotify(key, [...cur, newNote]);
    return newNote;
  }, []);
};

// ── AGENDAMENTOS (APPOINTMENTS) ─────────────────────────────────────────
const useAppointments = () => {
  const q = useQuery(cacheKey('appointments'), () => FluxoEndpoints.appointments.list());
  return q;
};

const useCreateAppointment = () => {
  return React.useCallback(async (data) => {
    const created = await FluxoEndpoints.appointments.create(data);
    _cache.delete(cacheKey('appointments'));
    return created;
  }, []);
};

const useDeleteAppointment = () => {
  return React.useCallback(async (id) => {
    await FluxoEndpoints.appointments.delete(id);
    _cache.delete(cacheKey('appointments'));
    return true;
  }, []);
};

// ── EQUIPE (TEAM) ─────────────────────────────────────────────────────────
const useTeam = () => {
  return useQuery(cacheKey('team'), () => FluxoEndpoints.team.list());
};

const useInviteTeamMember = () => {
  return React.useCallback(async (data) => {
    const created = await FluxoEndpoints.team.invite(data);
    _cache.delete(cacheKey('team'));
    return created;
  }, []);
};

const useRemoveTeamMember = () => {
  return React.useCallback(async (id) => {
    await FluxoEndpoints.team.remove(id);
    _cache.delete(cacheKey('team'));
    return true;
  }, []);
};

// ── CONVERSAS ──────────────────────────────────────────────────────────────
const useConversations = (filters = {}) =>
  useQuery(cacheKey('conversations', filters), () => FluxoEndpoints.conversations.list(filters), [JSON.stringify(filters)]);

const useConversation = (leadId) => {
  const q = useQuery(cacheKey('conversation', { leadId }),
    () => FluxoEndpoints.conversations.messages(leadId), [leadId]);

  // Subscreve a eventos de mensagem em tempo real
  React.useEffect(() => {
    if (!leadId) return;
    const unsub = window.FluxoRealtime.on('message.received', (msg) => {
      if (msg.leadId !== leadId) return;
      const key = cacheKey('conversation', { leadId });
      const cur = _cache.get(key)?.data || [];
      setCacheAndNotify(key, [...cur, msg]);
    });
    return unsub;
  }, [leadId]);

  return q;
};

const useSendMessage = () => {
  return React.useCallback(async (leadId, text, opts = {}) => {
    const msg = await FluxoEndpoints.conversations.send(leadId, {
      text,
      type: opts.type || 'text',
      replyToId: opts.replyToId,
      via: opts.via || 'human', // 'human' | 'ai'
    });
    const key = cacheKey('conversation', { leadId });
    const cur = _cache.get(key)?.data || [];
    setCacheAndNotify(key, [...cur, msg]);
    return msg;
  }, []);
};

const useAiSuggest = () => {
  const [state, setState] = React.useState({ suggestion: null, loading: false, error: null });
  const ask = React.useCallback(async (leadId, context) => {
    setState({ suggestion: null, loading: true, error: null });
    try {
      const suggestion = await FluxoEndpoints.ai.suggest(leadId, context);
      setState({ suggestion, loading: false, error: null });
      return suggestion;
    } catch (error) {
      setState({ suggestion: null, loading: false, error });
    }
  }, []);
  return { ...state, ask };
};

// ── RESPOSTAS RÁPIDAS ───────────────────────────────────────────────────
const useQuickReplies = () =>
  useQuery(cacheKey('quickReplies'), () => FluxoEndpoints.quickReplies.list());

const useUploadQuickReply = () => {
  return React.useCallback(async (id, file) => {
    const updated = await FluxoEndpoints.quickReplies.upload(id, file);
    _cache.delete(cacheKey('quickReplies'));
    return updated;
  }, []);
};

// ── IA / KIKO ───────────────────────────────────────────────────────────────
const useAiConfig = () =>
  useQuery(cacheKey('ai.config'), () => FluxoEndpoints.ai.config());

const useUpdateAiConfig = () => {
  return React.useCallback(async (patch) => {
    const updated = await FluxoEndpoints.ai.updateConfig(patch);
    setCacheAndNotify(cacheKey('ai.config'), updated);
    return updated;
  }, []);
};

const useAiTriggers = () =>
  useQuery(cacheKey('ai.triggers'), () => FluxoEndpoints.ai.listTriggers());

const useSaveAiTrigger = () => {
  return React.useCallback(async (trigger) => {
    // If it has no ID or is a new trigger, we can just use addTrigger or saveTrigger
    // But since the backend only has POST /triggers for insert, we use addTrigger
    const saved = await FluxoEndpoints.ai.addTrigger(trigger);
    _cache.delete(cacheKey('ai.triggers'));
    return saved;
  }, []);
};

const useDeleteAiTrigger = () => {
  return React.useCallback(async (id) => {
    await FluxoEndpoints.ai.deleteTrigger(id);
    _cache.delete(cacheKey('ai.triggers'));
    return true;
  }, []);
};

// ── WHATSAPP ───────────────────────────────────────────────────────────────
const useWhatsappStatus = () => {
  const q = useQuery(cacheKey('whatsapp.status'), () => window.FluxoApi.get('/api/whatsapp/status'));
  React.useEffect(() => {
    const unsub = window.FluxoRealtime.on('whatsapp.status', (status) => {
      setCacheAndNotify(cacheKey('whatsapp.status'), status);
    });
    
    const interval = setInterval(() => {
      q.refetch();
    }, 2500);

    return () => {
      unsub();
      clearInterval(interval);
    };
  }, [q.refetch]);
  return q;
};
// ── RADAR ──────────────────────────────────────────────────────────────────
const useRadarProspects = (filters = {}) =>
  useQuery(cacheKey('radar.prospects', filters), () => FluxoEndpoints.radar.prospects(filters), [JSON.stringify(filters)]);

const useRadarStats = () =>
  useQuery(cacheKey('radar.stats'), () => FluxoEndpoints.radar.stats());

const useRadarCriteria = () =>
  useQuery(cacheKey('radar.criteria'), () => FluxoEndpoints.radar.criteria());

// ── KNOWLEDGE ──────────────────────────────────────────────────────────────
const useKnowledgeSources = () =>
  useQuery(cacheKey('knowledge.sources'), () => FluxoEndpoints.knowledge.sources());

const useKnowledgeGaps = () =>
  useQuery(cacheKey('knowledge.gaps'), () => FluxoEndpoints.knowledge.gaps());

const useKnowledgeCoverage = () =>
  useQuery(cacheKey('knowledge.coverage'), () => FluxoEndpoints.knowledge.coverage());

// ── PIPELINE ───────────────────────────────────────────────────────────────
const usePipelineStages = () =>
  useQuery(cacheKey('pipeline.stages'), () => FluxoEndpoints.pipeline.stages());

// ── INTEGRATIONS ───────────────────────────────────────────────────────────
const useIntegrations = () =>
  useQuery(cacheKey('integrations'), () => FluxoEndpoints.integrations.list());

const useConnectIntegration = () => {
  return React.useCallback(async (provider, apiKey) => {
    const updated = await FluxoEndpoints.integrations.connect(provider, { apiKey });
    _cache.delete(cacheKey('integrations'));
    return updated;
  }, []);
};

const useDisconnectIntegration = () => {
  return React.useCallback(async (provider) => {
    const updated = await FluxoEndpoints.integrations.disconnect(provider);
    _cache.delete(cacheKey('integrations'));
    return updated;
  }, []);
};

// ── API KEYS ───────────────────────────────────────────────────────────────
const useApiKeys = () =>
  useQuery(cacheKey('apiKeys'), () => FluxoEndpoints.apiKeys.list());

const useCreateApiKey = () => {
  return React.useCallback(async (name) => {
    const key = await FluxoEndpoints.apiKeys.create(name);
    _cache.delete(cacheKey('apiKeys'));
    return key;
  }, []);
};

const useRevokeApiKey = () => {
  return React.useCallback(async (id) => {
    await FluxoEndpoints.apiKeys.revoke(id);
    _cache.delete(cacheKey('apiKeys'));
    return true;
  }, []);
};

// ── REALTIME ───────────────────────────────────────────────────────────────
/** Inscreve em eventos do WebSocket. Auto-unsubscribe no unmount. */
const useRealtime = (eventType, handler) => {
  React.useEffect(() => {
    return window.FluxoRealtime.on(eventType, handler);
  }, [eventType, handler]);
};

const useNotifications = () => 
  useQuery(cacheKey('notifications'), () => fetch('/api/settings/notifications').then(res => res.json()));

const useUpdateNotifications = () => {
  const [pending, setPending] = React.useState(false);
  const run = React.useCallback(async (patch) => {
    setPending(true);
    try {
      const updated = await fetch('/api/settings/notifications', {
        method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(patch)
      }).then(res => res.json());
      setCacheAndNotify(cacheKey('notifications'), updated);
      return updated;
    } finally { setPending(false); }
  }, []);
  return { run, pending };
};

// Expor tudo no window
Object.assign(window, {
  useQuery,
  useDashboardKpis, useDashboardFunnel, useDashboardHeatmap, useAiLive,
  useLeads, useLead, useUpdateLead, useLeadTimeline, useLeadInsights, useLeadNotes, useAddLeadNote,
  useConversations, useConversation, useSendMessage, useConversationActions, useMoveStage,
  useAiConfig, useUpdateAiConfig, useAiTriggers, useSaveAiTrigger, useDeleteAiTrigger,
  useRadarProspects, useRadarStats, useRadarCriteria,
  useKnowledgeSources, useKnowledgeGaps, useKnowledgeCoverage,
  usePipelineStages,
  useIntegrations, useConnectIntegration, useDisconnectIntegration,
  useApiKeys, useCreateApiKey, useRevokeApiKey,
  useQuickReplies, useUploadQuickReply,
  useNotifications, useUpdateNotifications,
  useRealtime: typeof useRealtime !== 'undefined' ? useRealtime : undefined,
  useWhatsappStatus: typeof useWhatsappStatus !== 'undefined' ? useWhatsappStatus : undefined,
  useAiSuggest: typeof useAiSuggest !== 'undefined' ? useAiSuggest : undefined,
  useNotes: typeof useNotes !== 'undefined' ? useNotes : undefined,
  useAddNote: typeof useAddNote !== 'undefined' ? useAddNote : undefined,
  useMoveLeadStage: typeof useMoveLeadStage !== 'undefined' ? useMoveLeadStage : undefined
});
