"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ConsoleOrganizationPage = void 0;
const test_1 = require("@playwright/test");
const sleep_1 = require("../../utils/sleep");
const expectLocatorWithRetry_1 = require("../../utils/assertionHelpers/expectLocatorWithRetry");
class ConsoleOrganizationPage {
    page;
    usersTab;
    optionsButton;
    editUserMenuItem;
    operationsEngineerCheckbox;
    developerCheckbox;
    analystCheckbox;
    confirmButton;
    settingsTab;
    optInButton;
    optInCheckbox;
    newContextPadButton;
    newContextPadButtonText;
    mainUser;
    authorizations;
    noAuthorizedResourceMessage;
    dialog;
    deleteAuthorisedResourceButton;
    deleteAuthorisedResourceSubButton;
    createResourceAuthorizationButton;
    createResourceAuthorizationDialog;
    nextButton;
    createButton;
    idComboBox;
    readPermissionCheckbox;
    startProcessIPermissionCheckbox;
    optInAICheckbox;
    rows;
    groupsTab;
    createGroupButton;
    createGroupSubButton;
    groupNameInput;
    noGroupsHeading;
    createFirstGroupButton;
    createGroupDialoge;
    assignMembersButton;
    assignMembersSubButton;
    assignMembersSearchbox;
    assignMembersSearchResult;
    organizationManagementLink;
    deleteSubButton;
    deleteButton;
    filterTableSearchbox;
    constructor(page) {
        this.page = page;
        this.usersTab = page.getByRole('tab', { name: 'Users' });
        this.optionsButton = page.getByRole('button', { name: 'Options' });
        this.editUserMenuItem = page.getByRole('menuitem', { name: 'Edit User' });
        this.operationsEngineerCheckbox = page
            .getByRole('group')
            .locator('label')
            .filter({ hasText: 'Operations Engineer' });
        this.developerCheckbox = page
            .getByRole('group')
            .locator('label')
            .filter({ hasText: 'Developer' });
        this.analystCheckbox = page
            .getByRole('group')
            .locator('label')
            .filter({ hasText: 'Analyst' });
        this.confirmButton = page.getByRole('button', { name: 'Confirm' });
        this.settingsTab = page.getByRole('tab', { name: 'Settings' });
        this.optInButton = page.getByRole('button', { name: 'Opt-in', exact: true });
        this.optInCheckbox = page.getByLabel('I understand and agree to');
        this.newContextPadButton = page.getByRole('switch').last();
        this.newContextPadButtonText = page
            .locator('[class= "cds--toggle__text"]')
            .last();
        this.mainUser = page
            .getByRole('row')
            .filter({ hasText: process.env.C8_USERNAME });
        this.authorizations = page.getByRole('tab', {
            name: 'Authorizations',
        });
        this.noAuthorizedResourceMessage = page.getByText("You haven't created any resource authorizations yet", { exact: true });
        this.dialog = page.getByRole('dialog');
        this.deleteAuthorisedResourceButton = page.getByRole('button', {
            name: 'Delete',
        });
        this.deleteAuthorisedResourceSubButton = page.getByRole('button', {
            name: 'danger Delete',
        });
        this.createResourceAuthorizationButton = page.getByRole('button', {
            name: 'Create resource authorization',
            exact: true,
        });
        this.createResourceAuthorizationDialog = page.getByRole('dialog', {
            name: 'Create resource authorizations',
            exact: true,
        });
        this.nextButton = this.createResourceAuthorizationDialog.getByRole('button', {
            name: 'Next',
        });
        this.createButton = this.createResourceAuthorizationDialog.getByRole('button', {
            name: 'Create',
        });
        this.idComboBox = page.getByRole('combobox', { name: 'ID' });
        this.readPermissionCheckbox = page.getByRole('checkbox', {
            name: 'Read definition',
        });
        this.startProcessIPermissionCheckbox = page.getByRole('checkbox', {
            name: 'Start process instance',
        });
        this.optInAICheckbox = page.getByLabel('I understand and agree to Terms for AI Usage');
        this.rows = this.page.getByRole('row');
        this.groupsTab = page.getByRole('tab', { name: 'Groups' });
        this.createGroupButton = page.getByRole('button', {
            name: 'create group',
        });
        this.createGroupSubButton = page
            .getByRole('button', {
            name: 'create group',
        })
            .last();
        this.groupNameInput = page.getByRole('textbox', { name: 'name' });
        this.noGroupsHeading = page.getByRole('heading', {
            name: 'you don’t have any groups yet',
        });
        this.createFirstGroupButton = page.getByRole('button', {
            name: 'create a group',
        });
        this.createGroupDialoge = page.getByRole('dialog', {
            name: 'create group',
        });
        this.assignMembersButton = page.getByRole('button', {
            name: 'assign members',
        });
        this.assignMembersSubButton = page
            .getByRole('button', {
            name: 'assign',
        })
            .last();
        this.assignMembersSearchbox = page.getByRole('searchbox', {
            name: 'search by full name or email address',
        });
        this.assignMembersSearchResult = page.locator('.cds--list-box__menu-item');
        this.organizationManagementLink = page.getByRole('link', {
            name: 'organization management',
        });
        this.deleteButton = page.getByRole('button', { name: 'delete' });
        this.deleteSubButton = page
            .getByRole('button', {
            name: 'danger',
        })
            .last();
        this.filterTableSearchbox = page.getByRole('searchbox', {
            name: 'Filter table',
        });
    }
    async clickCreateAuthorizedResourceButton() {
        await (0, test_1.expect)(this.createButton).toBeVisible({ timeout: 60000 });
        await this.createButton.click();
    }
    async processIdResourceAssertion(processId) {
        await (0, test_1.expect)(this.page.getByRole('row', { name: processId })).toBeVisible({
            timeout: 90000,
        });
    }
    async clickCreateResourceAuthorizationButton() {
        await (0, test_1.expect)(this.createResourceAuthorizationButton).toBeVisible({
            timeout: 60000,
        });
        await this.createResourceAuthorizationButton.click();
    }
    async clickNextButton() {
        await (0, test_1.expect)(this.nextButton).toBeVisible({
            timeout: 60000,
        });
        await this.nextButton.click();
    }
    async clickProcessIdInput() {
        await (0, test_1.expect)(this.idComboBox).toBeVisible({ timeout: 60000 });
        await this.idComboBox.click();
    }
    async fillProcessIdInput(processId) {
        await this.idComboBox.fill(processId);
    }
    async checkReadPermissionCheckbox() {
        await (0, test_1.expect)(this.readPermissionCheckbox).toBeVisible({ timeout: 60000 });
        if (!(await this.readPermissionCheckbox.isChecked())) {
            await this.readPermissionCheckbox.click({ force: true });
        }
    }
    async checkStartInstancePermissionCheckbox() {
        if (!(await this.startProcessIPermissionCheckbox.isChecked())) {
            await this.startProcessIPermissionCheckbox.click({ force: true });
        }
    }
    async clickUsersTab() {
        // The Users tab can fail to render if the Org page is mid-load when we
        // arrive. Try once with a shorter window, reload on failure, then give
        // the second attempt the full timeout before surfacing the error.
        try {
            await (0, test_1.expect)(this.usersTab).toBeVisible({ timeout: 30000 });
        }
        catch {
            await this.page.reload();
            await (0, test_1.expect)(this.usersTab).toBeVisible({ timeout: 60000 });
        }
        await this.usersTab.click({ timeout: 60000 });
        await (0, expectLocatorWithRetry_1.expectLocatorWithRetry)(this.page, this.filterTableSearchbox, {
            postAction: async () => {
                await this.usersTab.click({ timeout: 60000 });
            },
        });
    }
    async clickOptionsButton() {
        const dataRow = this.rows.nth(1);
        await dataRow.hover({ timeout: 30000 }).catch(() => { });
        // Try scoped click first; fall back to page-level with force
        try {
            await dataRow
                .getByRole('button', { name: 'Options' })
                .click({ timeout: 30000 });
        }
        catch (_e) {
            await this.optionsButton.first().click({ force: true, timeout: 60000 });
        }
    }
    async clickEditUserMenuItem() {
        await this.editUserMenuItem.click({ timeout: 60000 });
    }
    async clickOperationsEngineerCheckbox() {
        await this.operationsEngineerCheckbox.click();
    }
    async checkDeveloperCheckbox() {
        if (!(await this.developerCheckbox.isChecked())) {
            await this.developerCheckbox.click({ timeout: 60000 });
        }
    }
    async uncheckDeveloperCheckbox() {
        if (await this.developerCheckbox.isChecked()) {
            await this.developerCheckbox.click({ timeout: 60000 });
        }
    }
    async checkAnalystCheckbox() {
        if (!(await this.analystCheckbox.isChecked())) {
            await this.analystCheckbox.click({ timeout: 60000 });
        }
    }
    async uncheckAnalystCheckbox() {
        if (await this.analystCheckbox.isChecked()) {
            await this.analystCheckbox.click({ timeout: 60000 });
        }
    }
    async clickConfirmButton() {
        await this.confirmButton.click({ timeout: 60000 });
    }
    async clickSettingsTab() {
        await this.settingsTab.click({ timeout: 120000 });
        try {
            await (0, test_1.expect)(this.page.getByRole('heading', { name: 'Alpha features' })).toBeVisible({
                timeout: 120000,
            });
        }
        catch (error) {
            await this.settingsTab.click({ timeout: 120000 });
        }
    }
    async clickOptInButton() {
        await this.optInButton.click({ timeout: 60000 });
    }
    async enableAlphaFeature(name) {
        const maxRetries = 3;
        for (let retries = 0; retries < maxRetries; retries++) {
            try {
                await this.clickSettingsTab();
                await this.optInToAlphaFeatures();
                await (0, sleep_1.sleep)(30000);
                await this.page.reload();
                await this.clickSettingsTab();
                await (0, expectLocatorWithRetry_1.expectLocatorWithRetry)(this.page, this.rows.first(), {
                    visibilityTimeout: 15000,
                    totalTimeout: 90000,
                    postAction: async () => {
                        await this.page.reload();
                    },
                });
                const alphaFeature = this.rows.filter({ hasText: name }).first();
                if ((await alphaFeature.count()) < 1) {
                    console.error(`No alpha feature(${name}) is found.`);
                    return;
                }
                //Opt-in The Alpha Feature
                const alphaFeatureOptInButton = alphaFeature.getByRole('button', {
                    name: 'Opt in to enable',
                });
                if (await alphaFeatureOptInButton.isVisible({ timeout: 10000 })) {
                    await alphaFeatureOptInButton.click({ timeout: 30000 });
                    await this.optInAICheckbox.scrollIntoViewIfNeeded();
                    await this.optInAICheckbox.check({ timeout: 30000 });
                    await (0, sleep_1.sleep)(3000);
                }
                //Enable Alpha Feature
                const toggleText = await alphaFeature
                    .locator('[class= "cds--toggle__text"]')
                    .textContent();
                console.info(`Previous feature(${name}) setting is ${toggleText}.`);
                if (toggleText == 'Enabled') {
                    console.log(`Feature ${name} is already enabled.`);
                    return;
                }
                if (toggleText == 'Disabled') {
                    await alphaFeature
                        .locator('[class= "cds--toggle__switch"]')
                        .first()
                        .click();
                    await (0, sleep_1.sleep)(10000);
                }
                await (0, test_1.expect)(alphaFeature.locator('[class= "cds--toggle__text"]')).toHaveText('Enabled');
                return;
            }
            catch (error) {
                console.error(`Click attempt ${retries + 1} failed: ${error}`);
                await this.page.reload();
                await (0, sleep_1.sleep)(10000);
            }
        }
        throw new Error(`Failed to eanble alpha feature ${name} after ${maxRetries} attempts.`);
    }
    async scrollToOptInCheckbox() {
        await this.page.locator('.ps-contract-scroll').evaluate((el) => {
            el.scrollTop = el.scrollHeight;
        });
    }
    async checkOptInCheckbox() {
        await this.optInCheckbox.check({ timeout: 90000 });
    }
    async clickMainUser(email) {
        await this.filterTable([email]);
        const user = this.rows.filter({ hasText: email }).getByRole('link').first();
        await (0, test_1.expect)(user).toBeVisible({ timeout: 60000 });
        await user.click();
    }
    async clickAuthorizations() {
        await (0, test_1.expect)(this.authorizations).toBeVisible({ timeout: 60000 });
        // The Authorizations tab click sometimes doesn't actually switch the
        // panel — the click registers but Carbon stays on Details and the
        // downstream row assertions then poll forever against the wrong tab.
        // Verify aria-selected after the click and retry with force if needed.
        for (let i = 0; i < 3; i++) {
            await this.authorizations.click({ force: i > 0 });
            const selected = await this.authorizations
                .getAttribute('aria-selected')
                .catch(() => null);
            if (selected === 'true')
                return;
            await this.page.waitForTimeout(1000);
        }
    }
    async authorizedResourceAssertion(processId, maxRetries = 20, timeout = 60000) {
        const url = this.page.url();
        for (let attempt = 0; attempt < maxRetries; attempt++) {
            try {
                await this.page.goto(url, { timeout: 30000 });
                await this.clickAuthorizations();
                await (0, test_1.expect)(this.page.getByRole('row', { name: processId })).toBeVisible({ timeout: timeout });
                return;
            }
            catch (error) {
                if (attempt < maxRetries - 1) {
                    console.warn(`Attempt ${attempt + 1} failed. Error: ${error}. Retrying...`);
                    await (0, sleep_1.sleep)(5000);
                }
                else {
                    throw new Error(`Assertion failed after ${maxRetries} attempts. Last error: ${error}`);
                }
            }
        }
    }
    async authorizedResourcesAssertion(processIds, maxRetries = 10, perCheckTimeout = 30000) {
        // Was 30 × (30s + 30s) ≈ 30 min budget — far too long, and 30 attempts
        // hides whether the failure is really "still propagating" or "stuck on
        // the wrong tab forever". 10 × (30s check + 10s sleep) ≈ ~6.5 min total
        // gives RBA backend plenty of time to propagate while failing fast on
        // genuine UI-side regressions.
        const url = this.page.url();
        for (let attempt = 0; attempt < maxRetries; attempt++) {
            try {
                await this.page.goto(url, { timeout: 30000 });
                await this.clickAuthorizations();
                for (const processId of processIds) {
                    await (0, test_1.expect)(this.page.getByRole('row', { name: processId })).toBeVisible({ timeout: perCheckTimeout });
                }
                return;
            }
            catch (error) {
                if (attempt < maxRetries - 1) {
                    console.warn(`Attempt ${attempt + 1} failed. Error: ${error}. Retrying...`);
                    await (0, sleep_1.sleep)(10000);
                }
                else {
                    throw new Error(`Assertion failed after ${maxRetries} attempts. Last error: ${error}`);
                }
            }
        }
    }
    async clickNewContextPadButton() {
        try {
            await (0, test_1.expect)(this.newContextPadButtonText).toHaveText('Enabled', {
                timeout: 90000,
            });
        }
        catch {
            await this.page.reload();
            await this.newContextPadButton.click({ timeout: 90000 });
            await (0, test_1.expect)(this.newContextPadButtonText).toHaveText('Enabled', {
                timeout: 60000,
            });
        }
    }
    async optInToAlphaFeatures() {
        await (0, expectLocatorWithRetry_1.expectLocatorWithRetry)(this.page, this.rows.first(), {
            visibilityTimeout: 60000,
            totalTimeout: 140000,
            postAction: async () => {
                await this.page.reload();
            },
        });
        try {
            await (0, test_1.expect)(this.optInButton).toBeVisible({ timeout: 30000 });
            await this.clickOptInButton();
            await this.scrollToOptInCheckbox();
            await this.checkOptInCheckbox();
        }
        catch {
            await (0, test_1.expect)(this.optInButton).not.toBeVisible();
        }
    }
    async clickGroupsTab() {
        for (let attempt = 0; attempt < 3; attempt++) {
            try {
                await this.groupsTab.click({ timeout: 60000 });
                return;
            }
            catch (error) {
                if (attempt < 2) {
                    console.warn(`clickGroupsTab attempt ${attempt + 1} failed. Retrying...`);
                    await (0, sleep_1.sleep)(5000);
                    await this.page.reload();
                }
                else {
                    throw error;
                }
            }
        }
    }
    async clickCreateGroupButton() {
        const maxRetries = 3;
        for (let retries = 0; retries < maxRetries; retries++) {
            try {
                if (!(await this.noGroupsHeading.isVisible({ timeout: 120000 }))) {
                    await this.createGroupButton.click();
                }
                else {
                    await this.createFirstGroupButton.click();
                }
                return;
            }
            catch (error) {
                console.error(`Click attempt ${retries + 1} failed`);
            }
        }
        throw new Error(`Failed to click the button after ${maxRetries} attempts.`);
    }
    async fillGroupNameInput(name) {
        await this.groupNameInput.fill(name);
    }
    async clickCreateGroupSubButton() {
        await this.createGroupSubButton.click();
    }
    async clickUserGroup(name) {
        await this.page.getByRole('cell', { name: name }).click();
    }
    async clickAssignMembers() {
        await this.assignMembersButton.click();
    }
    async fillAssignMembers(names) {
        for (const name of names) {
            await this.assignMembersSearchbox.click({ timeout: 90000 });
            await (0, sleep_1.sleep)(1000);
            await this.assignMembersSearchbox.fill(name);
            await this.assignMembersSearchResult
                .filter({ hasText: name })
                .click({ timeout: 120000 });
        }
    }
    async filterTable(names) {
        for (const name of names) {
            await (0, test_1.expect)(this.filterTableSearchbox).toBeVisible({ timeout: 120000 });
            await this.filterTableSearchbox.click({ timeout: 60000 });
            await this.filterTableSearchbox.fill(name);
            await this.page
                .waitForLoadState('networkidle', { timeout: 30000 })
                .catch(() => { });
            // Wait for at least one data row to appear after filtering
            await (0, test_1.expect)(this.rows.nth(1))
                .toBeVisible({ timeout: 30000 })
                .catch(() => { });
        }
    }
    async clickAssignSubButton() {
        await this.assignMembersSubButton.click();
    }
    async clickOrganizationManagementLink() {
        await this.organizationManagementLink.click();
    }
    async deleteAllGroups() {
        try {
            await this.deleteButton
                .first()
                .waitFor({ state: 'visible', timeout: 60000 });
            const count = await this.deleteButton.count();
            if (count > 0) {
                for (let i = 0; i < count; i++) {
                    await this.deleteButton.nth(i).click({ timeout: 60000 });
                    await this.deleteSubButton.click({ timeout: 60000 });
                }
            }
        }
        catch (error) {
            console.log('Delete Button Not Clicked ' + error);
        }
    }
}
exports.ConsoleOrganizationPage = ConsoleOrganizationPage;
