/* @vitest-environment jsdom */

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

import type { GenerateDialogState } from './ImageCanvasEditorTypes';
import { ImageCanvasEditGenerationModalView } from './ImageCanvasEditGenerationModalView';

function createDialog(
  patch: Partial<GenerateDialogState> = {},
): GenerateDialogState {
  return {
    mode: 'edit',
    prompt: '旧修改提示',
    status: 'idle',
    sourceLayerId: 'layer-a',
    ...patch,
  };
}

function EditGenerationModalHarness({
  initialDialog = createDialog(),
  onSubmit = vi.fn(),
}: {
  initialDialog?: GenerateDialogState | null;
  onSubmit?: (dialog: GenerateDialogState) => void;
}) {
  const [dialog, setDialog] = useState<GenerateDialogState | null>(
    initialDialog,
  );

  return (
    <div>
      <ImageCanvasEditGenerationModalView
        dialog={dialog}
        setGenerateDialog={setDialog}
        onSubmit={onSubmit}
      />
      <output aria-label="弹窗状态">{dialog ? 'open' : 'closed'}</output>
      <output aria-label="当前提示词">{dialog?.prompt ?? '-'}</output>
    </div>
  );
}

describe('ImageCanvasEditGenerationModalView', () => {
  it('updates prompt and submits edit generation', () => {
    const submitEdit = vi.fn();
    render(<EditGenerationModalHarness onSubmit={submitEdit} />);

    fireEvent.change(screen.getByLabelText('生成提示词'), {
      target: { value: '新的修改提示' },
    });
    fireEvent.click(screen.getByRole('button', { name: '修改' }));

    expect(screen.getByLabelText('当前提示词').textContent).toBe(
      '新的修改提示',
    );
    expect(submitEdit).toHaveBeenCalledWith(
      expect.objectContaining({ prompt: '新的修改提示' }),
    );
  });

  it('renders failure state and closes through the modal close button', () => {
    render(
      <EditGenerationModalHarness
        initialDialog={createDialog({
          status: 'failed',
          errorMessage: '修改失败',
        })}
      />,
    );

    expect(screen.getByRole('alert').textContent).toContain('修改失败');

    fireEvent.click(screen.getByRole('button', { name: '关闭修改图片' }));

    expect(screen.getByLabelText('弹窗状态').textContent).toBe('closed');
  });

  it('stays hidden for non-edit dialogs and generating edit dialogs', () => {
    const { rerender } = render(
      <EditGenerationModalHarness
        initialDialog={createDialog({ mode: 'generate' })}
      />,
    );

    expect(screen.queryByRole('dialog', { name: '修改图片' })).toBeNull();

    rerender(
      <EditGenerationModalHarness
        initialDialog={createDialog({ status: 'generating' })}
      />,
    );

    expect(screen.queryByRole('dialog', { name: '修改图片' })).toBeNull();
  });
});
