/**
 * Paperclip agent ACTIVITY hooks — mirror live agent work into the Legal-AI UI.
 *
 * Frontend platform-presentation module (G12 / docs/spec/X15): the web-ui is a
 * presentation layer, and showing the agent platform's live activity is a
 * legitimate, declared use of platform data. Distinct from
 * `paperclip-agents.ts`, which is the settings/management view of an agent's
 * full config — hence the activity DTO here is `PaperclipAgentStatus`, not the
 * config `PaperclipAgent` (the two are different projections; the name no
 * longer collides).
 */

import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { apiRequest } from "./client";

// ── Types ────────────────────────────────────────────────────────

export type PaperclipIssue = {
  id: string;
  title: string;
  status: string;
  identifier: string;
  priority: string;
  assignee_name: string | null;
  started_at: string | null;
  completed_at: string | null;
  created_at: string | null;
  company_id: string;
  /** Null for top-level issues (the CEO "start process" issue); set for sub-issues. */
  parent_id: string | null;
};

export type PaperclipComment = {
  id: string;
  issue_id: string;
  body: string;
  created_at: string | null;
  author_agent_id: string | null;
  author_user_id: string | null;
  agent_name: string | null;
  agent_role: string | null;
  agent_icon: string | null;
};

export type PaperclipAgentStatus = {
  id: string;
  name: string;
  role: string;
  title: string | null;
  status: string;
  icon: string | null;
  last_heartbeat_at: string | null;
};

export type InteractionKind =
  | "ask_user_questions"
  | "request_confirmation"
  | "suggest_tasks";

export type InteractionStatus =
  | "pending"
  | "answered"
  | "accepted"
  | "rejected"
  | "expired"
  | "failed";

export type InteractionOption = {
  id: string;
  label: string;
  description?: string | null;
};

export type InteractionQuestion = {
  id: string;
  prompt: string;
  selectionMode?: "single" | "multi";
  required?: boolean;
  options: InteractionOption[];
};

export type InteractionTask = {
  clientKey: string;
  parentClientKey?: string | null;
  title: string;
  description?: string | null;
};

/** Free-form payload — shape depends on `kind`. Common fields surfaced for the
 * UI; everything else is preserved on the wire. */
export type InteractionPayload = {
  version?: number;
  submitLabel?: string;
  acceptLabel?: string;
  rejectLabel?: string;
  questions?: InteractionQuestion[];
  tasks?: InteractionTask[];
  body?: string;
  [key: string]: unknown;
};

export type Interaction = {
  id: string;
  issue_id: string;
  kind: InteractionKind;
  status: InteractionStatus;
  title: string | null;
  summary: string | null;
  payload: InteractionPayload;
  result: Record<string, unknown> | null;
  created_at: string | null;
  resolved_at: string | null;
};

export type AgentActivityResponse = {
  issues: PaperclipIssue[];
  comments: PaperclipComment[];
  agents: PaperclipAgentStatus[];
  interactions: Interaction[];
};

export type InteractionAction = "respond" | "accept" | "reject";

export type InteractionSubmitVars = {
  issue_id: string;
  interaction_id: string;
  action: InteractionAction;
  payload: Record<string, unknown>;
};

// ── Query Keys ───────────────────────────────────────────────────

export const agentKeys = {
  activity: (caseNumber: string) =>
    ["agents", "activity", caseNumber] as const,
};

// ── Hooks ────────────────────────────────────────────────────────

export function useAgentActivity(caseNumber: string | undefined) {
  return useQuery({
    queryKey: agentKeys.activity(caseNumber ?? ""),
    queryFn: ({ signal }) =>
      apiRequest<AgentActivityResponse>(
        `/api/cases/${caseNumber}/agents`,
        { signal },
      ),
    enabled: !!caseNumber,
    refetchInterval: 10_000,
  });
}

export function useSendComment(caseNumber: string | undefined) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (vars: { body: string; issue_id?: string; new_run?: boolean }) =>
      apiRequest<{
        comment_id: string | null;
        issue_id: string;
        issue_identifier: string;
        issue_status?: string;
        new_run?: boolean;
      }>(
        `/api/cases/${caseNumber}/agents/comment`,
        { method: "POST", body: vars },
      ),
    onSuccess: () => {
      if (caseNumber) {
        qc.invalidateQueries({ queryKey: agentKeys.activity(caseNumber) });
      }
    },
  });
}

export function useSubmitInteraction(caseNumber: string | undefined) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (vars: InteractionSubmitVars) =>
      apiRequest<Interaction>(
        `/api/cases/${caseNumber}/agents/interaction-response`,
        { method: "POST", body: vars },
      ),
    onSuccess: () => {
      if (caseNumber) {
        qc.invalidateQueries({ queryKey: agentKeys.activity(caseNumber) });
      }
    },
  });
}

/** Dismiss a pending interaction WITHOUT waking the issue assignee — used for
 * stale/duplicate questions. Backend marks it `cancelled` directly (the
 * `wake_assignee` continuation policy means a normal resolve would wake the
 * agent; dismiss must not). */
export function useDismissInteraction(caseNumber: string | undefined) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (vars: { issue_id: string; interaction_id: string }) =>
      apiRequest<{ ok: boolean; cancelled: boolean }>(
        `/api/cases/${caseNumber}/agents/interaction-dismiss`,
        { method: "POST", body: vars },
      ),
    onSuccess: () => {
      if (caseNumber) {
        qc.invalidateQueries({ queryKey: agentKeys.activity(caseNumber) });
      }
    },
  });
}

/** Manually close a board issue to done/cancelled — the chair tidying the agents
 * board (e.g. superseded runs left in in_review). Backend does a loop-safe
 * direct close and issues no wakeup; only the two terminal statuses are allowed. */
export function useSetIssueStatus(caseNumber: string | undefined) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (vars: { issue_id: string; status: "done" | "cancelled" }) =>
      apiRequest<{ ok: boolean; id: string; identifier: string; status: string }>(
        `/api/cases/${caseNumber}/agents/issue-status`,
        { method: "POST", body: vars },
      ),
    onSuccess: () => {
      if (caseNumber) {
        qc.invalidateQueries({ queryKey: agentKeys.activity(caseNumber) });
      }
    },
  });
}

export type AgentResetResult = {
  ok: boolean;
  reassigned_issues: { id: string; identifier: string }[];
  reset_agents: { id: string; name: string; ok: boolean; error?: string }[];
};

export function useResetCaseAgents(caseNumber: string | undefined) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: () =>
      apiRequest<AgentResetResult>(
        `/api/cases/${caseNumber}/agents/reset`,
        { method: "POST" },
      ),
    onSuccess: () => {
      if (caseNumber) {
        qc.invalidateQueries({ queryKey: agentKeys.activity(caseNumber) });
      }
    },
  });
}
