import { Browser, expect, test } from '@playwright/test';
import { FUYAO_BASE_URL } from '@/utils/constants';
import {
  clickCreate,
  fillYamlContent,
  saveCreateOrEdit,
  cancelCreateOrEdit,
  searchResource,
  deleteResourceInList,
  confirmDeleteDialog,
  cancelDeleteDialog,
  clickRefresh,
  clickYamlTab,
  openModifyLabelAnnotationEditor,
  ExpectAddLabelAnnotationSuccess,
  deleteLabelAnnotationAndExpectSuccess,
  expectEmptyLabelAnnotationError,
  expectNoChangeLabelAnnotationMessage,
  clickDeleteInDetail,
  clickExportYaml,
  clickFindInYaml,
  clickCopyYaml,
  clickEditResourceInList,
  expectSuccessMessage,
  expectErrorMessage,
  replaceTextInEditor,
  expectResourceDeleted,
} from '@/console/utils/common';
import { newAuthorizedContext } from '@/utils/common';
import path from 'path';
import { fileURLToPath } from 'url';
import fs from 'fs';

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const staticDir = path.resolve(__dirname, '../static');

const setYamlInEditor = async (
  page: import('@playwright/test').Page,
  editFunc?: (content: string) => string,
  yamlFileName: string = 'valid-limitrange.yaml',
): Promise<void> => {
  let content = fs.readFileSync(path.join(staticDir, yamlFileName), 'utf-8');
  if (editFunc) {
    content = editFunc(content);
  }
  await fillYamlContent(page, content);
};

const LIMITRANGE_NAME = 'test-limitrange';
const LIMITRANGE_NAMESPACE = 'default';

const cleanupTestLimitRange = async (browser: Browser) => {
  const context = await newAuthorizedContext(browser);
  const page = await context.newPage();
  await page.goto(FUYAO_BASE_URL + '/container_platform/namespace/limitRange');
  await searchResource(page, LIMITRANGE_NAME);
  if (await page.getByRole('row', { name: new RegExp(LIMITRANGE_NAME) }).first().isVisible({ timeout: 10000 })) {
    await deleteResourceInList(page, LIMITRANGE_NAME);
    await confirmDeleteDialog(page);
    await expect(page.getByText(/删除成功/)).toBeVisible({ timeout: 10000 });
  }

  await context.close();
};

test.describe('limitrange管理', () => {
  test.beforeEach(async ({ page }) => {
    await page.goto(FUYAO_BASE_URL + '/container_platform/namespace/limitRange');
  });

  test.afterAll(async ({ browser }) => {
    await cleanupTestLimitRange(browser);
  });

  test.describe.configure({ mode: 'serial' });

  test('【资源管理-344】 命名空间-LimitRange,取消创建LimitRange成功', {
    tag: ['@v24.06', '@k8s'],
  }, async ({ page }) => {
    await clickCreate(page);
    await setYamlInEditor(page);
    await cancelCreateOrEdit(page);
    await searchResource(page, LIMITRANGE_NAME);
    await expect(page.getByText('暂无数据')).toBeVisible({ timeout: 5000 });
  });

  test('【资源管理-340】 命名空间-LimitRange,输入格式有误的yaml创建LimitRange失败有提示', {
    tag: ['@v24.06', '@k8s'],
  }, async ({ page }) => {
    await clickCreate(page);
    // 去除全部缩进
    await setYamlInEditor(page, (content) => (
      content.replace(/\s+/g, '')
    ));
    await saveCreateOrEdit(page);
    await expectErrorMessage(page, /命名空间必须填写!/);
  });

  test('【资源管理-341】 命名空间-LimitRange,输入字段有误的yaml创建LimitRange失败有提示', {
    tag: ['@v24.06', '@k8s'],
  }, async ({ page }) => {
    await clickCreate(page);
    await setYamlInEditor(page, (content) => (
      content.replace(/1Gi/g, '32Mi')
    ));
    await saveCreateOrEdit(page);
    await expectErrorMessage(page, new RegExp(`LimitRange "${LIMITRANGE_NAME}" is invalid`));
  });

  test('【资源管理-342】 命名空间-LimitRange,使用不存在的namespace创建,应提示', {
    tag: ['@v24.06', '@k8s'],
  }, async ({ page }) => {
    await clickCreate(page);
    await setYamlInEditor(page, (content) => (
      content.replace(/namespace: default/g, 'namespace: non-existing-ns')
    ));
    await saveCreateOrEdit(page);
    await expectErrorMessage(page, 'namespaces "non-existing-ns" not found');
  });

  test('【资源管理-339】 命名空间-LimitRange,输入正确yaml创建LimitRange成功', {
    tag: ['@v24.06', '@k8s'],
  }, async ({ page }) => {
    await clickCreate(page);
    await setYamlInEditor(page);
    await saveCreateOrEdit(page);
    await expectSuccessMessage(page);
    await searchResource(page, LIMITRANGE_NAME);
    await expect(page.getByRole('row', { name: new RegExp(LIMITRANGE_NAME) }).first()).toBeVisible({ timeout: 10000 });
  });

  test('【资源管理-342】 命名空间-LimitRange,同一个命名空间下已存在相同的LimitRange名称,应提示', {
    tag: ['@v24.06', '@k8s'],
  }, async ({ page }) => {
    await clickCreate(page);
    await setYamlInEditor(page);
    await saveCreateOrEdit(page);
    await expectErrorMessage(page, /limitranges ".*" already exists/);
  });

  test('【资源管理-347】 命名空间-LimitRange,搜索框输入正确的LimitRange名称,可正确查询出LimitRange信息', {
    tag: ['@v24.06', '@k8s'],
  }, async ({ page }) => {
    await searchResource(page, LIMITRANGE_NAME);
    await expect(page.getByRole('row', { name: new RegExp(LIMITRANGE_NAME) }).first()).toBeVisible({ timeout: 10000 });
  });

  test('【资源管理-348】 命名空间-LimitRange,搜索框异常场景验证', {
    tag: ['@v24.06', '@k8s'],
  }, async ({ page }) => {
    // 大小写不敏感
    await searchResource(page, LIMITRANGE_NAME.toUpperCase());
    await expect(page.getByRole('row', { name: new RegExp(LIMITRANGE_NAME) }).first()).toBeVisible({ timeout: 10000 });
    // 最大长度63
    await searchResource(page, 'a'.repeat(64));
    await expect(page.getByText(/暂无数据/)).toBeVisible({ timeout: 5000 });
  });

  test('【资源管理-358】 命名空间-LimitRange,取消删除LimitRange成功', {
    tag: ['@v24.06', '@k8s'],
  }, async ({ page }) => {
    await searchResource(page, LIMITRANGE_NAME);
    await deleteResourceInList(page, LIMITRANGE_NAME);
    await cancelDeleteDialog(page);
    await expect(page.getByRole('row', { name: new RegExp(LIMITRANGE_NAME) }).first()).toBeVisible({ timeout: 5000 });
  });

  test('【资源管理-357】 命名空间-LimitRange,删除LimitRange成功', {
    tag: ['@v24.06', '@k8s'],
  }, async ({ page }) => {
    await searchResource(page, LIMITRANGE_NAME);
    await deleteResourceInList(page, LIMITRANGE_NAME);
    await confirmDeleteDialog(page);
    await expect(page.getByText(/删除成功/)).toBeVisible({ timeout: 10000 });
    await searchResource(page, LIMITRANGE_NAME);
    await expectResourceDeleted(page, LIMITRANGE_NAME);
  });

  test('【资源管理-360】 命名空间-LimitRange,刷新按钮可正常点击', {
    tag: ['@v24.06', '@k8s'],
  }, async ({ page }) => {
    await clickRefresh(page);
  });

  test('【资源管理-345】 命名空间-LimitRange,短时间连续点击创建按钮时,查看页面提示', {
    tag: ['@v24.06', '@k8s'],
  }, async ({ page }) => {
    await clickCreate(page);
    await setYamlInEditor(page);
    await saveCreateOrEdit(page);
    await saveCreateOrEdit(page);
    await expectSuccessMessage(page);
    await expectErrorMessage(page, /limitranges ".*" already exists/);
    await searchResource(page, LIMITRANGE_NAME);
    await expect(page.getByRole('row', { name: new RegExp(LIMITRANGE_NAME) }).first()).toBeVisible({ timeout: 10000 });
  });

  test('【资源管理-350】 命名空间-LimitRange,修改LimitRange时输入正确yaml修改LimitRange成功', {
    tag: ['@v24.06', '@k8s'],
  }, async ({ page }) => {
    await searchResource(page, LIMITRANGE_NAME);
    await clickEditResourceInList(page, LIMITRANGE_NAME);
    await replaceTextInEditor(page, 'example.com/created-by: e2e', 'example.com/created-by: e2e-test');
    await saveCreateOrEdit(page);
    await expectSuccessMessage(page);
  });

  test('【资源管理-351】 命名空间-LimitRange,修改LimitRange时输入格式有误的yaml修改LimitRange失败有提示', {
    tag: ['@v24.06', '@k8s'],
  }, async ({ page }) => {
    await searchResource(page, LIMITRANGE_NAME);
    await clickEditResourceInList(page, LIMITRANGE_NAME);
    await replaceTextInEditor(page, '^\\s+', '');
    await saveCreateOrEdit(page);
    await expectErrorMessage(page, /YAML格式不规范/);
  });

  test('【资源管理-352】 命名空间-LimitRange,修改LimitRange时输入字段有误的yaml修改LimitRange失败有提示', {
    tag: ['@v24.06', '@k8s'],
  }, async ({ page }) => {
    await searchResource(page, LIMITRANGE_NAME);
    await clickEditResourceInList(page, LIMITRANGE_NAME);
    await replaceTextInEditor(page, '1Gi', '32Mi');
    await saveCreateOrEdit(page);
    await expectErrorMessage(page, new RegExp(`LimitRange "${LIMITRANGE_NAME}" is invalid`));
  });

  test('【资源管理-353】 命名空间-LimitRange,修改LimitRange时同一个命名空间下已存在相同的LimitRange名称,应提示', {
    tag: ['@v24.06', '@k8s'],
  }, async ({ page }) => {
    await searchResource(page, `${LIMITRANGE_NAME}-copy`);
    if (await page.getByRole('row', { name: new RegExp(`${LIMITRANGE_NAME}-copy`) }).first().isVisible()) {
      await deleteResourceInList(page, `${LIMITRANGE_NAME}-copy`);
      await confirmDeleteDialog(page);
      await expectSuccessMessage(page, /删除成功!/);
    }
    await clickCreate(page);
    await setYamlInEditor(page, (content) => (
      content.replace(/name: test-limitrange/g, 'name: test-limitrange-copy')
    ));
    await saveCreateOrEdit(page);
    await expectSuccessMessage(page);

    await searchResource(page, LIMITRANGE_NAME);
    await clickEditResourceInList(page, LIMITRANGE_NAME);
    await replaceTextInEditor(page, 'name: test-limitrange', 'name: test-limitrange-copy');
    await saveCreateOrEdit(page);
    await expectErrorMessage(page);

    await page.goto(FUYAO_BASE_URL + '/container_platform/namespace/limitRange');
    await searchResource(page, 'test-limitrange-copy');
    await deleteResourceInList(page, 'test-limitrange-copy');
    await confirmDeleteDialog(page);
    await expectSuccessMessage(page, /删除成功!/);
  });

  test('【资源管理-354】 命名空间-LimitRange,修改时使用不存在的namespace,应提示', {
    tag: ['@v24.06', '@k8s'],
  }, async ({ page }) => {
    await searchResource(page, LIMITRANGE_NAME);
    await clickEditResourceInList(page, LIMITRANGE_NAME);
    await replaceTextInEditor(page, 'namespace: default', 'namespace: non-existing-ns');
    await saveCreateOrEdit(page);
    await expectErrorMessage(page, /修改失败/);
  });

  test('【资源管理-355】 命名空间-LimitRange,取消修改LimitRange成功', {
    tag: ['@v24.06', '@k8s'],
  }, async ({ page }) => {
    await searchResource(page, LIMITRANGE_NAME);
    await clickEditResourceInList(page, LIMITRANGE_NAME);
    await cancelCreateOrEdit(page);
  });

  test('【资源管理-361】 命名空间-LimitRange,LimitRange详情中的详情Tab页面信息展示正确', {
    tag: ['@v24.06', '@k8s'],
  }, async ({ page }) => {
    await page.goto(FUYAO_BASE_URL + `/container_platform/namespace/limitRange/${LIMITRANGE_NAMESPACE}/${LIMITRANGE_NAME}`);
    await page.waitForLoadState('networkidle');
    for (const val of await page.locator('.base_value').all()) {
      // 字段正常显示
      expect(await val.textContent()).not.toMatch(/^-?$/);
    }
  });

  test('【资源管理-362】 命名空间-LimitRange,LimitRange详情的操作-修改标签功能正常', {
    tag: ['@v24.06', '@k8s'],
  }, async ({ page }) => {
    await page.goto(FUYAO_BASE_URL + `/container_platform/namespace/limitRange/${LIMITRANGE_NAMESPACE}/${LIMITRANGE_NAME}`);
    const key = '000-test-key';
    const value = 'test-value';
    await test.step('修改成功', async () => {
      await openModifyLabelAnnotationEditor(page, 'label', 'icon');
      await ExpectAddLabelAnnotationSuccess(page, 'label', key, value);
    });
    await test.step('内容为空', async () => {
      await openModifyLabelAnnotationEditor(page, 'label', 'icon');
      await expectEmptyLabelAnnotationError(page, 'label');
    });
    await test.step('无变化提交', async () => {
      await openModifyLabelAnnotationEditor(page, 'label', 'icon');
      await expectNoChangeLabelAnnotationMessage(page, 'label');
    });
    await test.step('清理测试数据', async () => {
      await openModifyLabelAnnotationEditor(page, 'label', 'icon');
      await deleteLabelAnnotationAndExpectSuccess(page, 'label', key, value);
    });
  });

  test('【资源管理-363】 命名空间-LimitRange,LimitRange详情的操作-修改注解功能正常', {
    tag: ['@v24.06', '@k8s'],
  }, async ({ page }) => {
    await page.goto(FUYAO_BASE_URL + `/container_platform/namespace/limitRange/${LIMITRANGE_NAMESPACE}/${LIMITRANGE_NAME}`);
    const key = '000-test-key';
    const value = 'test-value';
    await test.step('修改成功', async () => {
      await openModifyLabelAnnotationEditor(page, 'annotation', 'icon');
      await ExpectAddLabelAnnotationSuccess(page, 'annotation', key, value);
    });
    await test.step('内容为空', async () => {
      await openModifyLabelAnnotationEditor(page, 'annotation', 'icon');
      await expectEmptyLabelAnnotationError(page, 'annotation');
    });
    await test.step('无变化提交', async () => {
      await openModifyLabelAnnotationEditor(page, 'annotation', 'icon');
      await expectNoChangeLabelAnnotationMessage(page, 'annotation');
    });
    await test.step('清理测试数据', async () => {
      await openModifyLabelAnnotationEditor(page, 'annotation', 'icon');
      await deleteLabelAnnotationAndExpectSuccess(page, 'annotation', key, value);
    });
  });

  test('【资源管理-365】 命名空间-LimitRange,LimitRange详情中的详情Tab-基本信息中修改标签功能正常', {
    tag: ['@v24.06', '@k8s'],
  }, async ({ page }) => {
    await page.goto(FUYAO_BASE_URL + `/container_platform/namespace/limitRange/${LIMITRANGE_NAMESPACE}/${LIMITRANGE_NAME}`);
    const key = '000-test-key';
    const value = 'test-value';
    await test.step('修改成功', async () => {
      await openModifyLabelAnnotationEditor(page, 'label', 'menu')
      await ExpectAddLabelAnnotationSuccess(page, 'label', key, value);
    });
    await test.step('内容为空', async () => {
      await openModifyLabelAnnotationEditor(page, 'label', 'menu')
      await expectEmptyLabelAnnotationError(page, 'label');
    });
    await test.step('无变化提交', async () => {
      await openModifyLabelAnnotationEditor(page, 'label', 'menu')
      await expectNoChangeLabelAnnotationMessage(page, 'label');
    });
    await test.step('清理测试数据', async () => {
      await openModifyLabelAnnotationEditor(page, 'label', 'menu')
      await deleteLabelAnnotationAndExpectSuccess(page, 'label', key, value);
    });
  });

  test('【资源管理-366】 命名空间-LimitRange,LimitRange详情中的详情Tab-基本信息中修改注解功能正常', {
    tag: ['@v24.06', '@k8s'],
  }, async ({ page }) => {
    await page.goto(FUYAO_BASE_URL + `/container_platform/namespace/limitRange/${LIMITRANGE_NAMESPACE}/${LIMITRANGE_NAME}`);
    const key = '000-test-key';
    const value = 'test-value';
    await test.step('修改成功', async () => {
      await openModifyLabelAnnotationEditor(page, 'annotation', 'menu')
      await ExpectAddLabelAnnotationSuccess(page, 'annotation', key, value);
    });
    await test.step('内容为空', async () => {
      await openModifyLabelAnnotationEditor(page, 'annotation', 'menu')
      await expectEmptyLabelAnnotationError(page, 'annotation');
    });
    await test.step('无变化提交', async () => {
      await openModifyLabelAnnotationEditor(page, 'annotation', 'menu')
      await expectNoChangeLabelAnnotationMessage(page, 'annotation');
    });
    await test.step('清理测试数据', async () => {
      await openModifyLabelAnnotationEditor(page, 'annotation', 'menu')
      await deleteLabelAnnotationAndExpectSuccess(page, 'annotation', key, value);
    });
  });

  test('【资源管理-367】 命名空间-LimitRange,LimitRange详情中的YAML Tab页面展示正常', {
    tag: ['@v24.06', '@k8s'],
  }, async ({ page }) => {
    await page.goto(FUYAO_BASE_URL + `/container_platform/namespace/limitRange/${LIMITRANGE_NAMESPACE}/${LIMITRANGE_NAME}`);
    await clickYamlTab(page);
    expect(await page.getByText(/apiVersion|kind:\s*LimitRange/).first().textContent()).not.toBeNull();
  });

  test('【资源管理-368】 命名空间-LimitRange,LimitRange详情中的YAML Tab页面导出按钮正常', {
    tag: ['@v24.06', '@k8s'],
  }, async ({ page }) => {
    await page.goto(FUYAO_BASE_URL + `/container_platform/namespace/limitRange/${LIMITRANGE_NAMESPACE}/${LIMITRANGE_NAME}`);
    await clickYamlTab(page);
    // 监听 download 事件判断是否有文件下载
    const [download] = await Promise.all([
      page.waitForEvent('download', { timeout: 3000 }),
      clickExportYaml(page),
    ]);
    expect(download).toBeTruthy();
  });

  test('【资源管理-369】 命名空间-LimitRange,LimitRange详情中的YAML Tab页面查找按钮正常', {
    tag: ['@v24.06', '@k8s'],
  }, async ({ page }) => {
    await page.goto(FUYAO_BASE_URL + `/container_platform/namespace/limitRange/${LIMITRANGE_NAMESPACE}/${LIMITRANGE_NAME}`);
    await clickYamlTab(page);
    await clickFindInYaml(page);
    await expect(page.getByRole('textbox').or(page.getByPlaceholder(/查找|搜索/))).toBeVisible({ timeout: 3000 });
  });

  test('【资源管理-370】 命名空间-LimitRange,LimitRange详情中的YAML Tab页面复制按钮正常', {
    tag: ['@v24.06', '@k8s'],
  }, async ({ page }) => {
    await page.goto(FUYAO_BASE_URL + `/container_platform/namespace/limitRange/${LIMITRANGE_NAMESPACE}/${LIMITRANGE_NAME}`);
    await clickYamlTab(page);
    await clickCopyYaml(page);
    await expect(page.getByText(/复制成功/)).toBeVisible({ timeout: 3000 });
  });

  test('【资源管理-364】 命名空间-LimitRange,LimitRange详情的操作-删除功能正常', {
    tag: ['@v24.06', '@k8s'],
  }, async ({ page }) => {
    await page.goto(FUYAO_BASE_URL + `/container_platform/namespace/limitRange/${LIMITRANGE_NAMESPACE}/${LIMITRANGE_NAME}`);
    await clickDeleteInDetail(page);
    await confirmDeleteDialog(page);
    await expectSuccessMessage(page, /删除成功!/);
    expect(page.url()).toContain('/container_platform/namespace/limitRange');
    await searchResource(page, LIMITRANGE_NAME);
    await expectResourceDeleted(page, LIMITRANGE_NAME);
  });
});