/**
 * Codex Plan Tracker
 *
 * Encapsulates plan delta accumulation and turn plan update tracking.
 * Extracted from codex-adapter.ts to isolate plan/todo state management.
 */

import { extractPlanTodos } from "./codex-plan-parser.js";

// ─── Plan Tracker ─────────────────────────────────────────────────────────────

export class CodexPlanTracker {
  /** Accumulated plan markdown deltas keyed by turn ID. */
  private planDeltaByTurnId = new Map<string, string>();
  /** Count of plan updates per turn (used to generate unique tool_use IDs). */
  private planUpdateCountByTurnId = new Map<string, number>();

  /** Accumulate a plan delta for a given turn. */
  handlePlanDelta(params: Record<string, unknown>): void {
    const turnId = typeof params.turnId === "string" ? params.turnId : null;
    const delta = typeof params.delta === "string" ? params.delta : null;
    if (!turnId || !delta) return;
    const current = this.planDeltaByTurnId.get(turnId) || "";
    this.planDeltaByTurnId.set(turnId, current + delta);
  }

  /**
   * Process a turn/plan/updated notification and emit a TodoWrite tool_use
   * if todos are found.
   *
   * @returns The tool_use ID and todos array, or null if no todos were extracted.
   */
  handleTurnPlanUpdated(
    params: Record<string, unknown>,
    currentTurnId: string | null,
  ): { toolUseId: string; todos: Array<{ content: string; status: string; activeForm?: string }> } | null {
    const turnObj = params.turn as Record<string, unknown> | undefined;
    const turnId = typeof params.turnId === "string"
      ? params.turnId
      : (typeof turnObj?.id === "string" ? turnObj.id : currentTurnId);
    if (!turnId) return null;

    const todos = extractPlanTodos(params, turnId, this.planDeltaByTurnId);
    if (todos.length === 0) return null;

    const nextCount = (this.planUpdateCountByTurnId.get(turnId) || 0) + 1;
    this.planUpdateCountByTurnId.set(turnId, nextCount);
    const toolUseId = `codex-plan-${turnId}-${nextCount}`;

    return { toolUseId, todos };
  }

  /** Clean up per-turn plan tracking state when a turn finishes. */
  clearTurn(turnId: string): void {
    this.planDeltaByTurnId.delete(turnId);
    this.planUpdateCountByTurnId.delete(turnId);
  }
}
