import { test, expect } from '../../fixtures/index';
import { LoginPage } from '../../pom/login.page';
import { ProfilePage } from '../../pom/profile/profile.page';
import { prepareFile, getFileDownloadedPathFromUrl } from '../../utils/file';
import { takeScreenshot, verifyScreenshot } from '../../utils/screenshot';

test.describe('UI profile 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_001 - Verify màn my profile UI', {
        tag: ['@PROFILE_001', '@profile', '@ui']
    }, async ({ conf }) => {

        await test.step('Click menu profile, verify các field', async () => {
            const avatarPromise = profilePage.page.waitForResponse(RegExp(`${profilePage.baseUrl}storage/images/avatar.*`));
            await profilePage.navigateToMenu('Profile');
            await expect(profilePage.profileLoc.title).toBeVisible();

            // Wait avatar loaded
            await avatarPromise;

            // Verify screenshot
            await verifyScreenshot('profile.png', profilePage.profileLoc.mainContainer, [profilePage.profileLoc.inputEmail]);
            await expect(profilePage.profileLoc.inputEmail).toBeDisabled();
            await expect(profilePage.profileLoc.inputEmail).toHaveValue(conf.data.username);
        });

        await test.step('Xoá first name và last name, bấm save', async () => {
            await profilePage.profileLoc.firstNameInput.clear();
            await profilePage.profileLoc.lastNameInput.clear();
            await profilePage.profileLoc.saveButton.click();
            await verifyScreenshot('validation.png', profilePage.profileLoc.mainContainer, [profilePage.profileLoc.inputEmail]);
        });
    });
});

test.describe('Function profile 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();

        await profilePage.open();
    });

    test('PROFILE_002 - Verify upload avatar', {
        tag: ['@PROFILE_002', '@profile', '@ui']
    }, async ({ conf }) => {
        await prepareFile(conf.data.avatar)
        await prepareFile(conf.data.wrong_file)
        await prepareFile(conf.data.big_file)

        await test.step('Upload with wrong file type', async () => {
            await profilePage.profileLoc.inputAvatar.setInputFiles([getFileDownloadedPathFromUrl(conf.data.wrong_file)]);
            await expect(profilePage.profileLoc.avatarErrorMessage).toBeVisible();
            await expect(profilePage.profileLoc.avatarErrorMessage).toContainText('The avatar field must be an image.');
            // await expect(profilePage.profileLoc.avatarErrorMessage).toContainText('The avatar field must be a file of type: jpeg, png, jpg, webp.');
        });

        await test.step('Upload with big file', async () => {
            await profilePage.profileLoc.inputAvatar.setInputFiles([getFileDownloadedPathFromUrl(conf.data.big_file)]);
            await expect(profilePage.profileLoc.avatarErrorMessage).toBeVisible();
            await expect(profilePage.profileLoc.avatarErrorMessage).toContainText('The avatar field must not be greater than 10240 kilobytes.', {
                timeout: 30_000,
            });
        });

        await test.step('Upload with correct file', async () => {
            const avatarPromise = profilePage.page.waitForResponse(RegExp(`${profilePage.baseUrl}storage/images/avatar.*`), { timeout: 10000 });
            await profilePage.profileLoc.inputAvatar.setInputFiles([getFileDownloadedPathFromUrl(conf.data.avatar)]);
            await avatarPromise;
            await verifyScreenshot('avatar.png', profilePage.profileLoc.userProfileAvatar);
        });
    });


    test('PROFILE_003 - Verify màn my profile function', {
        tag: ['@PROFILE_003', '@profile', '@function']
    }, async ({ conf }) => {
        test.slow();

        await test.step('Bấm save, save thành công', async () => {
            await profilePage.waitForSecond(2); // TODO: page need stable. fix me later
            await profilePage.profileLoc.saveButton.click();
            await expect(profilePage.baseLoc.updateSuccessNotification).toBeVisible();
            await profilePage.baseLoc.closeNotification.click({ force: true, clickCount: 2 });
            await expect(profilePage.baseLoc.updateSuccessNotification).toBeHidden();
        });

        await test.step('Fill lần lượt các field, verify lưu thành công', async () => {
            // Phone number
            await profilePage.waitForSecond(2);
            await profilePage.profileLoc.inputPhone.fill(conf.data.phone);
            await profilePage.profileLoc.saveButton.click();
            await expect(profilePage.baseLoc.updateSuccessNotification).toBeVisible();
            await profilePage.baseLoc.closeNotification.click({ force: true, clickCount: 2 });
            await expect(profilePage.baseLoc.updateSuccessNotification).toBeHidden();

            // Address
            await profilePage.waitForSecond(2);
            await profilePage.profileLoc.inputAddress.fill(conf.data.address);
            await profilePage.profileLoc.saveButton.click();
            await expect(profilePage.baseLoc.updateSuccessNotification).toBeVisible();
            await profilePage.baseLoc.closeNotification.click({ force: true, clickCount: 2 });
            await expect(profilePage.baseLoc.updateSuccessNotification).toBeHidden();

            // Suite
            await profilePage.waitForSecond(2);
            await profilePage.profileLoc.inputSuite.fill(conf.data.suite);
            await profilePage.profileLoc.saveButton.click();
            await expect(profilePage.baseLoc.updateSuccessNotification).toBeVisible();
            await profilePage.baseLoc.closeNotification.click({ force: true, clickCount: 2 });
            await expect(profilePage.baseLoc.updateSuccessNotification).toBeHidden();

            // City
            await profilePage.waitForSecond(2);
            await profilePage.profileLoc.inputCity.fill(conf.data.city);
            await profilePage.profileLoc.saveButton.click();
            await expect(profilePage.baseLoc.updateSuccessNotification).toBeVisible();
            await profilePage.baseLoc.closeNotification.click({ force: true, clickCount: 2 });
            await expect(profilePage.baseLoc.updateSuccessNotification).toBeHidden();

            // State
            await profilePage.waitForSecond(2);
            await profilePage.profileLoc.customSelectState.click();
            await profilePage.page.keyboard.type(conf.data.state);
            await profilePage.page.keyboard.press('Enter');
            await profilePage.profileLoc.saveButton.click();
            await expect(profilePage.baseLoc.updateSuccessNotification).toBeVisible();
            await profilePage.baseLoc.closeNotification.click({ force: true, clickCount: 2 });
            await expect(profilePage.baseLoc.updateSuccessNotification).toBeHidden();

            // Zip/postal code
            await profilePage.waitForSecond(2);
            await profilePage.profileLoc.inputZip.fill(conf.data.zip);
            await profilePage.profileLoc.saveButton.click();
            await expect(profilePage.baseLoc.updateSuccessNotification).toBeVisible();
            await profilePage.baseLoc.closeNotification.click({ force: true, clickCount: 2 });
            await expect(profilePage.baseLoc.updateSuccessNotification).toBeHidden();

            await verifyScreenshot('profile_updated.png', profilePage.profileLoc.mainContainer, [profilePage.profileLoc.inputEmail])
        });

        await test.step('Reset data các field', async () => {
            await profilePage.waitForSecond(2);
            await profilePage.profileLoc.inputPhone.click();
            await profilePage.page.keyboard.press('ControlOrMeta+A');
            await profilePage.page.keyboard.press('Backspace');
            await profilePage.profileLoc.inputAddress.clear();
            await profilePage.profileLoc.inputSuite.clear();
            await profilePage.profileLoc.inputCity.clear();
            await profilePage.profileLoc.optionState.evaluate(option => option.setAttribute('value', ''));
            await profilePage.profileLoc.inputZip.clear();
            await profilePage.profileLoc.saveButton.click();
            await expect(profilePage.baseLoc.updateSuccessNotification).toBeVisible();
            await profilePage.waitForSecond(2);
            await profilePage.baseLoc.closeNotification.click({ force: true, clickCount: 2 });
            await expect(profilePage.baseLoc.updateSuccessNotification).toBeHidden();

            await verifyScreenshot('profile_reset.png', profilePage.profileLoc.mainContainer, [profilePage.profileLoc.inputEmail])
        });
    });
});