import { test } from '../../fixtures/index';
import { LoginPage } from '../../pom/login.page';
import { expect } from '@playwright/test';
import { takeScreenshot, verifyScreenshot } from '../../utils/screenshot';
import { DashboardPage } from '../../pom/dashboard.page';
import { Mail } from '../../pom/utils/mail.page';
import { extractVerificationCode } from '../../utils/mail';

test.describe('Login suite', async () => {
    let loginPage: LoginPage;
    

    test.beforeEach(async ({ page, request }) => {
        loginPage = new LoginPage(page);
        await loginPage.open();
    })

    test('AUTH_001 - Verify form login UI', {
        tag: ['@AUTH_001', '@authentication', '@login']
    }, async ({ conf }) => {
        // 1. Mở trang Login. 
        // 2. Kiểm tra icon con mắt hiển thị password
        // - Click icon con mắt

        // 3. Kiểm tra validation message
        // 3.1. Click login mà chưa fill thông tin đăng nhập
        // 3.2. Fill email không đúng định dạng
        // 3.3. Fill email đúng định dạng, không fill password
        // 3.4. Fill email, password đúng định dạng, sai thông tin

        // 4. Kiểm tra remember info dialog
        // - Click button info

        await test.step('Verify tổng quan UI trang login', async () => {
            await expect(loginPage.loginLoc.inputUsername).toBeFocused();
            await verifyScreenshot('login-ui.png', loginPage.loginLoc.mainContainer);

            // Fill login info  
            await loginPage.loginLoc.eyeIcon("Show").click();
            await expect(loginPage.loginLoc.inputPassword).toHaveAttribute('type', 'text');
            await loginPage.loginLoc.eyeIcon("Hide").click();
            await expect(loginPage.loginLoc.inputPassword).toHaveAttribute('type', 'password');

            // Verify các link
            await expect(loginPage.loginLoc.forgotPasswordLink).toBeVisible();
            await expect(loginPage.loginLoc.loginWithPasscodeLink).toBeVisible();
            await expect(loginPage.loginLoc.tosLink).toBeVisible();
            await expect(loginPage.loginLoc.privacyPolicyLink).toBeVisible();
            await expect(loginPage.loginLoc.baaLink).toBeVisible();
        });

        await test.step('Verify validation message', async () => {
            // 3.1. Click login mà chưa fill thông tin đăng nhập

            // 3.3. Fill email đúng định dạng, không fill password
            // 3.4. Fill email, password đúng định dạng, sai thông tin
            await loginPage.loginLoc.btnLogin.click();
            await expect(loginPage.loginLoc.emailError).toBeVisible();
            await expect(loginPage.loginLoc.passwordRequiredError).toBeVisible();

            // 3.2. Fill email không đúng định dạng
            await loginPage.loginLoc.inputUsername.fill(conf.data.wrong_email_format);
            await loginPage.loginLoc.btnLogin.click();
            await expect(loginPage.loginLoc.emailFormatError).toBeVisible();

            // 3.3. Fill email đúng định dạng, không fill password
            await loginPage.loginLoc.inputUsername.fill(conf.data.username);
            await loginPage.loginLoc.btnLogin.click();
            await expect(loginPage.loginLoc.passwordRequiredError).toBeVisible();

            // 3.4. Fill email, password đúng định dạng, sai thông tin
            await loginPage.loginLoc.inputPassword.fill(conf.data.wrong_password);
            await loginPage.loginLoc.btnLogin.click();
            await expect(loginPage.loginLoc.invalidCredentialError).toBeVisible();
        });

        await test.step('Verify remember info dialog', async () => {
            await loginPage.loginLoc.infoButton.click();
            await expect(loginPage.loginLoc.trustedBrowserDialog).toBeVisible();

            await verifyScreenshot('remember-info.png', loginPage.loginLoc.trustedBrowserDialog);
        });
    })


    test('AUTH_002 - Verify form login function', {
        tag: ['@AUTH_002', '@authentication', '@login']
    }, async ({ conf }) => {
        let dashboardPage: DashboardPage;
        // 1. Fill email, password đúng định dạng, đúng thông tin 
        await test.step('Verify form login function', async () => {
            dashboardPage = await loginPage.login(conf.data.username, conf.data.password, conf.data.remember);
            await expect(dashboardPage.baseLoc.dashboardContainer).toBeVisible();
        });
    })
});

test.describe('Login with passcode suite', async () => {
    let loginPage: LoginPage;
    let mail: Mail; 

    test.beforeEach(async ({ page, request }) => {
        loginPage = new LoginPage(page);
        mail = new Mail(page, request);
        await loginPage.open();
    })

    test('AUTH_005 - Verify form login with passcode UI', {
        tag: ['@AUTH_005', '@authentication', '@login']
    }, async ({ conf }) => {
        // 1. Click Login with passcode
        await test.step('Click Login with passcode', async () => {
            await loginPage.loginLoc.loginWithPasscodeLink.click();
            await expect(loginPage.loginLoc.headingLoginWithPasscode).toBeVisible();
        });

        // 2. Kiểm tra validation message
        // 2.1. Không fill thông tin
        await test.step('Verify validation message - empty', async () => {
            await loginPage.loginLoc.btnNext.click();
            await expect(loginPage.loginLoc.errorEnterEmail).toBeVisible();
        });

        // 2.2. Fill email không đúng định dạng
        await test.step('Verify validation message - email format', async () => {
            await loginPage.loginLoc.inputUsername.fill(conf.data.wrong_email_format);
            await loginPage.loginLoc.btnNext.click();
            await expect(loginPage.loginLoc.errorEnterEmailFormat).toBeVisible();
        });
        // 2.3. Fill email đúng định dạng, không tồn tại trong hệ thống
        await test.step('Verify validation message - email not found', async () => {
            await loginPage.loginLoc.inputUsername.fill(conf.data.email_not_exist);
            await loginPage.loginLoc.btnNext.click();
            await expect(loginPage.loginLoc.errorEmailNotFound).toBeVisible();
        });

        // 2.4. Fill email đúng định dạng, tồn tại trong hệ thống
        await test.step('Verify validation message - email found', async () => {
            await loginPage.loginLoc.inputUsername.fill(conf.data.username);
            await loginPage.loginLoc.btnNext.click();
            await expect(loginPage.loginLoc.messageEmailFound).toBeVisible();
        });
        
        // 2.5. Click Resend ngay khi chưa đủ 1 phút
        await test.step('Verify validation message - resend code', async () => {
            await loginPage.loginLoc.resendCode.click();
            await expect(loginPage.loginLoc.errorTryAgainLater).toBeVisible();
        });
    })

    test('AUTH_006 - Verify form login with passcode function', {
        tag: ['@AUTH_006', '@authentication', '@login']
    }, async ({ conf }) => {
        // 1. Nhập email, click forgot password, kiểm tra email
        // 2. Nhập sai verification code, click next
        // 3. Nhập đúng verification code, click next
        let passcode: string;
        await test.step('Verify form login with passcode function', async () => {
            await loginPage.loginLoc.loginWithPasscodeLink.click();
            await expect(loginPage.loginLoc.headingLoginWithPasscode).toBeVisible();
            await loginPage.loginLoc.inputUsername.fill(conf.data.username);
            await loginPage.loginLoc.btnNext.click();
            await expect(loginPage.loginLoc.messageEmailFound).toBeVisible();
            await loginPage.waitForSecond(conf.data.wait_for_email_second);

            const foundMail = await mail.findMail('your passcode for signing in to', conf.data.username);
            expect(foundMail).toBeTruthy();
            console.log(foundMail);
            passcode = extractVerificationCode(foundMail.Subject) || '';
            expect(passcode).toBeTruthy();
        });

        await test.step('Verify form login with passcode function - wrong passcode', async () => {
            await loginPage.loginLoc.inputToken.fill(conf.data.wrong_passcode);
            await loginPage.loginLoc.btnNext.click();
            await expect(loginPage.loginLoc.errorInvalidPasscode).toBeVisible();
        });

        await test.step('Verify form login with passcode function - correct passcode', async () => {
            await loginPage.loginLoc.inputToken.fill(passcode);
            await loginPage.loginLoc.btnNext.click();
            const dashboardPage = new DashboardPage(loginPage.page);
            await expect(dashboardPage.baseLoc.dashboardContainer).toBeVisible();
        });
    })
})