import { test, expect } from '../../fixtures/index';
import { LoginPage } from '../../pom/login.page';
import { ProfilePage } from '../../pom/profile/profile.page';
import { takeScreenshot, verifyScreenshot } from '../../utils/screenshot';
import { authenticator } from 'otplib'
import * as fs from 'fs';

test.describe('UI two factor tests', async () => {
    let loginPage: LoginPage;
    let profilePage: ProfilePage;

    test.beforeEach(async ({ page, conf }) => {
        loginPage = new LoginPage(page);
        profilePage = new ProfilePage(page);

        await loginPage.open();
        await loginPage.login(conf.data.username, conf.data.password);
        await expect(loginPage.baseLoc.dashboardContainer).toBeVisible();
    });

    test('PROFILE_006 - Verify màn two-factor UI', {
        tag: ['@PROFILE_006', '@profile', '@ui']
    }, async ({ conf }) => {
        // 1. Click sang menu "Two-factor authentication"
        await test.step('Click sang menu "Two-factor authentication"', async () => {
            await profilePage.navigateToMenu("Profile");
            await profilePage.profileLoc.twoFactorMenu.click();
            await expect(profilePage.profileLoc.title).toContainText('Two-factor Authentication');
        });

        await test.step('Verify màn two-factor UI khi chưa setup MFA', async () => {
            await verifyScreenshot('two-factor-not-setup.png', profilePage.profileLoc.mainContainer);
        });

        await test.step('Verify màn two-factor UI khi đang setup MFA', async () => {
            await profilePage.profileLoc.setup2FaButton.click();
            await expect(profilePage.page).toHaveURL(/.*\?tab=2fa&action=setup/);
            await verifyScreenshot('two-factor-setting-up.png', profilePage.profileLoc.mainContainer,
                [
                    profilePage.profileLoc.twoFactorSetupQR,
                    profilePage.profileLoc.mfaSecretInput
                ]
            );

            await expect(profilePage.profileLoc.mfaSecretInput).not.toBeEmpty();
        });
    });
});

test.describe('Function two factor tests', async () => {
    let loginPage: LoginPage;
    let profilePage: ProfilePage;
    test.beforeEach(async ({ page, conf }, testInfo) => {
        loginPage = new LoginPage(page);
        profilePage = new ProfilePage(page);

        await loginPage.open();
        await loginPage.login(conf.data.username, conf.data.password);
        if (testInfo.title !== "Verify màn two-factor function") {
            await expect(loginPage.baseLoc.dashboardContainer).toBeVisible();
        }
        await profilePage.openTwoFactorSetup();
    });

    //Skip tạm thời để check vs client
    test('PROFILE_007 - Verify màn two-factor function', {
        tag: ['@PROFILE_007', '@profile', '@function']
    }, async ({ conf }) => {
        // 1. Thực hiện điền authentication code
        // 2. Logout ra và login lại
        // 3. Điền code sai
        // 4. Điền code đúng
        let secret: string;
        await test.step('Thực hiện điền authentication code', async () => {
            secret = await profilePage.profileLoc.mfaSecretInput.inputValue();
            console.log('Scret value: ');
            console.log(secret);
            const code = authenticator.generate(secret);
            // Write secret to file (append new line)
            fs.appendFileSync('two-factor-secret.txt', `${secret}\n`);

            // Split code into 6 digits
            const digits = code.split('');
            for (let i = 0; i < 6; i++) {
                await profilePage.profileLoc.digitInput(i + 1).press(digits[i], {
                    delay: 200,
                });
            }
            await profilePage.profileLoc.submitButton.click();
            await profilePage.waitAllRequestCompeleted();
        });

        await test.step('Logout ra và login lại', async () => {
            await profilePage.logout();
            await loginPage.open();
            await loginPage.login(conf.data.username, conf.data.password);
            await expect(loginPage.page).toHaveURL(/2fa-verification/)
            await expect(loginPage.loginLoc.twoFaLoginHeading).toBeVisible();

            const code = authenticator.generate(secret);
            // Split code into 6 digits
            const digits = code.split('');
            for (let i = 0; i < 6; i++) {
                await loginPage.loginLoc.digitInput(i + 1).press(digits[i], {
                    delay: 200,
                });
            }
            await loginPage.loginLoc.confirmButton.click();
            await profilePage.waitAllRequestCompeleted();
            await expect(loginPage.baseLoc.dashboardContainer).toBeVisible();
        });

        await test.step('Remove 2FA code và login lại', async () => {
            await profilePage.openTwoFactorDisable();
            await expect(profilePage.page).toHaveURL(/.*\?tab=2fa&action=disable/);

            const code = authenticator.generate(secret);
            // Split code into 6 digits
            const digits = code.split('');
            for (let i = 0; i < 6; i++) {
                await profilePage.profileLoc.digitInput(i + 1).press(digits[i], {
                    delay: 200,
                });
            }
            await profilePage.profileLoc.confirmButton.click();
            await profilePage.waitAllRequestCompeleted();
            await expect(profilePage.profileLoc.setup2FaButton).toBeVisible();

            await profilePage.logout();
            await loginPage.open();
            await loginPage.login(conf.data.username, conf.data.password);
            await expect(loginPage.baseLoc.dashboardContainer).toBeVisible();
        });
    });
});