const { test, expect } = require('@playwright/test');
const testData = require('./fixtures/test-data');
const { cleanDatabase, seedExistingUser, disconnect, prisma } = require('./fixtures/database');

test.describe('创作者中心与角色发布/编辑', () => {
  let existingUser;
  let existingRole;

  test.beforeAll(async () => {
    await cleanDatabase();
    await seedExistingUser();
    existingUser = await prisma.user.findUnique({
      where: { account: testData.users.existing.account },
    });

    existingRole = await prisma.role.create({
      data: {
        creatorId: existingUser.id,
        displayName: '已有角色',
        gender: 'female',
        personality: '温柔体贴',
        background: '来自南方',
        speechStyle: '轻声细语',
        greeting: '你好~',
        desc: '温柔体贴的角色',
        price: 19.9,
        status: 'running',
        temperature: 0.8,
        maxTokens: 2048,
        enableMemory: true,
        enableTools: false,
        model: 'gpt-4o',
      },
    });
  });

  test.afterAll(async () => {
    await cleanDatabase();
    await disconnect();
  });

  async function loginAsExisting(page) {
    await page.goto('/');
    await page.locator('[data-action="open-characters"]').first().click();
    await expect(page.locator('#auth')).toBeVisible();
    await page.fill('[data-form="login"] [name="account"]', testData.users.existing.account);
    await page.fill('[data-form="login"] [name="password"]', testData.users.existing.password);
    await page.locator('[data-form="login"] button[type="submit"]').click();
    await expect(page.locator('#creator-center')).toBeVisible({ timeout: 5000 });
  }

  test('创作者中心显示三个 tab', async ({ page }) => {
    await loginAsExisting(page);
    await expect(page.locator('[data-center-tab="roles"]')).toBeVisible();
    await expect(page.locator('[data-center-tab="income"]')).toBeVisible();
    await expect(page.locator('[data-center-tab="settings"]')).toBeVisible();
  });

  test('角色 tab 显示已有角色', async ({ page }) => {
    await loginAsExisting(page);
    // 默认在 roles tab
    await expect(page.locator('#creator-role-list .role-card')).toHaveCount(1, { timeout: 5000 });
    await expect(page.locator('#creator-role-list .role-card__name')).toHaveText('已有角色');
  });

  test('收入 tab 显示余额和流水', async ({ page }) => {
    await loginAsExisting(page);
    await page.locator('[data-center-tab="income"]').click();
    // income 面板可见（#center-income 带 active class）
    await expect(page.locator('#center-income')).toBeVisible();
    // 余额元素可见
    await expect(page.locator('#income-balance')).toBeVisible({ timeout: 5000 });
    // 流水列表容器存在
    await expect(page.locator('#income-list')).toBeVisible();
  });

  test('设置 tab 可保存昵称和库名', async ({ page }) => {
    await loginAsExisting(page);
    await page.locator('[data-center-tab="settings"]').click();
    await expect(page.locator('#center-settings')).toBeVisible();

    // 修改设置
    await page.fill('#settings-form [name="creatorName"]', '新昵称');
    await page.fill('#settings-form [name="libraryName"]', '新库名');

    // 保存成功会弹 alert「设置已保存」
    const dialogPromise = page.waitForEvent('dialog');
    await page.locator('#settings-form button[type="submit"]').click();
    const dialog = await dialogPromise;
    expect(dialog.message()).toContain('保存');
    await dialog.accept();
  });

  test('新建角色完整流程（4步表单）', async ({ page }) => {
    await loginAsExisting(page);

    // 点击新建角色
    await page.locator('[data-action="new-role"]').click();
    await expect(page.locator('#creator')).toBeVisible();

    // Step 1: 基础身份（agentId 必填，pattern [a-zA-Z0-9_]+；displayName 必填）
    await page.fill('#character-form [name="agentId"]', 'e2e_test_role');
    await page.fill('#character-form [name="displayName"]', testData.role.displayName);
    await page.selectOption('#character-form [name="gender"]', testData.role.gender);
    await page.fill('#character-form [name="age"]', testData.role.age);
    await page.locator('.form-step.active [data-action="next"]').click();

    // Step 2: 灵魂设定（background / personality / speechStyle 必填）
    await page.fill('#character-form [name="background"]', testData.role.background);
    await page.fill('#character-form [name="personality"]', testData.role.personality);
    await page.fill('#character-form [name="speechStyle"]', testData.role.speechStyle);
    await page.fill('#character-form [name="likes"]', testData.role.likes);
    await page.fill('#character-form [name="dislikes"]', testData.role.dislikes);
    await page.locator('.form-step.active [data-action="next"]').click();

    // Step 3: 关系与记忆（greeting 必填）
    await page.fill('#character-form [name="relationship"]', testData.role.relationship);
    await page.fill('#character-form [name="memories"]', testData.role.memories);
    await page.fill('#character-form [name="secrets"]', testData.role.secrets);
    await page.fill('#character-form [name="greeting"]', testData.role.greeting);
    await page.locator('.form-step.active [data-action="next"]').click();

    // Step 4: 运行配置（model/temperature/maxTokens 有默认值；无 price 字段）
    // 捕获可能的错误弹窗
    let dialogMessage = '';
    page.on('dialog', async (dialog) => {
      dialogMessage = dialog.message();
      await dialog.accept();
    });
    await page.locator('.form-step.active [data-action="publish"]').click();

    // 应显示生成结果面板
    await expect(page.locator('#result-panel')).toBeVisible({ timeout: 15000 });

    // 验证 Soul.md 内容（单个 #preview-code 元素，默认显示 soul）
    await expect(page.locator('#preview-code')).toBeVisible();
    const soulContent = await page.locator('#preview-code').textContent();
    expect(soulContent).toContain(testData.role.displayName);
    // generateSoulMd 会把 personality 按 [,，] 拆分成 " | " 连接的标签
    const personalityTag = testData.role.personality.split(/[,，]/)[0].trim();
    expect(soulContent).toContain(personalityTag);

    // 切换到 config.yaml 预览（preview-tabs 内的 [data-tab="config"]）
    await page.locator('.preview-tabs [data-tab="config"]').click();
    const configContent = await page.locator('#preview-code').textContent();
    expect(configContent).toContain('model:');
    expect(configContent).toContain('temperature:');
  });

  test('新建角色后数据库有记录', async ({ page }) => {
    await loginAsExisting(page);
    await page.locator('[data-action="new-role"]').click();
    await expect(page.locator('#creator')).toBeVisible();

    // Step 1: 填写最小必填字段
    await page.fill('#character-form [name="agentId"]', 'e2e_db_role');
    await page.fill('#character-form [name="displayName"]', 'DB验证角色');
    await page.selectOption('#character-form [name="gender"]', 'female');
    await page.locator('.form-step.active [data-action="next"]').click();

    // Step 2
    await page.fill('#character-form [name="personality"]', '测试性格');
    await page.fill('#character-form [name="background"]', '测试背景');
    await page.fill('#character-form [name="speechStyle"]', '测试风格');
    await page.locator('.form-step.active [data-action="next"]').click();

    // Step 3
    await page.fill('#character-form [name="greeting"]', '测试问候');
    await page.locator('.form-step.active [data-action="next"]').click();

    // Step 4: 直接发布（无 price 字段，使用默认值）
    let dialogMessage = '';
    page.on('dialog', async (dialog) => {
      dialogMessage = dialog.message();
      await dialog.accept();
    });
    await page.locator('.form-step.active [data-action="publish"]').click();
    await expect(page.locator('#result-panel')).toBeVisible({ timeout: 15000 });

    // 验证数据库
    const dbRole = await prisma.role.findFirst({
      where: { displayName: 'DB验证角色' },
    });
    expect(dbRole).not.toBeNull();
    expect(dbRole.personality).toBe('测试性格');
    expect(dbRole.greeting).toBe('测试问候');
    expect(dbRole.soulMd).not.toBeNull();
    expect(dbRole.configYaml).not.toBeNull();
  });

  test('编辑角色加载已有数据', async ({ page }) => {
    await loginAsExisting(page);

    // 等待角色列表加载，找到已 seeded 的角色（其他测试可能已创建额外角色）
    await expect(page.locator('#creator-role-list .role-card')).not.toHaveCount(0, { timeout: 5000 });
    // 定位到"已有角色"那张卡片的编辑按钮
    const seededCard = page.locator('#creator-role-list .role-card', { hasText: '已有角色' }).first();
    await expect(seededCard).toBeVisible({ timeout: 5000 });
    await seededCard.locator('[data-action="edit-role"]').click();
    await expect(page.locator('#creator')).toBeVisible();

    // 验证表单已预填（loadRoleForEdit 会拉取 /roles/:id/full 填充表单）
    await expect(page.locator('#character-form [name="displayName"]')).toHaveValue('已有角色', { timeout: 5000 });
    await expect(page.locator('#character-form [name="personality"]')).toHaveValue('温柔体贴');
  });

  test('表单验证 - 必填字段为空时阻止提交', async ({ page }) => {
    await loginAsExisting(page);
    await page.locator('[data-action="new-role"]').click();
    await expect(page.locator('#creator')).toBeVisible();

    // 不填任何字段直接点下一步
    await page.locator('.form-step.active [data-action="next"]').click();

    // 应仍停留在 step 0（agentId / displayName 必填，验证失败）
    // step 0 仍 active => agentId 字段仍可见
    await expect(page.locator('#character-form [name="agentId"]')).toBeVisible();
    await expect(page.locator('#character-form [name="displayName"]')).toBeVisible();
  });

  test('步骤导航 - 上一步按钮', async ({ page }) => {
    await loginAsExisting(page);
    await page.locator('[data-action="new-role"]').click();
    await expect(page.locator('#creator')).toBeVisible();

    // 填写 step 1 并前进
    await page.fill('#character-form [name="agentId"]', 'e2e_nav_test');
    await page.fill('#character-form [name="displayName"]', '导航测试');
    await page.selectOption('#character-form [name="gender"]', 'female');
    await page.locator('.form-step.active [data-action="next"]').click();

    // 进入 step 2 后点上一步（data-action="prev"，非 prev-step）
    await expect(page.locator('#character-form [name="background"]')).toBeVisible();
    await page.locator('.form-step.active [data-action="prev"]').click();

    // 应回到 step 1，且数据保留
    await expect(page.locator('#character-form [name="displayName"]')).toBeVisible();
    await expect(page.locator('#character-form [name="displayName"]')).toHaveValue('导航测试');
  });
});
