import { test, expect } from '../../fixtures/index';
import { Mail } from '../../pom/utils/mail.page';
import { ForgotPage } from '../../pom/authentication/forgot.page';
import { extractVerificationCode } from '../../utils/mail';
import { LoginPage } from '../../pom/login.page';
import { takeScreenshot } from '../../utils/screenshot';

test.describe('Forgot password suite', {
    annotation: {
        type: 'suite_name',
        description: 'Forgot password suite'
    }
}, async () => {
    let mail: Mail;
    let forgotPage: ForgotPage;
    let loginPage: LoginPage;
    test.beforeEach(async ({ page, request }) => {
        mail = new Mail(page, request);
        loginPage = new LoginPage(page);
    });

    test('AUTH_003 - Verify forgot password UI',        
        {
            tag: ['@AUTH_003', '@authentication', '@forgot']
        },
        // 1. Click forgot password
        // 2. Kiểm tra validation message
        // 2.1. Không fill thông tin
        // 2.2. Fill email không đúng định dạng
        // 2.3. Fill email đúng định dạng, không tồn tại trong hệ thống
        // 2.4. Fill email đúng định dạng, tồn tại trong hệ thống
        // 2.5. Click Resend ngay khi chưa đủ 1 phút

        async ({ page, request, conf }) => {
            await test.step('Click forgot password', async () => {
                await loginPage.open();
                forgotPage = await loginPage.clickForgotPassword();
                await expect(forgotPage.forgotLoc.inputEmail).toBeVisible();

                await takeScreenshot('forgot-ui.png', forgotPage.forgotLoc.mainContainer)
            });

            await test.step('Verify validation message', async () => {
                await forgotPage.fillEmail('');
                await forgotPage.submit();
                await expect(forgotPage.forgotLoc.errorMissingEmail).toBeVisible();

                await forgotPage.fillEmail(conf.data.wrong_email);
                await forgotPage.submit();
                await expect(forgotPage.forgotLoc.errorInvalidEmail).toBeVisible();

                await forgotPage.fillEmail(conf.data.email_not_exist);
                await forgotPage.submit();
                await expect(forgotPage.forgotLoc.errorEmailNotFound).toBeVisible();
            });

        }
    );

    test('AUTH_004 - Verify forgot password function',
        {
            tag: ['@AUTH_004', '@authentication', '@forgot']
        },
        // 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
        // 4. Nhập password mới.
        // 5. Đăng nhập với password mới
        // 6. Kiểm tra email báo password đã được thay đổi
        async ({ page, conf }) => {
            test.slow();
            let verificationCode = '';
            forgotPage = new ForgotPage(page);
            await forgotPage.open();

            await test.step('Fill email, click forgot password. Verify email received', async () => {
                await forgotPage.fillAndSubmit(conf.data.email);
                await forgotPage.waitForSecond(conf.data.wait_for_email_second); // Wait for new mail
                const foundMail = await mail.findMail('your recovery code for the', conf.data.email);
                expect(foundMail).toBeTruthy();
                console.log(foundMail);
                verificationCode = extractVerificationCode(foundMail.Subject) || '';
                expect(verificationCode).toBeTruthy();
            });

            await test.step('Fill invalid verification code. Verify error message', async () => {
                await forgotPage.fillVerificationCode(conf.data.wrong_verification_code);
                await forgotPage.submit();
                await expect(forgotPage.forgotLoc.verificationMsg).toBeVisible();
            });

            await test.step('Fill valid verification code. Verify change success', async () => {
                await forgotPage.fillVerificationCode(verificationCode);
                await forgotPage.submit();
                await expect(forgotPage.forgotLoc.headingCreateNewPassword).toBeVisible();
            });

            await test.step('Fill new password. Verify change success', async () => {
                await forgotPage.fillNewPassword(conf.data.new_password);
                await forgotPage.submit();
                await expect(forgotPage.forgotLoc.createPasswordSuccessMsg).toBeVisible();
            });

            await test.step('Logout and login with new password', async () => {
                await loginPage.login(conf.data.email, conf.data.new_password);
                await expect(loginPage.baseLoc.dashboardContainer).toBeVisible();
            });

            await test.step('Verify email received', async () => {
                await forgotPage.waitForSecond(conf.data.wait_for_email_second); // Wait for new mail
                const foundMail = await mail.findMail('Password Reset for', conf.data.email);
                expect(foundMail).toBeTruthy();
                console.log(foundMail);
            });
        }
    );
});