'use client';

import { useEffect, useRef, useState } from 'react';

export function useBgAgents({ refresh, runs }) {
  const [bgAgents, setBgAgents] = useState({});
  const refreshRef = useRef(refresh);
  useEffect(() => { refreshRef.current = refresh; }, [refresh]);

  useEffect(() => {
    if (typeof window === 'undefined' || !window.EventSource) return;
    const src = new EventSource('/api/events/stream');

    function applyToolStart(evt) {
      const id = evt.agent_id;
      if (!id) return;
      setBgAgents(prev => {
        const existing = prev[id] || {
          agent_id: id,
          agent_name: evt.agent_name || id,
          status: 'running',
          started_at: Date.now(),
          steps: [],
        };
        return {
          ...prev,
          [id]: {
            ...existing,
            agent_name: evt.agent_name || existing.agent_name,
            status: 'running',
            current_tool: evt.tool,
            current_input_summary: evt.input_summary,
            steps: [
              ...existing.steps,
              { tool: evt.tool, input_summary: evt.input_summary, status: 'running', ts: evt.ts || Date.now() },
            ].slice(-12),
          },
        };
      });
    }

    function applyToolResult(evt) {
      const id = evt.agent_id;
      if (!id) return;
      setBgAgents(prev => {
        const existing = prev[id] || {
          agent_id: id,
          agent_name: evt.agent_name || id,
          status: 'running',
          started_at: Date.now(),
          steps: [],
        };
        const nextSteps = [...existing.steps];
        let matched = false;
        for (let i = nextSteps.length - 1; i >= 0; i--) {
          if (nextSteps[i].tool === evt.tool && nextSteps[i].status === 'running') {
            nextSteps[i] = { ...nextSteps[i], status: evt.isError ? 'error' : 'done' };
            matched = true;
            break;
          }
        }
        if (!matched) {
          nextSteps.push({ tool: evt.tool, status: evt.isError ? 'error' : 'done', ts: Date.now() });
          if (nextSteps.length > 12) nextSteps.shift();
        }
        return {
          ...prev,
          [id]: { ...existing, current_tool: null, steps: nextSteps },
        };
      });
    }

    function applyRunStart(evt) {
      const id = evt.agent_id;
      if (!id) return;
      setBgAgents(prev => ({
        ...prev,
        [id]: {
          agent_id: id,
          agent_name: evt.agent_name || id,
          triggered_by: evt.triggered_by,
          status: 'running',
          started_at: Date.now(),
          steps: prev[id]?.steps?.slice(-6) ?? [],
        },
      }));
    }

    function applyRunComplete(evt) {
      const id = evt.agent_id;
      if (!id) return;
      const finishedAt = Date.now();
      setBgAgents(prev => {
        const existing = prev[id];
        if (!existing) return prev;
        return {
          ...prev,
          [id]: {
            ...existing,
            status: evt.isError ? 'failed' : 'complete',
            finished_at: finishedAt,
            current_tool: null,
          },
        };
      });
      setTimeout(() => {
        setBgAgents(prev => {
          const entry = prev[id];
          if (!entry) return prev;
          if (entry.status === 'running') return prev;
          if (entry.finished_at !== finishedAt) return prev;
          const next = { ...prev };
          delete next[id];
          return next;
        });
      }, 30000);
    }

    src.addEventListener('agent_tool_start', e => {
      try { applyToolStart(JSON.parse(e.data)); } catch { /* ignore */ }
    });
    src.addEventListener('agent_tool_result', e => {
      try { applyToolResult(JSON.parse(e.data)); } catch { /* ignore */ }
    });
    src.addEventListener('agent_run_start', e => {
      try { applyRunStart(JSON.parse(e.data)); } catch { /* ignore */ }
    });
    src.addEventListener('agent_run_complete', e => {
      try {
        applyRunComplete(JSON.parse(e.data));
        refreshRef.current?.();
      } catch { /* ignore */ }
    });
    src.addEventListener('agent_created', () => {
      refreshRef.current?.();
    });
    src.onerror = () => { /* let browser auto-reconnect */ };

    return () => {
      src.close();
    };
  }, []);

  useEffect(() => {
    if (!Array.isArray(runs) || runs.length === 0) return;
    setBgAgents(prev => {
      const ids = Object.keys(prev);
      if (ids.length === 0) return prev;
      let changed = false;
      const next = { ...prev };
      for (const id of ids) {
        const entry = prev[id];
        if (!entry || entry.status !== 'running') continue;
        const matchingFinish = runs.find(r =>
          r && r.agent_id === id
          && (r.status === 'complete' || r.status === 'failed')
          && r.at && new Date(r.at).getTime() >= (entry.started_at || 0) - 1000,
        );
        if (matchingFinish) {
          next[id] = {
            ...entry,
            status: matchingFinish.status,
            finished_at: Date.now(),
            current_tool: null,
          };
          changed = true;
          const finishedAt = next[id].finished_at;
          setTimeout(() => {
            setBgAgents(p => {
              const e = p[id];
              if (!e || e.status === 'running' || e.finished_at !== finishedAt) return p;
              const out = { ...p };
              delete out[id];
              return out;
            });
          }, 30000);
        }
      }
      return changed ? next : prev;
    });
  }, [runs]);

  useEffect(() => {
    const ORPHAN_TTL_MS = 2 * 60 * 1000;
    const SWEEP_INTERVAL_MS = 15 * 1000;
    const timer = window.setInterval(() => {
      const cutoff = Date.now() - ORPHAN_TTL_MS;
      setBgAgents(prev => {
        const ids = Object.keys(prev);
        if (ids.length === 0) return prev;
        let changed = false;
        const next = { ...prev };
        for (const id of ids) {
          const entry = prev[id];
          if (!entry || entry.status !== 'running') continue;
          const lastStepTs = entry.steps?.length ? entry.steps[entry.steps.length - 1].ts : 0;
          const lastActivity = Math.max(entry.started_at || 0, lastStepTs || 0);
          if (lastActivity > 0 && lastActivity < cutoff) {
            delete next[id];
            changed = true;
          }
        }
        return changed ? next : prev;
      });
    }, SWEEP_INTERVAL_MS);
    return () => window.clearInterval(timer);
  }, []);

  const bgAgentList = Object.values(bgAgents);
  const hasBgActivity = bgAgentList.some(a => a.status === 'running');

  return { bgAgents, bgAgentList, hasBgActivity };
}
