import assert from "node:assert/strict";
import test from "node:test";

import {
  applyProgressAction,
  enforceMonotonicProgress,
  progressActionsFromToolCalls,
} from "../web/static/js/progress.js";

test("update_step without title preserves title from the existing plan", () => {
  const initial = applyProgressAction([], {
    action: "set_plan",
    steps: [
      { id: "s1", title: "理解需求", status: "in_progress" },
      { id: "s2", title: "实现功能", status: "pending" },
    ],
  });

  const updated = applyProgressAction(initial, {
    action: "update_step",
    step: { id: "s1", status: "completed" },
  });

  assert.deepEqual(updated, [
    { id: "s1", title: "理解需求", status: "completed" },
    { id: "s2", title: "实现功能", status: "pending" },
  ]);
});

test("tool calls can apply progress updates on top of previous task progress", () => {
  const previous = [
    { id: "s1", title: "理解需求", status: "in_progress" },
    { id: "s2", title: "实现功能", status: "pending" },
  ];
  const toolCalls = [{
    function: {
      name: "task_progress",
      arguments: JSON.stringify({
        action: "update_step",
        step: { id: "s1", status: "completed" },
      }),
    },
  }];

  const result = progressActionsFromToolCalls(toolCalls, previous);

  assert.equal(result.sawProgress, true);
  assert.deepEqual(result.steps, [
    { id: "s1", title: "理解需求", status: "completed" },
    { id: "s2", title: "实现功能", status: "pending" },
  ]);
});

test("a completed step force-completes earlier dangling steps (monotonic heal)", () => {
  const steps = [
    { id: "s1", title: "摄取素材", status: "in_progress" },
    { id: "s2", title: "策略", status: "completed" },
    { id: "s3", title: "配图", status: "pending" },
  ];
  assert.deepEqual(enforceMonotonicProgress(steps), [
    { id: "s1", title: "摄取素材", status: "completed" },
    { id: "s2", title: "策略", status: "completed" },
    { id: "s3", title: "配图", status: "pending" },
  ]);
});

test("update_step marking a later step completed heals the earlier in_progress step", () => {
  const initial = applyProgressAction([], {
    action: "set_plan",
    steps: [
      { id: "s1", title: "摄取素材", status: "in_progress" },
      { id: "s2", title: "策略", status: "pending" },
      { id: "s3", title: "配图", status: "pending" },
    ],
  });

  const updated = applyProgressAction(initial, {
    action: "update_step",
    step: { id: "s2", status: "completed" },
  });

  assert.deepEqual(updated, [
    { id: "s1", title: "摄取素材", status: "completed" },
    { id: "s2", title: "策略", status: "completed" },
    { id: "s3", title: "配图", status: "pending" },
  ]);
});

// Replay the exact d1285247 task_progress sequence that produced the reported
// "green check below, red dot above" bug; the heal must yield a clean 6/6.
test("replays the d1285247 skip-ahead sequence to a fully completed plan", () => {
  const call = (args) => ({
    function: { name: "task_progress", arguments: JSON.stringify(args) },
  });
  const seq = [
    call({
      action: "set_plan",
      steps: [
        { id: "s1", title: "摄取素材", status: "in_progress" },
        { id: "s2", title: "策略", status: "pending" },
        { id: "s3", title: "配图", status: "pending" },
        { id: "s4", title: "执行", status: "pending" },
        { id: "s5", title: "质检", status: "pending" },
        { id: "s6", title: "导出", status: "pending" },
      ],
    }),
    call({ action: "update_step", step: { id: "s2", status: "completed" } }),
    call({ action: "update_step", step: { id: "s3", status: "in_progress" } }),
    call({ action: "update_step", step: { id: "s4", status: "completed" } }),
    call({ action: "update_step", step: { id: "s5", status: "in_progress" } }),
    call({ action: "update_step", step: { id: "s5", status: "completed" } }),
    call({ action: "update_step", step: { id: "s6", status: "completed" } }),
  ];

  const { steps } = progressActionsFromToolCalls(seq, []);
  assert.deepEqual(steps.map(s => s.status), [
    "completed", "completed", "completed", "completed", "completed", "completed",
  ]);
});
