/**
 * Minimal read-only list of a project's agents, used by the ticket surfaces to
 * (a) resolve agent ids to names and (b) offer only *known* agents when
 * assigning (F5). Deliberately lighter than the full `useAgents` view-model —
 * tickets never launch or mutate agents.
 */

import { useEffect, useMemo, useState } from "react";

import type { Agent } from "@/domain";
import { useGateways } from "@/app/di";

export interface ProjectAgents {
  agents: Agent[];
  /** Maps an agent id to a display name, falling back to a short id. */
  nameOf: (agentId: string) => string;
  /**
   * `true` once the agent roster has been fetched for the current project.
   * Callers that reconcile persisted state against known agents (ticket #29)
   * must wait for this so a valid assignee is not dropped during the load window.
   */
  loaded: boolean;
}

export function useProjectAgents(projectId: string): ProjectAgents {
  const { agent } = useGateways();
  const [agents, setAgents] = useState<Agent[]>([]);
  const [loaded, setLoaded] = useState(false);

  useEffect(() => {
    let cancelled = false;
    setLoaded(false);
    void agent
      .listAgents(projectId)
      .then((list) => {
        if (!cancelled) {
          setAgents(list);
          setLoaded(true);
        }
      })
      .catch(() => {
        if (!cancelled) {
          setAgents([]);
          setLoaded(true);
        }
      });
    return () => {
      cancelled = true;
    };
  }, [projectId, agent]);

  const byId = useMemo(
    () => new Map(agents.map((a) => [a.id, a.name])),
    [agents],
  );

  const nameOf = (agentId: string): string =>
    byId.get(agentId) ?? `${agentId.slice(0, 8)}…`;

  return { agents, nameOf, loaded };
}
