import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { ImageWorkspaceApiError } from '@/lib/image-workspace';
import { ImageCanvas } from '@/pages/ImageCanvas';
import { useAuthStore } from '@/stores/auth';
import { useImageWorkspaceStore } from '@/stores/image-workspace';
import type { ImageWorkspaceSnapshot } from '../../shared/image-workspace';

const fetchImageWorkspaceMock = vi.hoisted(() => vi.fn());
const addImageWorkspaceAgentMock = vi.hoisted(() => vi.fn());
const sendImageWorkspaceMessageMock = vi.hoisted(() => vi.fn());
const uploadImageWorkspaceReferenceMock = vi.hoisted(() => vi.fn());

vi.mock('@/lib/image-workspace', async (importOriginal) => {
  const actual = await importOriginal<typeof import('@/lib/image-workspace')>();
  return {
    ...actual,
    fetchImageWorkspace: (...args: unknown[]) => fetchImageWorkspaceMock(...args),
    addImageWorkspaceAgent: (...args: unknown[]) => addImageWorkspaceAgentMock(...args),
    sendImageWorkspaceMessage: (...args: unknown[]) => sendImageWorkspaceMessageMock(...args),
    uploadImageWorkspaceReference: (...args: unknown[]) => uploadImageWorkspaceReferenceMock(...args),
  };
});

function workspaceFixture(): ImageWorkspaceSnapshot {
  return {
    activeProjectId: 'project-cloud',
    capabilities: {
      modes: [{ id: 'generate', label: '图片生成' }],
      models: [{ id: 'cloud-model', label: '云端模型 A' }],
      aspectRatios: [
        { id: 'square', label: '1:1' },
        { id: 'wide', label: '16:9' },
      ],
      resolutions: [{ id: '2k', label: '2K' }],
      outputCounts: [{ id: 'four', label: '4 张' }],
      defaultModeId: 'generate',
      defaultModelId: 'cloud-model',
      defaultAspectRatioId: 'square',
      defaultResolutionId: '2k',
      defaultOutputCountId: 'four',
      maxReferenceImages: 3,
      referenceUpload: {
        enabled: true,
        acceptedMimeTypes: ['image/png', 'image/jpeg'],
        maxBytes: 5 * 1024 * 1024,
      },
    },
    projects: [{
      id: 'project-cloud',
      name: '云端角色设定',
      activeAgentId: 'agent-default',
      updatedAt: '2026-07-28T10:00:00Z',
      agents: [{ id: 'agent-default', name: '视觉创作 Agent' }],
      messages: [{
        id: 'message-result',
        role: 'assistant',
        agentId: 'agent-default',
        text: '已经为你生成一组角色图。',
        status: 'succeeded',
        createdAt: '2026-07-28T10:00:00Z',
        images: [{
          id: 'image-cloud-1',
          url: 'https://example.com/cloud-result.png',
          thumbnailUrl: 'https://example.com/cloud-result-thumb.png',
          alt: '云端角色结果',
        }],
      }],
    }],
  };
}

function resetAuthStore() {
  useAuthStore.setState({
    initialized: true,
    loading: false,
    error: null,
    authBase: '',
    clientId: 'app',
    accessToken: 'access-token',
    refreshToken: null,
    tokenType: 'Bearer',
    expiresAt: Date.now() + 60_000,
    user: {
      username: 'creator',
      userId: 'user_1',
      tenantId: null,
      deptId: null,
      authorities: ['ROLE_USER'],
    },
  });
}

describe('ImageCanvas cloud conversation workspace', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    window.electron.imageWorkspaceLocalDevelopment = false;
    useImageWorkspaceStore.getState().reset();
    resetAuthStore();
    const workspace = workspaceFixture();
    fetchImageWorkspaceMock.mockResolvedValue(workspace);
    addImageWorkspaceAgentMock.mockResolvedValue(workspace);
    sendImageWorkspaceMessageMock.mockResolvedValue(workspace);
    uploadImageWorkspaceReferenceMock.mockResolvedValue({
      workspace,
      reference: {
        id: 'uploaded-reference',
        url: 'https://example.com/uploaded.png',
        alt: '上传的参考图',
      },
    });
  });

  it('shows an honest unavailable state instead of local or fabricated projects', async () => {
    fetchImageWorkspaceMock.mockRejectedValueOnce(new ImageWorkspaceApiError(
      501,
      'IMAGE_WORKSPACE_UNAVAILABLE',
      '创作空间暂不可用',
    ));

    render(
      <MemoryRouter initialEntries={['/image-canvas']}>
        <ImageCanvas />
      </MemoryRouter>,
    );

    expect(await screen.findByTestId('image-workspace-unavailable')).toHaveTextContent('创作空间暂不可用');
    expect(screen.getByText(/暂时无法连接创作空间/)).toBeInTheDocument();
    expect(screen.queryByText('制作中心')).not.toBeInTheDocument();
    expect(screen.queryByText('任务模块')).not.toBeInTheDocument();
  });

  it('renders cloud projects, conversations, agents, and server-provided generation controls', async () => {
    render(
      <MemoryRouter initialEntries={['/image-canvas']}>
        <ImageCanvas />
      </MemoryRouter>,
    );

    expect(await screen.findByTestId('image-workspace-page')).toHaveTextContent('云端角色设定');
    expect(screen.getByText('当前 Agent：视觉创作 Agent')).toBeInTheDocument();
    expect(screen.getByTestId('image-workspace-conversation')).toHaveTextContent('已经为你生成一组角色图');
    expect(screen.getByRole('img', { name: '云端角色结果' })).toHaveAttribute(
      'src',
      'https://example.com/cloud-result-thumb.png',
    );
    expect(screen.getByLabelText('创作模式')).toHaveValue('generate');
    expect(screen.getByLabelText('模型')).toHaveValue('cloud-model');
    expect(screen.getByLabelText('画幅')).toHaveValue('square');
    expect(screen.getByLabelText('分辨率')).toHaveValue('2k');
    expect(screen.getByLabelText('生成数量')).toHaveValue('four');
    expect(screen.queryByText('Image2')).not.toBeInTheDocument();
  });

  it('renders the anonymous development adapter with the same production copy', async () => {
    useAuthStore.setState({
      accessToken: null,
      refreshToken: null,
      expiresAt: null,
    });
    window.electron.imageWorkspaceLocalDevelopment = true;
    fetchImageWorkspaceMock.mockResolvedValueOnce({
      ...workspaceFixture(),
      activeProjectId: null,
      projects: [],
    });

    render(
      <MemoryRouter initialEntries={['/image-canvas']}>
        <ImageCanvas />
      </MemoryRouter>,
    );

    expect(await screen.findByText('创建第一个项目')).toBeInTheDocument();
    expect(screen.getByRole('button', { name: '新建项目' })).toBeInTheDocument();
    expect(fetchImageWorkspaceMock).toHaveBeenCalledWith(null);
    expect(screen.queryByText('本地开发')).not.toBeInTheDocument();
    expect(screen.queryByText('创建第一个本地项目')).not.toBeInTheDocument();
    expect(screen.queryByText('创建第一个云端项目')).not.toBeInTheDocument();
  });

  it('adds an output only after an explicit action and clears references after a successful turn', async () => {
    render(
      <MemoryRouter initialEntries={['/image-canvas']}>
        <ImageCanvas />
      </MemoryRouter>,
    );

    await screen.findByTestId('image-workspace-page');
    fireEvent.click(screen.getByRole('button', { name: '继续编辑' }));
    expect(screen.getByTestId('image-workspace-selected-references')).toHaveTextContent('云端角色结果');

    fireEvent.change(screen.getByLabelText('创作描述'), { target: { value: '把角色换成夜景光线' } });
    fireEvent.change(screen.getByLabelText('画幅'), { target: { value: 'wide' } });
    fireEvent.click(screen.getByRole('button', { name: '生成图片' }));

    await waitFor(() => expect(sendImageWorkspaceMessageMock).toHaveBeenCalledWith('access-token', {
      projectId: 'project-cloud',
      agentId: 'agent-default',
      prompt: '把角色换成夜景光线',
      referenceImageIds: ['image-cloud-1'],
      settings: {
        modeId: 'generate',
        modelId: 'cloud-model',
        aspectRatioId: 'wide',
        resolutionId: '2k',
        outputCountId: 'four',
      },
    }));
    await waitFor(() => expect(screen.queryByTestId('image-workspace-selected-references')).not.toBeInTheDocument());

    fireEvent.change(screen.getByLabelText('创作描述'), { target: { value: '另起一张纯文字创作' } });
    fireEvent.click(screen.getByRole('button', { name: '生成图片' }));
    await waitFor(() => expect(sendImageWorkspaceMessageMock).toHaveBeenLastCalledWith(
      'access-token',
      expect.objectContaining({
        prompt: '另起一张纯文字创作',
        referenceImageIds: [],
      }),
    ));
  });

  it('uploads references through the cloud boundary and selects the returned cloud image', async () => {
    render(
      <MemoryRouter initialEntries={['/image-canvas']}>
        <ImageCanvas />
      </MemoryRouter>,
    );

    await screen.findByTestId('image-workspace-page');
    const file = new File(['image-bytes'], 'reference.png', { type: 'image/png' });
    fireEvent.change(screen.getByLabelText('选择参考图'), { target: { files: [file] } });

    await waitFor(() => expect(uploadImageWorkspaceReferenceMock).toHaveBeenCalledWith(
      'access-token',
      expect.objectContaining({
        projectId: 'project-cloud',
        fileName: 'reference.png',
        mimeType: 'image/png',
      }),
    ));
    expect(await screen.findByTestId('image-workspace-selected-references')).toHaveTextContent('上传的参考图');
  });
});
