import { expect, test } from '@playwright/test';

test.describe('Project Canvas Baseline Flow', () => {
  test('enter project, load canvas, edit prompt node, and trigger save', async ({ page }) => {
    const savePayloads: Array<Record<string, unknown>> = [];

    await page.route('**/api/v1/**', async (route) => {
      const req = route.request();
      const url = new URL(req.url());
      const path = url.pathname;
      const method = req.method();

      if (method === 'GET' && path === '/api/v1/config/models') {
        return route.fulfill({
          status: 200,
          contentType: 'application/json',
          body: JSON.stringify({
            code: 0,
            message: 'ok',
            data: { image: {}, video: {}, llm: {}, audio: {} },
          }),
        });
      }

      if (method === 'GET' && path === '/api/v1/projects/e2e-project') {
        return route.fulfill({
          status: 200,
          contentType: 'application/json',
          body: JSON.stringify({
            code: 0,
            message: 'ok',
            data: {
              id: 'e2e-project',
              name: 'E2E Project',
              type: 'video',
              status: 'active',
              created_at: '2026-01-01T00:00:00.000Z',
              updated_at: '2026-01-01T00:00:00.000Z',
              episodes: [],
              assets: [],
              storyboards: [],
              generalCanvases: [],
            },
          }),
        });
      }

      if (method === 'GET' && path === '/api/v1/projects/e2e-project/canvases') {
        const canvasType = url.searchParams.get('canvas_type');
        if (canvasType === 'general') {
          return route.fulfill({
            status: 200,
            contentType: 'application/json',
            body: JSON.stringify({ code: 0, message: 'ok', data: [] }),
          });
        }
      }

      if (method === 'POST' && path === '/api/v1/projects/e2e-project/canvases') {
        return route.fulfill({
          status: 200,
          contentType: 'application/json',
          body: JSON.stringify({
            code: 0,
            message: 'ok',
            data: {
              id: 'canvas-main-1',
              projectId: 'e2e-project',
              canvasType: 'general',
              relatedEntityType: null,
              relatedEntityId: null,
              name: '通用画布',
              description: '',
              orderIndex: 0,
              isPinned: false,
              tags: [],
              nodeCount: 0,
              accessCount: 0,
              createdAt: Date.now(),
              updatedAt: Date.now(),
            },
          }),
        });
      }

      if (method === 'GET' && path === '/api/v1/canvas') {
        return route.fulfill({
          status: 200,
          contentType: 'application/json',
          body: JSON.stringify({
            code: 0,
            message: 'ok',
            data: {
              id: 'canvas-main-1',
              nodes: [],
              connections: [],
              history: [],
            },
          }),
        });
      }

      if (method === 'POST' && path === '/api/v1/canvas') {
        const payload = req.postDataJSON() as Record<string, unknown>;
        savePayloads.push(payload);
        return route.fulfill({
          status: 200,
          contentType: 'application/json',
          body: JSON.stringify({ code: 0, message: 'ok', data: { id: 'canvas-main-1' } }),
        });
      }

      return route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify({ code: 0, message: 'ok', data: {} }),
      });
    });

    await page.goto('/project/e2e-project');

    await expect(
      page.getByPlaceholder('有什么可以帮您？（可输入 @ 选择素材）')
    ).toBeVisible();

    await page.getByTestId('canvas-add-node-toggle').click();
    await page.getByTestId('add-node-prompt_input').click();

    const promptTextarea = page.getByTestId('prompt-input-textarea');
    await expect(promptTextarea).toBeVisible();
    await promptTextarea.fill('E2E: prompt update should be persisted');

    await page.waitForTimeout(900);
    await page.keyboard.press('Control+S');

    await expect.poll(() => savePayloads.length, { timeout: 10000 }).toBeGreaterThan(0);

    await expect.poll(
      () =>
        savePayloads.some((payload) => {
          const nodes = (payload.nodes ?? []) as Array<{ data?: { type?: string; prompt?: string } }>;
          return nodes.some(
            (node) =>
              node.data?.type === 'PROMPT_INPUT'
              && node.data?.prompt?.includes('E2E: prompt update should be persisted')
          );
        }),
      { timeout: 10000 }
    ).toBeTruthy();
  });
});
