"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.IdentityTenantPage = void 0;
const test_1 = require("@playwright/test");
const sleep_1 = require("../../utils/sleep");
const expectLocatorWithPagination_1 = require("../../utils/assertionHelpers/expectLocatorWithPagination");
const clickLocatorWithRetry_1 = require("../../utils/assertionHelpers/clickLocatorWithRetry");
class IdentityTenantPage {
    page;
    createTenantMainButton;
    enterTenantNameInput;
    enterTenantIdInput;
    createTenantSubButton;
    assignedUsersTab;
    assignUsersButton;
    searchUsersInput;
    assignUserFinalButton;
    removeUserButton;
    removeButton;
    openSidebarButton;
    logoutButton;
    assignedApplicationsTab;
    searchApplicationsInput;
    assignApplicationsButtonFinal;
    assignApplicationsButton;
    modalCloseButton;
    cancelButton;
    dialog;
    row;
    usersTab;
    constructor(page) {
        this.page = page;
        this.createTenantMainButton = page.getByRole('button', {
            name: 'Create Tenant',
        });
        this.usersTab = page.getByRole('tab', { name: 'Users' });
        this.enterTenantNameInput = page.getByPlaceholder('Enter tenant name');
        this.enterTenantIdInput = page.getByPlaceholder('Enter tenant ID');
        this.createTenantSubButton = page.getByRole('button', {
            name: 'Create tenant',
            exact: true,
        });
        this.assignedUsersTab = page.getByRole('tab', { name: 'Assigned users' });
        this.assignUsersButton = page.getByRole('button', { name: 'Assign users' });
        this.searchUsersInput = page.getByPlaceholder('Search users');
        this.assignUserFinalButton = page
            .getByRole('dialog', { name: 'Assign users' })
            .getByRole('button', { name: 'Assign users' });
        this.removeUserButton = page.getByLabel('Remove user');
        this.removeButton = page.getByRole('button', { name: 'danger Remove' });
        this.openSidebarButton = page.getByLabel('Open User Sidebar');
        this.logoutButton = page.getByRole('button', { name: 'Log out' });
        this.assignedApplicationsTab = page.getByRole('tab', {
            name: 'Assigned applications',
        });
        this.searchApplicationsInput = page.getByPlaceholder('Search applications');
        this.assignApplicationsButtonFinal = page
            .getByLabel('Assign applications')
            .getByRole('button', { name: 'Assign applications' });
        this.assignApplicationsButton = page.getByRole('button', {
            name: 'Assign applications',
        });
        this.modalCloseButton = page
            .getByRole('dialog')
            .getByRole('button', { name: 'Close' });
        this.cancelButton = page
            .getByRole('dialog')
            .getByRole('button', { name: 'Cancel' });
        this.dialog = page.getByRole('dialog');
        this.row = (name) => this.page.getByRole('row').filter({ hasText: name }).first();
    }
    async clickCreateTenantMainButton() {
        await (0, test_1.expect)(this.createTenantMainButton).toBeVisible({ timeout: 60000 });
        await this.createTenantMainButton.click({ timeout: 60000 });
    }
    async clickCreateTenantSubButton() {
        await (0, test_1.expect)(this.createTenantSubButton).toBeVisible({ timeout: 60000 });
        await this.createTenantSubButton.click({ timeout: 60000 });
    }
    async clickEnterTenantNameInput() {
        await (0, test_1.expect)(this.enterTenantNameInput).toBeVisible({ timeout: 60000 });
        await this.enterTenantNameInput.click();
    }
    async fillEnterTenantNameInput(tenantName) {
        await this.enterTenantNameInput.fill(tenantName);
    }
    async clickEnterTenantIdInput() {
        await (0, test_1.expect)(this.enterTenantIdInput).toBeVisible({ timeout: 60000 });
        await this.enterTenantIdInput.click();
    }
    async fillEnterTenantIdInput(tenantId) {
        await this.enterTenantIdInput.fill(tenantId);
    }
    async clickAssignedUsersTab() {
        await (0, clickLocatorWithRetry_1.clickLocatorWithRetry)(this.page, this.assignedUsersTab, {
            postAction: async () => {
                await this.page.reload();
            },
        });
    }
    async clickAssignUsersButton() {
        await (0, test_1.expect)(this.assignUsersButton).toBeVisible({ timeout: 60000 });
        await this.assignUsersButton.click();
    }
    async clickSearchUsersInput() {
        await this.searchUsersInput.click();
    }
    async fillSearchUsersInput(user) {
        await this.searchUsersInput.fill(user);
    }
    async clickAssignUserFinalButton() {
        await (0, test_1.expect)(this.assignUserFinalButton).toBeVisible({ timeout: 60000 });
        await this.assignUserFinalButton.click();
        const successToast = this.page.getByText('Users assigned', { exact: true });
        const errorToast = this.page.getByText('An error occurred');
        const alreadyExists = this.page.getByText('ALREADY_EXISTS');
        await (0, test_1.expect)(successToast.or(errorToast).or(alreadyExists)).toBeVisible({
            timeout: 30000,
        });
        if (await alreadyExists.isVisible()) {
            console.log('User already assigned to tenant');
            await this.cancelButton.click();
            await (0, test_1.expect)(this.dialog).not.toBeVisible({ timeout: 15000 });
            return;
        }
        if (await errorToast.isVisible()) {
            await this.cancelButton.click().catch(() => { });
            await (0, test_1.expect)(this.dialog)
                .not.toBeVisible({ timeout: 15000 })
                .catch(() => { });
            throw new Error('Identity API returned "An error occurred" when assigning user to tenant');
        }
        // success: "Users assigned" toast visible
    }
    async clickRemoveUserButton() {
        await this.removeUserButton.click();
    }
    async clickRemoveButton() {
        await this.removeButton.click();
    }
    async createTenant(tenantName) {
        if (await this.isRowVisible(tenantName)) {
            return;
        }
        await this.clickCreateTenantMainButton();
        await this.clickEnterTenantNameInput();
        await this.fillEnterTenantNameInput(tenantName);
        await this.clickEnterTenantIdInput();
        await this.fillEnterTenantIdInput(tenantName);
        await this.clickCreateTenantSubButton();
        await (0, test_1.expect)(this.page.getByText('Tenant created')).toBeVisible({
            timeout: 60000,
        });
        await (0, sleep_1.sleep)(30000);
    }
    async clickTenant(tenantName) {
        const maxRetries = 5;
        for (let attempt = 1; attempt <= maxRetries; attempt++) {
            try {
                await this.page.waitForLoadState('domcontentloaded').catch(() => { });
                const tenantRow = this.row(tenantName);
                await (0, expectLocatorWithPagination_1.expectLocatorWithPagination)(this.page, tenantRow);
                await tenantRow.locator('td').first().click({ timeout: 30000 });
                await this.usersTab.waitFor({ state: 'visible', timeout: 30000 });
                return;
            }
            catch (error) {
                console.warn(`Attempt ${attempt} to click tenant '${tenantName}' failed. Retrying...`, error);
                if (attempt === maxRetries) {
                    throw new Error(`Failed to click tenant '${tenantName}' after ${maxRetries} attempts.`);
                }
                await this.page.reload({ timeout: 30000 }).catch(() => { });
                await (0, sleep_1.sleep)(3000);
            }
        }
    }
    async isRowVisible(name) {
        await (0, sleep_1.sleep)(1000);
        if (await this.row(name).isVisible()) {
            console.log(`Row ${name} already exists.`);
            return true;
        }
        return false;
    }
    async assignUserToTenant(tenantName, user, userEmail) {
        const MAX_ATTEMPTS = 3;
        for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {
            await (0, sleep_1.sleep)(attempt === 1 ? 1000 : 10000);
            await this.clickTenant(tenantName);
            await this.clickAssignedUsersTab();
            if (await this.isRowVisible(userEmail)) {
                return;
            }
            try {
                await this.clickAssignUsersButton();
                await this.clickSearchUsersInput();
                await this.fillSearchUsersInput(user);
                await (0, test_1.expect)(this.page.getByText(userEmail)).toBeVisible({
                    timeout: 30000,
                });
                await this.page.getByText(userEmail).click({ timeout: 30000 });
                await this.clickAssignUserFinalButton();
                return;
            }
            catch (e) {
                console.log(`Attempt ${attempt} to assign user '${user}' to tenant '${tenantName}' failed: ${e}.`);
                if (attempt >= MAX_ATTEMPTS) {
                    throw new Error(`Failed to assign user '${user}' to tenant '${tenantName}' after ${MAX_ATTEMPTS} attempts: ${e}`);
                }
                await this.page.reload({ timeout: 30000 }).catch(() => { });
                await (0, sleep_1.sleep)(5000);
            }
        }
    }
    async removeUserFromTenant(tenantName) {
        await this.page.getByText(tenantName).first().click();
        await this.clickAssignedUsersTab();
        await this.clickRemoveUserButton();
        await this.clickRemoveButton();
        await (0, test_1.expect)(this.page.getByText('users.Entity removed')).toBeVisible({
            timeout: 60000,
        });
    }
    async clickOpenSidebarButton() {
        await this.openSidebarButton.click({ timeout: 60000 });
    }
    async clickLogoutButton() {
        await this.logoutButton.click({ timeout: 60000 });
    }
    async assignClientToTenant(clientName) {
        await this.clickAssignedApplicationsTab();
        await (0, sleep_1.sleep)(3000);
        if (await this.isRowVisible(clientName)) {
            return;
        }
        await this.clickAssignApplicationsButton();
        await this.clickSearchApplicationsInput();
        await this.fillSearchApplicationsInput(clientName);
        await (0, test_1.expect)(this.page.getByText(clientName, { exact: true })).toBeVisible({
            timeout: 15000,
        });
        await this.page.getByText(clientName, { exact: true }).click();
        await this.clickAssignApplicationsFinalButton();
        await (0, test_1.expect)(this.page.getByText('Applications assigned').first()).toBeVisible({
            timeout: 60000,
        });
    }
    async clickAssignedApplicationsTab() {
        await this.assignedApplicationsTab.click({ timeout: 60000 });
    }
    async clickSearchApplicationsInput() {
        await this.searchApplicationsInput.click({ timeout: 60000 });
    }
    async fillSearchApplicationsInput(clientName) {
        await this.searchApplicationsInput.fill(clientName);
    }
    async clickAssignApplicationsFinalButton() {
        await this.assignApplicationsButtonFinal.click({ timeout: 60000 });
    }
    async clickAssignApplicationsButton() {
        await this.assignApplicationsButton.click({ timeout: 60000 });
    }
}
exports.IdentityTenantPage = IdentityTenantPage;
