"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.OperateProcessInstancePage = void 0;
const test_1 = require("@playwright/test");
const sleep_1 = require("../../utils/sleep");
const constants_1 = require("../../utils/constants");
const expectLocatorWithRetry_1 = require("../../utils/assertionHelpers/expectLocatorWithRetry");
class OperateProcessInstancePage {
    page;
    diagram;
    completedIcon;
    diagramSpinner;
    activeIcon;
    incidentIcon;
    variablesList;
    messageVariable;
    constructor(page) {
        this.page = page;
        this.diagram = page.getByTestId('diagram');
        this.completedIcon = page
            .getByTestId('instance-header')
            .getByTestId('COMPLETED-icon');
        this.diagramSpinner = page.getByTestId('diagram-spinner');
        this.activeIcon = page
            .getByTestId('instance-header')
            .getByTestId('ACTIVE-icon');
        this.incidentIcon = page
            .getByTestId('instance-header')
            .getByTestId('INCIDENT-icon');
        this.variablesList = page.getByTestId('variables-list');
        this.messageVariable = page.getByTestId('variable-message');
    }
    async connectorResultVariableName(name) {
        return await this.page.getByTestId(name);
    }
    async connectorResultVariableValue(variableName) {
        return await this.page.getByTestId(variableName).locator('td').last();
    }
    async completedIconAssertion() {
        let retryCount = 0;
        const maxRetries = 3;
        while (retryCount < maxRetries) {
            try {
                await (0, test_1.expect)(this.completedIcon).toBeVisible({
                    timeout: 90000,
                });
                return; // Exit the function if the expectation is met
            }
            catch (error) {
                // If the active icon isn't found, reload the page and try again
                retryCount++;
                console.log(`Attempt ${retryCount} failed. Retrying...`);
                await this.page.reload();
                await this.page.waitForLoadState('domcontentloaded');
            }
        }
        throw new Error(`Active icon not visible after ${maxRetries} attempts.`);
    }
    async activeIconAssertion() {
        let retryCount = 0;
        const maxRetries = 3;
        while (retryCount < maxRetries) {
            try {
                await (0, test_1.expect)(this.activeIcon).toBeVisible({
                    timeout: 90000,
                });
                return; // Exit the function if the expectation is met
            }
            catch (error) {
                // If the active icon isn't found, reload the page and try again
                retryCount++;
                console.log(`Attempt ${retryCount} failed. Retrying...`);
                await this.page.reload();
                await this.page.waitForLoadState('domcontentloaded');
            }
        }
        throw new Error(`Active icon not visible after ${maxRetries} attempts.`);
    }
    async activeUserTaskIconVisibleAssertion(taskName) {
        let retryCount = 0;
        const maxRetries = 3;
        while (retryCount < maxRetries) {
            try {
                await (0, test_1.expect)(this.page.getByTestId(taskName)).toBeVisible({
                    timeout: 90000,
                });
                return; // Exit the function if the expectation is met
            }
            catch (error) {
                // If the active icon isn't found, reload the page and try again
                retryCount++;
                console.log(`Attempt ${retryCount} failed. Retrying...`);
                await this.page.reload();
                await this.page.waitForLoadState('domcontentloaded');
            }
        }
        throw new Error(`Active icon not visible after ${maxRetries} attempts.`);
    }
    async activeUserTaskIconNotVisibleAssertion(taskName) {
        let retryCount = 0;
        const maxRetries = 3;
        while (retryCount < maxRetries) {
            try {
                await (0, test_1.expect)(this.page.getByTestId(taskName)).not.toBeVisible({
                    timeout: 90000,
                });
                return; // Exit the function if the expectation is met
            }
            catch (error) {
                // If the active icon is found, reload the page and try again
                retryCount++;
                console.log(`Attempt ${retryCount} failed. Retrying...`);
                await this.page.reload();
                await this.page.waitForLoadState('domcontentloaded');
            }
        }
        throw new Error(`Active icon visible after ${maxRetries} attempts.`);
    }
    async tenantNameAssertion(name) {
        await (0, test_1.expect)(this.page.getByRole('cell', { name: name, exact: true })).toBeVisible({ timeout: 60000 });
    }
    async incidentIconAssertion() {
        await (0, test_1.expect)(this.incidentIcon).toBeVisible({ timeout: 90000 });
    }
    async assertEitherIncidentOrActiveIconVisible() {
        const either = this.incidentIcon.or(this.activeIcon);
        await (0, test_1.expect)(either).toBeVisible({ timeout: 90000 });
        if (await this.incidentIcon.isVisible())
            return 'incident';
        return 'active';
    }
    async assertEitherIncidentOrCompletedIconVisible() {
        const either = this.incidentIcon.or(this.completedIcon);
        await (0, test_1.expect)(either).toBeVisible({ timeout: 90000 });
        if (await this.incidentIcon.isVisible())
            return 'incident';
        return 'completed';
    }
    async assertProcessCompleteStatusWithRetry(timeout = 60000, maxRetries = 10) {
        for (let attempt = 0; attempt < maxRetries; attempt++) {
            try {
                await (0, test_1.expect)(this.completedIcon).toBeVisible({
                    timeout: timeout,
                });
                return;
            }
            catch (error) {
                if (attempt < maxRetries - 1) {
                    console.warn(`Process complete status attempt ${attempt + 1} failed. Retrying...`);
                    await this.page.reload();
                    await this.page.waitForLoadState('domcontentloaded');
                }
                else {
                    throw new Error(`Assertion failed after ${maxRetries} attempts`);
                }
            }
        }
    }
    async assertProcessVariableContainsText(variableName, text) {
        const maxRetries = 3;
        for (let attempt = 0; attempt < maxRetries; attempt++) {
            try {
                await (0, test_1.expect)(this.page.getByTestId(`variable-${variableName}`)).toContainText(text, { timeout: 8000 });
                return;
            }
            catch (uiError) {
                // Document-typed variables render as a compact summary
                // (e.g. "3 documents" or "<docId> <size>") that omits metadata
                // such as filename, storeId, and contentType. Fall back to the
                // raw JSON value from the variables API response.
                try {
                    const value = await this.captureVariableJsonValue(variableName);
                    if (value != null && value.includes(text)) {
                        return;
                    }
                }
                catch (apiError) {
                    console.log(`captureVariableJsonValue for ${variableName} attempt ${attempt + 1}/${maxRetries} failed: ${apiError}`);
                }
                console.log(`assertProcessVariableContainsText attempt ${attempt + 1}/${maxRetries} failed: ${uiError}`);
                if (attempt < maxRetries - 1) {
                    await this.page.reload({ timeout: 10000 }).catch(() => { });
                    await this.page.waitForLoadState('domcontentloaded').catch(() => { });
                }
            }
        }
        throw new Error(`Failed to assert variable ${variableName} contains "${text}" after ${maxRetries} attempts.`);
    }
    async captureVariableJsonValue(variableName) {
        let capturedValue = null;
        const responsePromise = this.page
            .waitForResponse(async (resp) => {
            if (!resp.url().includes('/v2/variables/search') ||
                resp.status() !== 200) {
                return false;
            }
            try {
                const body = await resp.text();
                const data = JSON.parse(body);
                const item = data?.items?.find((i) => i.name === variableName);
                if (item?.value != null) {
                    capturedValue = String(item.value);
                    return true;
                }
                return false;
            }
            catch {
                return false;
            }
        }, { timeout: 15000 })
            .catch(() => null);
        await this.page.reload({ timeout: 10000 }).catch(() => { });
        await this.page.waitForLoadState('domcontentloaded').catch(() => { });
        await responsePromise;
        return capturedValue;
    }
    async assertResultVariableVisibleWithRetry(variableName) {
        const maxRetries = 3;
        for (let attempt = 0; attempt < maxRetries; attempt++) {
            try {
                await (0, test_1.expect)(this.variablesList).toBeVisible({ timeout: 8000 });
                await (0, test_1.expect)(this.page.getByTestId(`variable-${variableName}`)).toBeVisible({ timeout: 8000 });
                return;
            }
            catch (error) {
                console.log(`assertResultVariableVisibleWithRetry attempt ${attempt + 1}/${maxRetries} failed: ${error}`);
                if (attempt < maxRetries - 1) {
                    await this.page.reload({ timeout: 10000 }).catch(() => { });
                    await this.page.waitForLoadState('domcontentloaded').catch(() => { });
                }
            }
        }
        throw new Error(`Failed to assert variable ${variableName} visible after ${maxRetries} attempts.`);
    }
    async assertActiveTokenIsPresent() {
        await (0, test_1.expect)(this.activeIcon).toBeVisible({ timeout: 60000 });
    }
    async assertBusinessIdVisible(businessId) {
        const instanceHeader = this.page.getByTestId('instance-header');
        const reload = async () => {
            await this.page.reload();
        };
        await (0, expectLocatorWithRetry_1.expectLocatorWithRetry)(this.page, instanceHeader.getByText('Business ID'), {
            totalTimeout: 60000,
            visibilityTimeout: 10000,
            maxRetries: 5,
            postAction: reload,
        });
        await (0, expectLocatorWithRetry_1.expectLocatorWithRetry)(this.page, instanceHeader.getByText(businessId, { exact: true }), {
            totalTimeout: 60000,
            visibilityTimeout: 10000,
            maxRetries: 5,
            postAction: reload,
        });
    }
    async assertVariablesListVisible(timeout = 30000) {
        const startTime = Date.now();
        while (Date.now() - startTime < timeout) {
            try {
                await (0, test_1.expect)(this.variablesList).toBeVisible({
                    timeout: constants_1._1_SECOND_IN_MS * 10,
                });
                return;
            }
            catch {
                console.log(`Variables list not visible, reloading... (${Math.round((Date.now() - startTime) / 1000)}s elapsed)`);
                await this.page
                    .reload({ timeout: 10000 })
                    .catch(() => console.log('Page reload timed out, continuing...'));
                await (0, sleep_1.sleep)(2000);
            }
        }
        throw new Error(`Variables list not visible after ${Math.round(timeout / 1000)}s`);
    }
}
exports.OperateProcessInstancePage = OperateProcessInstancePage;
