import { expect, test } from "@playwright/test";
import {
    goToAppMarket,
    installComponent,
    checkComponent,
    upgradeComponent,
    verifyOverviewSort,
    prepareHelloWorldPackageLikeMarketplace,
} from "./utils/application";
import { cleanupAfterEach } from "./utils/application-cleanup";
import type { DeployPlan } from "./test-application.constants";
import {
    totalTimeout,
    upgradeTime,
    serviceClusterUrl,
    appName,
    appNameAiaio,
    appNameMonitor,
    componentNameMonitor,
    PLAN_APP_AIAIO,
    PLAN_EXTEND_LOGGING_MONITOR,
    eagleEyeApp,
    initVersion,
    upgradeVersion,
    EAGLE_INIT_VERSION,
    EAGLE_UPGRADE_VERSION,
    PLAN_APP_EAGLE,
} from "./test-application.constants";

test.describe("应用管理-概览", () => {
    let createdApps: DeployPlan[] = [];
    test.beforeEach(async ({ page }) => {
        await page.goto(serviceClusterUrl + "/container_platform/applicationManageHelm");
    });
    test.afterEach(async ({ page }) => {
        await cleanupAfterEach(page, {
            createdApps,
        });
    });

    async function installComponentTracked(page: any, plan: DeployPlan) {
        await installComponent(page, plan.componentName, plan.appName, plan.version, plan.source);
        createdApps.push(plan);
    }

    async function deployComponents(page: any, plans: DeployPlan[]) {
        for (const plan of plans) {
            await test.step(`部署前置组件(${plan.componentName} -> ${plan.appName})`, async () => {
                await goToAppMarket(page);
                await installComponentTracked(page, plan);
                await checkComponent(page, plan.appName, {
                    entry: plan.entry,
                    serviceClusterUrl,
                });
            });
        }
    }

    test("【应用运维-应用管理概览-007】应用管理-概览-刷新-基础功能验证 ", { tag: ["@v24.06", "@application"] }, async ({ page }) => {
        test.setTimeout(totalTimeout);
        let oldTime = "";
        await test.step("部署应用并记录更新时间", async () => {
            await deployComponents(page, PLAN_APP_EAGLE);
            await page.goto(serviceClusterUrl + "/container_platform/applicationManageHelm");
            await page.getByRole("textbox", { name: /搜索.*名称/ }).fill(eagleEyeApp);
            await page.getByRole("button", { name: "search" }).click();
            await expect(page.getByRole("link", { name: eagleEyeApp })).toBeVisible();
            const row = page
                .getByRole("row")
                .filter({ has: page.getByRole("link", { name: eagleEyeApp }) })
                .first();
            const updateTimeCell = row
                .getByRole("cell")
                .filter({ hasText: /\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}/ })
                .last();
            await expect(updateTimeCell).toBeVisible();
            oldTime = ((await updateTimeCell.textContent()) ?? "").trim();
            await expect(oldTime).not.toBe("");
        });
        await test.step("新标签页进行升级", async () => {
            const pageB = await page.context().newPage();
            await pageB.goto(serviceClusterUrl + "/container_platform/applicationManageHelm");
            await pageB.getByRole("textbox", { name: /搜索.*名称/ }).fill(eagleEyeApp);
            await pageB.getByRole("button", { name: "search" }).click();
            await pageB.getByRole("link", { name: eagleEyeApp }).click();
            await upgradeComponent(pageB, EAGLE_INIT_VERSION, EAGLE_UPGRADE_VERSION);
            await pageB.getByRole("button", { name: /确\s*定/ }).click();
            await expect(pageB.getByText("升级成功")).toBeVisible({ timeout: upgradeTime });
            await pageB.close();
        });
        await test.step("原标签页点击平台刷新并校验更新时间", async () => {
            await page.getByRole("button", { name: "sync" }).click();
            const row = page
                .getByRole("row")
                .filter({ has: page.getByRole("link", { name: eagleEyeApp }) })
                .first();
            const updateTimeCell = row
                .getByRole("cell")
                .filter({ hasText: /\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}/ })
                .last();
            const newTime = ((await updateTimeCell.textContent()) ?? "").trim();
            await expect(newTime).not.toBe("");
            await expect(newTime >= oldTime).toBeTruthy();
        });
    });

    test("【应用运维-扩展组件管理概览-007】扩展管理-概览-刷新-基础功能验证 ", { tag: ["@v24.06", "@application"] }, async ({ page }) => {
        test.setTimeout(totalTimeout);
        let oldTime = "";
        await test.step("部署扩展组件并验证成功", async () => {
            await deployComponents(page, [{ componentName: componentNameMonitor, appName: appNameMonitor, entry: "extendManage", version: initVersion }]);
            oldTime = ((await page.locator(".container-platform-space-item").nth(5).textContent()) ?? "").trim();
            await expect(oldTime).not.toBe("");
        });
        await test.step("创建新标签页升级", async () => {
            const pageB = await page.context().newPage();
            await pageB.goto(serviceClusterUrl + "/container_platform/extendManage");
            await pageB.getByRole("textbox", { name: /搜索.*名称/ }).fill(appNameMonitor);
            await pageB.getByRole("button", { name: "search" }).click();
            await pageB.getByRole("link", { name: appNameMonitor }).click();
            await upgradeComponent(pageB, initVersion, upgradeVersion);
            await pageB.getByRole("button", { name: /确\s*定/ }).click();
            await expect(pageB.getByText("升级成功")).toBeVisible({ timeout: upgradeTime });
            await pageB.close();
        });
        await test.step("返回原标签页检查更新时间", async () => {
            await page.getByRole("button", { name: "sync" }).click();
            const nowTime = ((await page.locator(".container-platform-space-item").nth(5).textContent()) ?? "").trim();
            await expect(nowTime).not.toBe("");
            await expect(nowTime >= oldTime).toBeTruthy();
        });
    });

    test("【应用运维-扩展管理概览-008】扩展管理-概览-排序-基础功能验证 ", { tag: ["@v24.06", "@application"] }, async ({ page }) => {
        await deployComponents(page, PLAN_EXTEND_LOGGING_MONITOR);
        await test.step("进入扩展组件管理概览页", async () => {
            await page.goto(serviceClusterUrl + "/container_platform/extendManage");
            await expect(page.getByRole("table")).toBeVisible();
        });
        await verifyOverviewSort(page, {
            nameHeader: "扩展组件名称",
            nameColIndex: 1,
            updateTimeHeader: "更新时间",
            updateTimeColIndex: 3,
        });
    });

    test("【应用运维-应用管理概览-008】应用管理-概览-排序-基础功能验证 ", { tag: ["@v24.06", "@application"] }, async ({ page }) => {
        await deployComponents(page, PLAN_APP_AIAIO);
        await test.step("进入应用管理概览页", async () => {
            await page.goto(serviceClusterUrl + "/container_platform/applicationManageHelm");
            await expect(page.getByRole("table")).toBeVisible();
        });
        await verifyOverviewSort(page, {
            nameHeader: "应用名称",
            nameColIndex: 1,
            updateTimeHeader: "更新时间",
            updateTimeColIndex: 3,
        });
    });

    test("【应用运维-扩展管理概览-002/009】扩展管理-概览-搜索/筛选-基础功能验证 ", { tag: ["@v24.06", "@application"] }, async ({ page }) => {
        await deployComponents(page, PLAN_EXTEND_LOGGING_MONITOR);
        await test.step("进入扩展组件管理概览页", async () => {
            await page.goto(serviceClusterUrl + "/container_platform/extendManage");
            await expect(page.getByRole("table")).toBeVisible();
        });
        await test.step("搜索:全称命中 test-log", async () => {
            const search = page.getByRole("textbox", { name: /搜索.*名称/ });
            await search.fill(appName);
            await search.press("Enter");
            await expect(page.getByRole("link", { name: appName })).toBeVisible();
        });
        await test.step("搜索:部分命中 log", async () => {
            const search = page.getByRole("textbox", { name: /搜索.*名称/ });
            await search.fill("log");
            await search.press("Enter");
            await expect(page.getByRole("link", { name: appName })).toBeVisible();
        });
        await test.step("搜索:大小写命中 MONITOR", async () => {
            const search = page.getByRole("textbox", { name: /搜索.*名称/ });
            await search.fill("MONITOR");
            await search.press("Enter");
            await expect(page.getByRole("link", { name: appNameMonitor })).toBeVisible();
        });
        await test.step("搜索:数字 1(当前前置数据无数字名称)", async () => {
            const search = page.getByRole("textbox", { name: /搜索.*名称/ });
            await search.fill("1");
            await search.press("Enter");
            await expect(page.getByRole("link", { name: appName })).toHaveCount(0);
            await expect(page.getByRole("link", { name: appNameMonitor })).toHaveCount(0);
        });
        await test.step("按状态筛选部署成功", async () => {
            const search = page.getByRole("textbox", { name: /搜索.*名称/ });
            await search.fill("");
            await search.press("Enter");
            await page.getByLabel("状态").getByRole("button", { name: "filter" }).click();
            await page.getByRole("menuitem", { name: "部署成功" }).click();
            await page.getByRole("button", { name: /确\s*定/ }).click();
            await expect(page.getByRole("table")).toContainText("部署成功");
        });
    });

    test("【应用运维-应用管理概览-002/009】应用管理-概览-搜索/筛选-基础功能验证 ", { tag: ["@v24.06", "@application"] }, async ({ page }) => {
        await deployComponents(page, PLAN_APP_AIAIO);
        await test.step("进入应用管理概览页", async () => {
            await page.goto(serviceClusterUrl + "/container_platform/applicationManageHelm");
            await expect(page.getByRole("table")).toBeVisible();
        });
        await test.step("搜索:全称命中 test-aiaio", async () => {
            const search = page.getByRole("textbox", { name: /搜索.*名称/ });
            await search.fill(appNameAiaio);
            await search.press("Enter");
            await expect(page.getByRole("link", { name: appNameAiaio })).toBeVisible();
        });
        await test.step("搜索:部分命中 aiaio", async () => {
            const search = page.getByRole("textbox", { name: /搜索.*名称/ });
            await search.fill("aiaio");
            await search.press("Enter");
            await expect(page.getByRole("link", { name: appNameAiaio })).toBeVisible();
        });
        await test.step("搜索:大小写命中 AIAIO", async () => {
            const search = page.getByRole("textbox", { name: /搜索.*名称/ });
            await search.fill("AIAIO");
            await search.press("Enter");
            await expect(page.getByRole("link", { name: appNameAiaio })).toBeVisible();
        });
        await test.step("搜索:数字 1(当前前置数据无数字名称)", async () => {
            const search = page.getByRole("textbox", { name: /搜索.*名称/ });
            await search.fill("1");
            await search.press("Enter");
            await expect(page.getByRole("link", { name: appNameAiaio })).toHaveCount(0);
        });
        await test.step("按状态筛选部署成功", async () => {
            const search = page.getByRole("textbox", { name: /搜索.*名称/ });
            await search.fill("");
            await search.press("Enter");
            await page.getByLabel("状态").getByRole("button", { name: "filter" }).click();
            await page.getByRole("menuitem", { name: "部署成功" }).click();
            await page.getByRole("button", { name: /确\s*定/ }).click();
            await expect(page.getByRole("table")).toContainText("部署成功");
        });
    });

    test("【应用运维-应用管理概览-010】应用管理-概览-页面跳转-基础功能验证 ", { tag: ["@v24.06", "@application"] }, async ({ page }) => {
        test.setTimeout(totalTimeout);
        const componentNameHelloWorld = "hello-world";
        const appNames = Array.from({ length: 12 }, (_, i) => `test${i + 1}`);
        await prepareHelloWorldPackageLikeMarketplace(page);
        // 部署 12 个 hello-world
        await deployComponents(
            page,
            appNames.map((appName): DeployPlan => ({
                componentName: componentNameHelloWorld,
                appName,
                entry: "applicationManageHelm",
                source: "",
            })),
        );
        await page.goto(serviceClusterUrl + "/container_platform/applicationManageHelm");
        await expect(page.getByRole("table")).toBeVisible();
        const extractFirstRowAppName = async (): Promise<string> => {
            const rowText = (await page.locator("table tbody tr").first().textContent()) ?? "";
            const m = rowText.match(/test\d+/);
            return m?.[0] ?? rowText.trim();
        };
        const getPaginationContainer = () =>
            page
                .locator("[class*='container-platform-pagination']")
                .filter({ hasText: /条\/页|共\s*\d+\s*条/ })
                .first();
        const clickPageNumber = async (no: number) => {
            const strNo = String(no);
            const pagination = getPaginationContainer();
            await expect(pagination).toBeVisible({ timeout: 60_000 });

            const byText = pagination.getByText(strNo, { exact: true }).first();
            await expect(byText).toBeVisible({ timeout: 60_000 });
            await byText.click();
        };
        const isPageButtonVisible = async (no: number) => {
            const strNo = String(no);
            const pagination = getPaginationContainer();
            if ((await pagination.count()) === 0) return false;
            return pagination.getByText(strNo, { exact: true }).first().isVisible().catch(() => false);
        };
        const pickPageSize = async (size: 10 | 20) => {
            const pagination = getPaginationContainer();
            await expect(pagination).toBeVisible({ timeout: 30_000 });
            const sizeTrigger = pagination.locator(".container-platform-select-selection-item").first();
            await expect(sizeTrigger).toBeVisible({ timeout: 10_000 });
            await sizeTrigger.click();
            const option = page.getByText(new RegExp(`^${size}\\s*条/页$`)).first();
            await expect(option).toBeVisible({ timeout: 10_000 });
            await option.click();
            await expect(pagination.locator(".container-platform-select-selection-item").first()).toContainText(
                new RegExp(`${size}\\s*条/页`),
            );
        };
        await expect(page.getByText(/共\s*13\s*条/)).toBeVisible();
        await pickPageSize(10);
        await expect.poll(async () => await isPageButtonVisible(2), { timeout: 10_000 }).toBeTruthy();
        const firstRowPage1 = await extractFirstRowAppName();
        await clickPageNumber(2);
        await page.waitForTimeout(1000);
        const firstRowPage2 = await extractFirstRowAppName();
        expect(firstRowPage2).not.toBe(firstRowPage1);
        await pickPageSize(20);
        await page.waitForTimeout(1000);
        const page2VisibleAfter20 = await isPageButtonVisible(2);
        expect(page2VisibleAfter20).toBeFalsy();
    });
});