import { describe, expect, it } from "vitest";
import { unsafeOpaqueId } from "@awp/contracts";
import { renderApprovedLiveProject, type LiveHierarchy } from "../../apps/web/src/approved-live.js";

function emptyHierarchy(): LiveHierarchy {
  const projectId = unsafeOpaqueId("project:authoring");
  return {
    project: {
      id: projectId,
      name: "Authoring",
      repositoryUrl: "https://github.com/platform-modules/awp.git",
      requiredChecks: [],
      status: "active",
    } as never,
    vision: { id: "vision:1", sequence: 1, summary: "Existing canonical vision" },
    goals: [],
    plans: [],
    planRevisions: [],
    tasks: [],
    factoryRuns: [],
    agentRuns: [],
    attempts: [],
    workspaces: [],
    changeSets: [],
    reviews: [],
    verificationEvidence: [],
    reviewFindings: [],
    events: [],
  } as unknown as LiveHierarchy;
}

describe("approved live owner authoring", () => {
  it("keeps Overview information-first while exposing first-use mutation controls on canonical tabs", () => {
    const hierarchy = emptyHierarchy();
    const overview = renderApprovedLiveProject(hierarchy, "overview");
    expect(overview).toContain("New Project");
    expect(overview).not.toContain("Save ProjectVision");
    expect(overview).not.toContain("Create Goal");

    const vision = renderApprovedLiveProject(hierarchy, "vision");
    expect(vision).toContain("Save ProjectVision");
    expect(vision).toContain("Existing canonical vision");
    expect(vision).toContain('action="/internal/projects/project%3Aauthoring/vision"');

    const goals = renderApprovedLiveProject(hierarchy, "goals");
    expect(goals).toContain("Create Goal");
    expect(goals).toContain('name="successCriteria"');

    const plans = renderApprovedLiveProject(hierarchy, "plans");
    expect(plans).toContain("Plan authoring");
    expect(plans).toContain("Create Plan");
    expect(plans).toContain('name="taskTitles"');
    expect(plans).toContain("No draft Plan is waiting to start");
  });
  it("renders durable journey stage history on the canonical Project surface", () => {
    const hierarchy = {
      ...emptyHierarchy(),
      events: [
        {
          id: "event:1",
          type: "TaskDispatched",
          occurredAt: "2026-08-24T09:00:00.000Z",
          aggregateType: "Task",
          aggregateId: "task:1",
          payload: {},
        },
        {
          id: "event:2",
          type: "MergeCompleted",
          occurredAt: "2026-08-24T09:00:05.000Z",
          aggregateType: "ChangeSet",
          aggregateId: "changeset:1",
          payload: {},
        },
      ],
    } satisfies LiveHierarchy;
    const html = renderApprovedLiveProject(hierarchy, "overview");
    expect(html).toContain("data-live-stage-timeline");
    expect(html).toContain('data-live-stage-event="TaskDispatched"');
    expect(html).toContain('data-event-aggregate-id="task:1"');
    expect(html).toContain("Task dispatched");
    expect(html).toContain('data-live-stage-event="MergeCompleted"');
    expect(html).toContain("Merge completed");
  });

  it("projects current I1 owner prerequisites into Needs Your Attention", () => {
    const base = emptyHierarchy();
    const projectId = base.project.id;
    const planId = unsafeOpaqueId("plan:attention");
    const planRevisionId = unsafeOpaqueId("plan-revision:attention");
    const hierarchy = {
      ...base,
      goals: [{ id: unsafeOpaqueId("goal:attention"), title: "Ship", status: "active" }],
      plans: [{ id: planId, title: "Ship I1", status: "draft" }],
      planRevisions: [
        {
          id: planRevisionId,
          planId,
          projectId,
          sequence: 1,
          title: "Ship I1",
          goalIds: [unsafeOpaqueId("goal:attention")],
        },
      ],
    } as unknown as LiveHierarchy;

    const withoutAccount = renderApprovedLiveProject(hierarchy, "overview", []);
    expect(withoutAccount).toContain("Needs Your Attention");
    expect(withoutAccount).toContain("Execution account required");
    expect(withoutAccount).toContain("Add account");
    expect(withoutAccount).not.toContain("Full Attention projection activates");

    const withAccount = renderApprovedLiveProject(hierarchy, "overview", [
      { accountKey: "owner-account", label: "Owner account", status: "available" } as never,
    ]);
    expect(withAccount).toContain("Approve &amp; start Ship I1");
    expect(withAccount).toContain("Review Plan");
  });
});
