/* @vitest-environment jsdom */

import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { expect, test, vi } from 'vitest';

import type {
  CustomWorldNpc,
  CustomWorldPlayableNpc,
  CustomWorldProfile,
} from '../types';
import { CustomWorldEntityEditorModal } from './CustomWorldEntityEditorModal';

vi.mock('./CharacterAnimator', () => ({
  CharacterAnimator: () => <div>角色预览</div>,
}));

vi.mock('./CustomWorldNpcVisualEditor', () => ({
  CustomWorldNpcPortrait: ({ npc }: { npc: { name: string } }) => (
    <div>{npc.name}</div>
  ),
  CustomWorldNpcVisualEditor: () => <div>预设形象编辑器</div>,
}));

vi.mock('./asset-studio/characterAssetWorkflowPersistence', () => ({
  fetchCharacterWorkflowCache: vi.fn().mockResolvedValue({ cache: null }),
  generateCharacterPromptBundle: vi.fn().mockResolvedValue({
    visualPromptText: '自动生成的形象提示词',
    animationPromptText: '自动生成的动作提示词',
  }),
  saveCharacterWorkflowCache: vi.fn().mockResolvedValue(undefined),
  generateCharacterVisualCandidates: vi.fn(),
  publishCharacterVisualAsset: vi.fn(),
  generateCharacterAnimationDraft: vi.fn(),
  publishCharacterAnimationAssets: vi.fn(),
}));

function createBackstoryReveal() {
  return {
    publicSummary: '公开背景',
    chapters: [
      {
        id: 'surface',
        title: '表层来意',
        affinityRequired: 6,
        teaser: '表层来意',
        content: '表层来意内容',
        contextSnippet: '表层来意摘要',
      },
      {
        id: 'scar',
        title: '旧事裂痕',
        affinityRequired: 12,
        teaser: '旧事裂痕',
        content: '旧事裂痕内容',
        contextSnippet: '旧事裂痕摘要',
      },
      {
        id: 'hidden',
        title: '隐藏执念',
        affinityRequired: 18,
        teaser: '隐藏执念',
        content: '隐藏执念内容',
        contextSnippet: '隐藏执念摘要',
      },
      {
        id: 'final',
        title: '最终底牌',
        affinityRequired: 24,
        teaser: '最终底牌',
        content: '最终底牌内容',
        contextSnippet: '最终底牌摘要',
      },
    ],
  };
}

function createPlayableRole(id: string, name: string): CustomWorldPlayableNpc {
  return {
    id,
    name,
    title: '同行者',
    role: '协作战力',
    description: `${name}的定位描述`,
    backstory: `${name}的背景`,
    personality: `${name}的性格`,
    motivation: `${name}的动机`,
    combatStyle: `${name}的战斗风格`,
    initialAffinity: 18,
    relationshipHooks: ['关系钩子'],
    relations: [],
    tags: ['测试'],
    backstoryReveal: createBackstoryReveal(),
    skills: [],
    initialItems: [],
    templateCharacterId: 'knight-female-1',
  };
}

function createStoryRole(id: string, name: string): CustomWorldNpc {
  return {
    ...createPlayableRole(id, name),
    initialAffinity: 6,
    visual: undefined,
  };
}

function createProfile(): CustomWorldProfile {
  return {
    id: 'world-1',
    settingText: '潮雾群岛上的禁制与旧航道正在一起失衡。',
    name: '潮雾群岛',
    subtitle: '旧航道与沉钟回响',
    summary: '一座正在被旧誓与新利益共同撕扯的群岛世界。',
    tone: '压抑、潮湿、带着未解旧伤。',
    playerGoal: '找到能让群岛重新稳定的关键节点。',
    templateWorldType: 'WUXIA',
    majorFactions: ['守潮盟', '沉钟会'],
    coreConflicts: ['旧航道归属', '沉钟遗产争夺'],
    attributeSchema: {},
    playableNpcs: [createPlayableRole('playable-1', '沈砺')],
    storyNpcs: [createStoryRole('story-1', '顾潮音')],
    items: [],
    camp: {
      name: '潮灯居',
      description: '玩家最初落脚的旧灯塔内院。',
      dangerLevel: 'medium',
    },
    landmarks: [],
    creatorIntent: null,
    anchorPack: null,
    lockState: null,
    ownedSettingLayers: null,
    generationMode: 'full',
    generationStatus: 'complete',
  } as unknown as CustomWorldProfile;
}

test('playable角色打开AI工坊后不会自动关闭', async () => {
  const user = userEvent.setup();
  const handleClose = vi.fn();

  render(
    <CustomWorldEntityEditorModal
      profile={createProfile()}
      target={{ kind: 'playable', mode: 'edit', id: 'playable-1' }}
      onClose={handleClose}
      onProfileChange={vi.fn()}
    />,
  );

  await user.click(screen.getByRole('button', { name: 'AI生成' }));

  await waitFor(() => {
    expect(screen.getByText('AI角色形象生成')).toBeTruthy();
  });

  expect(handleClose).not.toHaveBeenCalled();
});

test('场景角色打开AI工坊后不会自动关闭', async () => {
  const user = userEvent.setup();
  const handleClose = vi.fn();

  render(
    <CustomWorldEntityEditorModal
      profile={createProfile()}
      target={{ kind: 'story', mode: 'edit', id: 'story-1' }}
      onClose={handleClose}
      onProfileChange={vi.fn()}
    />,
  );

  await user.click(screen.getByRole('button', { name: 'AI生成' }));

  await waitFor(() => {
    expect(screen.getByText('AI角色形象生成')).toBeTruthy();
  });

  expect(handleClose).not.toHaveBeenCalled();
});
