/* @vitest-environment jsdom */

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

import type { BabyObjectMatchDraft } from '../../../packages/shared/src/contracts/edutainmentBabyObject';
import {
  BABY_OBJECT_MATCH_EDUTAINMENT_TAG,
  BABY_OBJECT_MATCH_TEMPLATE_ID,
  BABY_OBJECT_MATCH_TEMPLATE_NAME,
} from '../../../packages/shared/src/contracts/edutainmentBabyObject';
import { BabyObjectMatchResultView } from './BabyObjectMatchResultView';

vi.mock('../ResolvedAssetImage', () => ({
  ResolvedAssetImage: ({
    src,
    alt,
    className,
  }: {
    src?: string | null;
    alt?: string;
    className?: string;
  }) => (src ? <img src={src} alt={alt} className={className} /> : null),
}));

function createDraft(overrides: Partial<BabyObjectMatchDraft> = {}) {
  const draft: BabyObjectMatchDraft = {
    draftId: 'baby-object-draft-1',
    profileId: 'baby-object-profile-1',
    templateId: BABY_OBJECT_MATCH_TEMPLATE_ID,
    templateName: BABY_OBJECT_MATCH_TEMPLATE_NAME,
    workTitle: '宝贝识物',
    workDescription: '苹果和香蕉识物分类',
    itemNames: ['苹果', '香蕉'],
    itemAssets: [
      {
        itemId: 'baby-object-item-1',
        itemName: '苹果',
        imageSrc: 'data:image/svg+xml;utf8,a',
        assetObjectId: null,
        generationProvider: 'placeholder',
        prompt: '苹果',
      },
      {
        itemId: 'baby-object-item-2',
        itemName: '香蕉',
        imageSrc: 'data:image/svg+xml;utf8,b',
        assetObjectId: null,
        generationProvider: 'placeholder',
        prompt: '香蕉',
      },
    ],
    visualPackage: null,
    themeTags: ['宝贝识物'],
    publicationStatus: 'draft',
    createdAt: '2026-05-11T00:00:00.000Z',
    updatedAt: '2026-05-11T00:00:00.000Z',
    publishedAt: null,
    ...overrides,
  };

  return draft;
}

function createGeneratedDraft() {
  return createDraft({
    itemAssets: [
      {
        itemId: 'baby-object-item-1',
        itemName: '苹果',
        imageSrc: 'data:image/png;base64,a',
        assetObjectId: null,
        generationProvider: 'vector-engine-gpt-image-2',
        prompt: '苹果',
      },
      {
        itemId: 'baby-object-item-2',
        itemName: '香蕉',
        imageSrc: 'data:image/png;base64,b',
        assetObjectId: null,
        generationProvider: 'vector-engine-gpt-image-2',
        prompt: '香蕉',
      },
    ],
    visualPackage: {
      themePrompt: '果园主题',
      assets: [
        {
          assetId: 'baby-object-visual-background',
          assetKind: 'background',
          imageSrc: 'data:image/png;base64,background',
          assetObjectId: null,
          generationProvider: 'vector-engine-gpt-image-2',
          prompt: 'background',
        },
        {
          assetId: 'baby-object-visual-ui-frame',
          assetKind: 'ui-frame',
          imageSrc: 'data:image/png;base64,ui',
          assetObjectId: null,
          generationProvider: 'vector-engine-gpt-image-2',
          prompt: 'ui',
        },
        {
          assetId: 'baby-object-visual-gift-box',
          assetKind: 'gift-box',
          imageSrc: 'data:image/png;base64,gift',
          assetObjectId: null,
          generationProvider: 'vector-engine-gpt-image-2',
          prompt: 'gift',
        },
        {
          assetId: 'baby-object-visual-basket',
          assetKind: 'basket',
          imageSrc: 'data:image/png;base64,basket',
          assetObjectId: null,
          generationProvider: 'vector-engine-gpt-image-2',
          prompt: 'basket',
        },
        {
          assetId: 'baby-object-visual-smoke-puff',
          assetKind: 'smoke-puff',
          imageSrc: 'data:image/png;base64,smoke',
          assetObjectId: null,
          generationProvider: 'vector-engine-gpt-image-2',
          prompt: 'smoke',
        },
      ],
    },
  });
}

test('baby object result publishes with exact edutainment tag', async () => {
  const user = userEvent.setup();
  const onPublish = vi.fn();

  render(
    <BabyObjectMatchResultView
      draft={createGeneratedDraft()}
      onBack={() => {}}
      onPublish={onPublish}
    />,
  );

  await user.click(screen.getByRole('button', { name: '发布' }));

  expect(onPublish).toHaveBeenCalledTimes(1);
  expect(onPublish.mock.calls[0]?.[0].themeTags[0]).toBe(
    BABY_OBJECT_MATCH_EDUTAINMENT_TAG,
  );
  expect(onPublish.mock.calls[0]?.[0].themeTags).toContain('宝贝识物');
});

test('baby object result exposes save and test run actions', async () => {
  const user = userEvent.setup();
  const onSaveDraft = vi.fn();
  const onStartTestRun = vi.fn();

  render(
    <BabyObjectMatchResultView
      draft={createGeneratedDraft()}
      onBack={() => {}}
      onSaveDraft={onSaveDraft}
      onStartTestRun={onStartTestRun}
    />,
  );

  await user.click(screen.getByRole('button', { name: '保存草稿' }));
  await user.click(screen.getByRole('button', { name: '试玩' }));

  expect(onSaveDraft).toHaveBeenCalledTimes(1);
  expect(onStartTestRun).toHaveBeenCalledTimes(1);
});

test('baby object result blocks placeholder assets and exposes regeneration', async () => {
  const user = userEvent.setup();
  const onPublish = vi.fn();
  const onStartTestRun = vi.fn();
  const onRegenerateAssets = vi.fn();

  render(
    <BabyObjectMatchResultView
      draft={createDraft()}
      onBack={() => {}}
      onPublish={onPublish}
      onStartTestRun={onStartTestRun}
      onRegenerateAssets={onRegenerateAssets}
    />,
  );

  expect(
    screen.getByText('当前作品仍是占位资源，请重新生成 image-2 资源后再试玩或发布。'),
  ).toBeTruthy();
  expect(
    (screen.getByRole('button', { name: '试玩' }) as HTMLButtonElement)
      .disabled,
  ).toBe(true);
  expect(
    (screen.getByRole('button', { name: '发布' }) as HTMLButtonElement)
      .disabled,
  ).toBe(true);

  await user.click(screen.getByRole('button', { name: '重新生成资源' }));

  expect(onRegenerateAssets).toHaveBeenCalledTimes(1);
  expect(onPublish).not.toHaveBeenCalled();
  expect(onStartTestRun).not.toHaveBeenCalled();
});
