import { writable, derived } from "svelte/store";
import type { AgentInfo } from "$lib/types/agents";

// Map of conversation ID -> agents in that conversation
const agentsByConversation = writable<Record<string, AgentInfo[]>>({});

function createAgentStore() {
  return {
    subscribe: agentsByConversation.subscribe,

    addAgent(conversationId: string, agent: AgentInfo) {
      agentsByConversation.update((state) => {
        const existing = state[conversationId] || [];
        return {
          ...state,
          [conversationId]: [...existing, agent],
        };
      });
    },

    updateAgentId(conversationId: string, toolUseId: string, agentId: string) {
      agentsByConversation.update((state) => {
        const agents = state[conversationId];
        if (!agents) return state;

        const agentIndex = agents.findIndex((a) => a.toolUseId === toolUseId);
        if (agentIndex === -1) return state;

        const updated = [...agents];
        updated[agentIndex] = {
          ...updated[agentIndex],
          agentId,
        };

        return {
          ...state,
          [conversationId]: updated,
        };
      });
    },

    endAgent(conversationId: string, toolUseId: string, endedAt: number, isError: boolean) {
      agentsByConversation.update((state) => {
        const agents = state[conversationId];
        if (!agents) return state;

        const agentIndex = agents.findIndex((a) => a.toolUseId === toolUseId);
        if (agentIndex === -1) return state;

        const updated = [...agents];
        const agent = updated[agentIndex];
        const durationMs = endedAt - agent.startedAt;

        updated[agentIndex] = {
          ...agent,
          endedAt,
          status: isError ? "errored" : "completed",
          durationMs,
        };

        return {
          ...state,
          [conversationId]: updated,
        };
      });
    },

    markAllErrored(conversationId: string) {
      agentsByConversation.update((state) => {
        const agents = state[conversationId];
        if (!agents) return state;

        const now = Date.now();
        const updated = agents.map((agent) =>
          agent.status === "running"
            ? { ...agent, endedAt: now, status: "errored" as const }
            : agent
        );

        return {
          ...state,
          [conversationId]: updated,
        };
      });
    },

    clearCompleted(conversationId: string) {
      agentsByConversation.update((state) => {
        const agents = state[conversationId];
        if (!agents) return state;

        return {
          ...state,
          [conversationId]: agents.filter((a) => a.status === "running"),
        };
      });
    },

    clearConversation(conversationId: string) {
      agentsByConversation.update((state) => {
        // eslint-disable-next-line @typescript-eslint/no-unused-vars -- Unused destructured value
        const { [conversationId]: _, ...rest } = state;
        return rest;
      });
    },
  };
}

export const agentStore = createAgentStore();

export function getAgentsForConversation(conversationId: string) {
  return derived(agentsByConversation, ($state) => $state[conversationId] || []);
}

export const runningAgentCount = derived(agentsByConversation, ($state) => {
  let count = 0;
  for (const agents of Object.values($state)) {
    count += agents.filter((a) => a.status === "running").length;
  }
  return count;
});
