// @vitest-environment jsdom

import { fireEvent, render, screen } from '@testing-library/react';
import { expect, test, vi } from 'vitest';

import type {
  CreativeAgentSessionSnapshot,
  CreativeAgentSseEvent,
  CreativeAgentStage,
} from '../../../packages/shared/src/contracts/creativeAgent';
import type { PuzzleCreativeTemplateProtocol } from '../../../packages/shared/src/contracts/puzzleCreativeTemplate';
import { CreativeAgentStageTimeline } from './CreativeAgentStageTimeline';
import { resolveCreativeAgentTargetSelectionStage } from './creativeAgentViewModel';
import { CreativeAgentWorkspace } from './CreativeAgentWorkspace';

function createTemplate(
  overrides: Partial<PuzzleCreativeTemplateProtocol> = {},
): PuzzleCreativeTemplateProtocol {
  return {
    templateId: 'puzzle.default-creative',
    title: '创意拼图',
    summary: '把图文灵感做成拼图。',
    previewImageSrc: null,
    supportedLevelMode: 'single_or_multi',
    minLevelCount: 1,
    maxLevelCount: 6,
    defaultLevelCount: 1,
    costRange: {
      minPoints: 2,
      maxPoints: 12,
      pricingUnit: 'point',
      reason: '按关卡数估算',
    },
    requiredDraftFields: ['workTitle'],
    imagePolicy: {
      allowUploadedImageDirectly: true,
      allowGeneratedImages: true,
      allowPerLevelReferenceImage: true,
      defaultCandidateCountPerLevel: 1,
    },
    ...overrides,
  };
}

function createSession(
  overrides: Partial<CreativeAgentSessionSnapshot> = {},
): CreativeAgentSessionSnapshot {
  return {
    sessionId: 'creative-session-1',
    stage: 'target_ready',
    inputSummary: {
      text: '做一个生日拼图',
      entryContext: 'creation_home',
      images: [],
      materialSummary: '做一个生日拼图',
      unsupportedCapabilities: [
        {
          playType: 'rpg',
          title: 'RPG',
          status: 'unsupported',
          reason: 'Phase 1 暂不开放',
        },
      ],
    },
    messages: [
      {
        id: 'assistant-1',
        role: 'assistant',
        kind: 'chat',
        text: '拼图草稿已准备好。',
        createdAt: '2026-05-05T10:00:00.000Z',
      },
    ],
    puzzleTemplateCatalog: [],
    puzzleTemplateSelection: null,
    puzzleImageGenerationPlan: null,
    targetBinding: {
      playType: 'puzzle',
      targetSessionId: 'puzzle-session-1',
      targetStage: 'puzzle-result',
      resultProfileId: 'puzzle-profile-1',
    },
    updatedAt: '2026-05-05T10:00:00.000Z',
    ...overrides,
  };
}

test('target ready session exposes the puzzle result entry action', () => {
  const onOpenTarget = vi.fn();
  const eventLog: CreativeAgentSseEvent[] = [
    {
      event: 'puzzle_cost_range',
      data: {
        sessionId: 'creative-session-1',
        costRange: {
          minPoints: 2,
          maxPoints: 12,
          pricingUnit: 'point',
          reason: '按关卡数估算',
        },
      },
    },
  ];

  render(
    <CreativeAgentWorkspace
      session={createSession()}
      isBusy={false}
      isStreaming={false}
      error={null}
      eventLog={eventLog}
      onBack={() => {}}
      onSubmitMessage={() => {}}
      onConfirmTemplate={() => {}}
      onCancelTemplate={() => {}}
      onOpenTarget={onOpenTarget}
    />,
  );

  expect(screen.getByText('拼图草稿已就绪')).toBeTruthy();
  expect(screen.getByText('可以进入结果页继续编辑')).toBeTruthy();
  expect(screen.getByText('预计 2-12 泥点')).toBeTruthy();

  fireEvent.click(screen.getByRole('button', { name: '打开草稿' }));

  expect(onOpenTarget).toHaveBeenCalledTimes(1);
});

test('waiting confirmation shows template catalog before template config dialog', () => {
  const onConfirmTemplate = vi.fn();

  render(
    <CreativeAgentWorkspace
      session={createSession({
        stage: 'waiting_template_confirmation',
        targetBinding: null,
        puzzleTemplateCatalog: [
          createTemplate(),
          createTemplate({
            templateId: 'puzzle.travel-memory',
            title: '旅行记忆拼图',
            summary: '把一次出行拆成地点、风景和故事节点拼图。',
            defaultLevelCount: 3,
            costRange: {
              minPoints: 4,
              maxPoints: 16,
              pricingUnit: 'point',
              reason: '按旅行节点估算',
            },
          }),
        ],
      })}
      isBusy={false}
      isStreaming={false}
      error={null}
      eventLog={[]}
      onBack={() => {}}
      onSubmitMessage={() => {}}
      onConfirmTemplate={onConfirmTemplate}
      onOpenTarget={() => {}}
    />,
  );

  expect(screen.getByRole('button', { name: /创意拼图/u })).toBeTruthy();
  expect(screen.getByRole('button', { name: /旅行记忆拼图/u })).toBeTruthy();
  expect(screen.queryByRole('dialog', { name: '确认拼图模板' })).toBeNull();

  fireEvent.click(screen.getByRole('button', { name: /旅行记忆拼图/u }));

  expect(screen.getByRole('dialog', { name: '确认拼图模板' })).toBeTruthy();
  expect(screen.getByText('预计 4 到 16 泥点')).toBeTruthy();

  fireEvent.click(screen.getByRole('button', { name: /确认/u }));

  expect(onConfirmTemplate).toHaveBeenCalledWith(
    expect.objectContaining({
      templateId: 'puzzle.travel-memory',
      selectedLevelMode: 'multi_level',
      plannedLevelCount: 3,
    }),
  );
});

test('switching creative session clears pending template config dialog', () => {
  const firstSession = createSession({
    sessionId: 'creative-session-first',
    stage: 'waiting_template_confirmation',
    targetBinding: null,
    puzzleTemplateCatalog: [createTemplate()],
  });
  const secondSession = createSession({
    sessionId: 'creative-session-second',
    stage: 'waiting_template_confirmation',
    targetBinding: null,
    puzzleTemplateCatalog: [],
  });
  const { rerender } = render(
    <CreativeAgentWorkspace
      session={firstSession}
      isBusy={false}
      isStreaming={false}
      error={null}
      eventLog={[]}
      onBack={() => {}}
      onSubmitMessage={() => {}}
      onConfirmTemplate={() => {}}
      onOpenTarget={() => {}}
    />,
  );

  fireEvent.click(screen.getByRole('button', { name: /创意拼图/u }));

  expect(screen.getByRole('dialog', { name: '确认拼图模板' })).toBeTruthy();

  rerender(
    <CreativeAgentWorkspace
      session={secondSession}
      isBusy={false}
      isStreaming={false}
      error={null}
      eventLog={[]}
      onBack={() => {}}
      onSubmitMessage={() => {}}
      onConfirmTemplate={() => {}}
      onOpenTarget={() => {}}
    />,
  );

  expect(screen.queryByRole('dialog', { name: '确认拼图模板' })).toBeNull();
});

test('target ready puzzle result binding resolves to puzzle-result stage', () => {
  expect(resolveCreativeAgentTargetSelectionStage('puzzle-result')).toBe(
    'puzzle-result',
  );
  expect(
    resolveCreativeAgentTargetSelectionStage('puzzle-agent-workspace'),
  ).toBe('puzzle-agent-workspace');
});

test('target ready timeline renders completed labels instead of active labels', () => {
  render(<CreativeAgentStageTimeline stage={'target_ready' as CreativeAgentStage} />);

  expect(screen.getByText('素材已理解')).toBeTruthy();
  expect(screen.getByText('构思已完成')).toBeTruthy();
  expect(screen.getByText('草稿已生成')).toBeTruthy();
  expect(screen.queryByText('正在理解素材')).toBeNull();
  expect(screen.queryByText('正在构思')).toBeNull();
});
