/**
 * Read-only project work-state panel: one row per agent, showing live/offline
 * and idle/busy state from the backend read-model, plus the current input queue.
 */

import type {
  AgentTicketState,
  AgentWorkState,
  ConversationPreviewStatus,
  ConversationWorkSummary,
} from "@/domain";
import { Button, Panel, Spinner, cn } from "@/shared";
import { useProjectWorkState } from "./useProjectWorkState";

export interface ProjectWorkStatePanelProps {
  projectId: string;
}

function shortTicket(ticket: string): string {
  return ticket.length <= 8 ? ticket : ticket.slice(0, 8);
}

function formatStatus(status: AgentTicketState["status"]): string {
  return status === "inProgress" ? "In progress" : "Queued";
}

function requesterLabel(ticket: AgentTicketState): string {
  if (ticket.source.kind === "human") return "Human";
  const id = shortTicket(ticket.source.agentId);
  return ticket.requesterLabel.trim()
    ? `${ticket.requesterLabel} (${id})`
    : `Agent ${id}`;
}

function summaryLabel(status: ConversationPreviewStatus): string {
  switch (status) {
    case "ready":
      return "Summary";
    case "missing":
      return "No summary";
    case "partial":
      return "Partial";
    case "unavailable":
      return "Unavailable";
  }
}

function summaryText(summary: ConversationWorkSummary): string | null {
  if (summary.objectivePreview) return `Goal: ${summary.objectivePreview}`;
  if (summary.summaryPreview) return summary.summaryPreview;
  const lastTurn = summary.recentTurns.at(-1);
  return lastTurn ? `Last: ${lastTurn.textPreview}` : null;
}

function ConversationSummaryLine({
  summary,
}: {
  summary: ConversationWorkSummary;
}) {
  const text = summaryText(summary);
  if (!text) return null;
  return (
    <div className="mt-1 flex min-w-0 items-start gap-2 pl-1 text-xs text-muted">
      <span
        className={cn(
          "mt-0.5 shrink-0 rounded-full px-1.5 py-0.5 font-medium",
          summary.status === "ready"
            ? "bg-success/10 text-success"
            : "bg-raised text-muted",
        )}
      >
        {summaryLabel(summary.status)}
      </span>
      <span className="min-w-0 break-words">{text}</span>
    </div>
  );
}

function TicketRow({
  ticket,
  summary,
}: {
  ticket: AgentTicketState;
  summary?: ConversationWorkSummary;
}) {
  const truncated = ticket.taskLen > ticket.taskPreview.length;
  return (
    <li className="min-w-0 text-xs text-muted">
      <div className="flex min-w-0 items-start gap-2">
        <span
          className={cn(
            "mt-0.5 shrink-0 rounded-full px-1.5 py-0.5 font-medium",
            ticket.status === "inProgress"
              ? "bg-warning/15 text-warning"
              : "bg-raised text-muted",
          )}
        >
          #{ticket.position + 1} {formatStatus(ticket.status)}
        </span>
        <span className="min-w-0 flex-1">
          <span className="font-medium text-content">{requesterLabel(ticket)}</span>
          <span className="text-muted"> · </span>
          <span className="break-words">{ticket.taskPreview}</span>
          {truncated && (
            <span
              aria-label={`${ticket.taskLen - ticket.taskPreview.length} more characters`}
              className="text-muted"
            >
              {" "}
              +{ticket.taskLen - ticket.taskPreview.length}
            </span>
          )}
        </span>
        <code
          aria-label={`ticket ${shortTicket(ticket.ticketId)}`}
          title={ticket.ticketId}
          className="mt-0.5 shrink-0 rounded bg-raised px-1.5 py-0.5 text-[11px] text-muted"
        >
          {shortTicket(ticket.ticketId)}
        </code>
      </div>
      {summary && <ConversationSummaryLine summary={summary} />}
    </li>
  );
}

function AgentRow({
  agent,
  conversations,
}: {
  agent: AgentWorkState;
  conversations: Map<string, ConversationWorkSummary>;
}) {
  const live = agent.live !== undefined;
  const busy = agent.busy.state === "busy";
  const tickets = [...agent.tickets].sort((a, b) => a.position - b.position);
  return (
    <li className="py-2 first:pt-0 last:pb-0">
      <div className="flex items-center justify-between gap-3">
        <span className="flex min-w-0 flex-col gap-0.5">
          <span className="truncate text-sm font-medium text-content">
            {agent.name}
          </span>
          <code className="truncate text-xs text-muted">{agent.profileId}</code>
        </span>
        <span className="flex shrink-0 items-center gap-1.5">
          <span
            className={cn(
              "rounded-full px-2 py-0.5 text-xs font-medium",
              live
                ? "bg-success/15 text-success"
                : "bg-raised text-muted",
            )}
          >
            {live ? "Live" : "Offline"}
          </span>
          <span
            className={cn(
              "rounded-full px-2 py-0.5 text-xs font-medium",
              busy
                ? "bg-warning/15 text-warning"
                : "bg-raised text-muted",
            )}
          >
            {busy ? "Busy" : "Idle"}
          </span>
          {agent.busy.state === "busy" && (
            <code
              aria-label={`busy ticket ${shortTicket(agent.busy.ticket)}`}
              title={agent.busy.ticket}
              className="rounded bg-raised px-1.5 py-0.5 text-xs text-muted"
            >
              {shortTicket(agent.busy.ticket)}
            </code>
          )}
        </span>
      </div>
      {tickets.length > 0 && (
        <ul
          aria-label={`${agent.name} tickets`}
          className="mt-2 flex flex-col gap-1"
        >
          {tickets.map((ticket) => (
            <TicketRow
              key={ticket.ticketId}
              ticket={ticket}
              summary={conversations.get(ticket.conversationId)}
            />
          ))}
        </ul>
      )}
    </li>
  );
}

export function ProjectWorkStatePanel({ projectId }: ProjectWorkStatePanelProps) {
  const vm = useProjectWorkState(projectId);
  const agents = vm.state?.agents ?? [];
  const conversations = new Map(
    (vm.state?.conversations ?? []).map((summary) => [
      summary.conversationId,
      summary,
    ]),
  );

  return (
    <Panel
      title="Work"
      actions={
        <Button
          size="sm"
          variant="ghost"
          onClick={() => void vm.refresh()}
          loading={vm.busy}
        >
          Refresh
        </Button>
      }
    >
      {vm.error && (
        <p
          role="alert"
          className="mb-3 rounded-md border border-danger/40 bg-danger/10 px-3 py-2 text-sm text-danger"
        >
          {vm.error}
        </p>
      )}
      {vm.busy && vm.state === null ? (
        <div className="flex items-center gap-2 text-sm text-muted">
          <Spinner size={14} />
          <span>Loading work state…</span>
        </div>
      ) : agents.length === 0 ? (
        <p className="text-sm text-muted">No agent work state.</p>
      ) : (
        <ul className="flex flex-col divide-y divide-border">
          {agents.map((agent) => (
            <AgentRow
              key={agent.agentId}
              agent={agent}
              conversations={conversations}
            />
          ))}
        </ul>
      )}
    </Panel>
  );
}
