import { test, expect } from "../../../fixtures/index";
import { ContactPage } from "../../../pom/contact/contact.page";
import { LoginPage } from "../../../pom/login.page";
import { RequestPage } from "../../../pom/request/request.page";

test.describe("Features for contact tests", async () => {
    let loginPage: LoginPage;
    let contactPage: ContactPage;

    test.beforeEach(async ({ page, conf }) => {
        loginPage = new LoginPage(page);
        contactPage = new ContactPage(page);
        contactPage.loadBusinessNames(
            conf.data.business_singular,
            conf.data.business_plural
        );

        await test.step("Navigate to login page", async () => {
            await loginPage.open();
            await page.waitForLoadState('networkidle');
        });

        await test.step("Perform login authentication", async () => {
            await loginPage.login(conf.data.username, conf.data.password);
            await expect(loginPage.baseLoc.dashboardContainer).toBeVisible({ timeout: 15_000 });
        });

        if (conf.data.not_redirect) {
            return;
        }

        await test.step("Navigate to contact page", async () => {
            await contactPage.open();
            await page.waitForLoadState('networkidle');
        });
    });

    test("CONTACT_007 - Verify contact pin/unpin functionality", {
        tag: ["@CONTACT_007", "@contact", "@function"]
    }, async ({ conf }) => {
        const contactName = conf.data.contact_exist;

        await test.step("Search for existing contact", async () => {
            await contactPage.contactLoc.searchInput.fill(contactName);
            await expect(contactPage.contactLoc.searchInput).toHaveValue(contactName);
            await expect(contactPage.contactLoc.nameInrow(contactName).first()).toBeVisible();
        });

        await test.step("Pin contact and verify pinned state", async () => {
            await contactPage.waitForSecond(1);

            const pinButton = contactPage.contactLoc.btnPin.first();
            await expect(pinButton).toBeVisible();
            await pinButton.click();

            await expect(contactPage.contactLoc.btnUnPin.first()).toBeVisible({ timeout: 5_000 });
            await expect(contactPage.contactLoc.singleBoxContactPin(contactName)).toBeVisible();
        });

        await test.step("Unpin contact and verify unpinned state", async () => {
            const unpinButton = contactPage.contactLoc.btnUnPin.first();
            await expect(unpinButton).toBeVisible();
            await unpinButton.click();

            await expect(contactPage.contactLoc.btnPin.first()).toBeVisible({ timeout: 5_000 });
            await expect(contactPage.contactLoc.singleBoxContactPin(contactName)).not.toBeVisible();
        });
    });

    test("CONTACT_009 - Verify contact archive and unarchive functionality", {
        tag: ["@CONTACT_009", "@contact", "@function"],
    }, async ({ conf, updateContactPage }) => {
        const contactName = conf.data.contact_exist;

        await test.step("Archive contact and verify archived state", async () => {
            await updateContactPage.dashboardLoc.modal.button.archive.click();
            await updateContactPage.dashboardLoc.modal.button.acceptArchive.click();

            await expect(updateContactPage.contactLoc.updating.msgArchiveSucess).toBeVisible({ timeout: 10_000 });
            await expect(updateContactPage.dashboardLoc.modal.headerModal("Contact Detail")).not.toBeVisible();
            await expect(updateContactPage.contactLoc.updating.headerWarningContact).toBeVisible();

            await updateContactPage.dashboardLoc.btnClosePopupNotification.click();
            await updateContactPage.dashboardLoc.detail.button.back.click();
            await updateContactPage.waitForSecond(2);
            await expect(updateContactPage.dashboardLoc.table.noResult.first()).toBeVisible();
        });

        await test.step("Navigate to archived contacts and verify contact exists", async () => {
            await updateContactPage.dashboardLoc.table.btnThreeDot.click();
            await updateContactPage.contactLoc.btnShowArchiveContact.click();
            await expect(updateContactPage.contactLoc.updating.contactAlreadyExits(contactName).first()).toBeVisible({ timeout: 5_000 });
        });

        await test.step("Unarchive contact and verify restored state", async () => {
            await updateContactPage.contactLoc.updating.contactAlreadyExits(contactName).first().click();
            await updateContactPage.dashboardLoc.buttonUpdate.click();
            await expect(updateContactPage.dashboardLoc.modal.headerModal("Contact Detail")).toBeVisible();

            await updateContactPage.dashboardLoc.modal.button.unArchive.click();
            await expect(updateContactPage.contactLoc.updating.msgUnArchiveSucess).toBeVisible({ timeout: 1_000 });
            await expect(updateContactPage.dashboardLoc.modal.headerModal("Contact Detail")).not.toBeVisible();
            await expect(updateContactPage.contactLoc.updating.headerWarningContact).not.toBeVisible();

            await updateContactPage.dashboardLoc.btnClosePopupNotification.click();
            await updateContactPage.dashboardLoc.detail.button.back.click();
            await updateContactPage.waitForSecond(2);
            await expect(updateContactPage.dashboardLoc.table.noResult.first()).toBeVisible();
        });
    });

    test("CONTACT_022 - Verify contact group email count filtering", {
        tag: ["@CONTACT_022", "@contact", "@validate"]
    }, async ({ conf }) => {
        const contactGroupName = conf.data.contact_group;

        await test.step("Navigate to Contact Group page and search", async () => {
            await contactPage.dashboardLoc.buttonByText("Contact Group").click();
            await expect(contactPage.contactLoc.contactGroup.heading("Contact Groups")).toBeVisible();

            await contactPage.search(contactGroupName);
            await expect(contactPage.dashboardLoc.table.itemInRow(contactGroupName).first()).toBeVisible();
        });

        await test.step("Verify total email count matches contact list", async () => {
            const totalEmailElement = contactPage.contactLoc.contactGroup.totalEmail;
            await expect(totalEmailElement).toBeVisible();
            const totalEmailText = await totalEmailElement.textContent();
            const totalEmailCount = parseInt(totalEmailText?.trim() || "0");

            await totalEmailElement.click();
            await expect(contactPage.contactLoc.contactGroup.heading("Contacts")).toBeVisible();

            const contactData = await contactPage.getDataTable();
            const prescriptionContactsCount = contactData.filter(item =>
                item.includes("Prescription")
            ).length;

            expect(totalEmailCount).toBe(prescriptionContactsCount);
        });
    });

    test("CONTACT_024 - Verify suggested contact modal workflow", {
        tag: ["@CONTACT_024", "@contact", "@function"]
    }, async ({ page, conf }) => {
        const contactPageInstance = new ContactPage(page);
        let requestPage: RequestPage;
        const uniqueEmail = await contactPageInstance.getRanmdomEmail(conf.data.email);
        const caseId = conf.data.case;

        await test.step("Share request with new contact not in system", async () => {
            requestPage = new RequestPage(contactPageInstance.page);
            await requestPage.open();
            await requestPage.getDetailCase(caseId);
            await expect(requestPage.dashboardLoc.buttonByText("Share")).toBeVisible();
            await requestPage.waitForSecond(1);
            await requestPage.dashboardLoc.buttonByText("Share").click();
            await expect(requestPage.dashboardLoc.modal.headerModal("Share with others")).toBeVisible();

            const emailInput = requestPage.requestLoc.create.inputByPlaceholder("Type or select an email address").first();
            await emailInput.type(uniqueEmail, { delay: 100 });

            const newContactDropdown = requestPage.requestLoc.create.dropdownMemberShareNew(uniqueEmail);
            await expect(newContactDropdown).toBeVisible();
            await newContactDropdown.click();

            await requestPage.dashboardLoc.buttonByText("Done").first().click();
        });

        await test.step("Verify suggested contact modal appears", async () => {
            const contactPageForModal = new ContactPage(requestPage.page);
            await contactPageForModal.open();

            await expect(contactPageForModal.dashboardLoc.modal.headerModal("Suggested Contacts")).toBeVisible();
            await expect(contactPageForModal.dashboardLoc.common.spanText(uniqueEmail)).toBeVisible();
        });

        await test.step("Add suggested contact and verify in contact list", async () => {
            const contactPageForVerification = new ContactPage(requestPage.page);

            await contactPageForVerification.dashboardLoc.buttonByText("Save").first().click();
            await contactPageForVerification.search(uniqueEmail);
            await expect(contactPageForVerification.contactLoc.nameInrow(uniqueEmail).first()).toBeVisible();
        });
    });

    test("CONTACT_025 - Verify add tag in contact's detail", {
        tag: ["@CONTACT_025", "@contact", "@validate"]
    }, async ({ conf }) => {
        await test.step("Navigate to contact detail", async () => {
            await contactPage.getDetailCase(conf.data.email_already_exist);
        });

        await test.step("Verify add tags with tag count greater than 9 (invalid)", async () => {
            await contactPage.addMultipleTags(10);
            await contactPage.saveTags();
            await expect(contactPage.dashboardLoc.tag.errorMaxTag).toBeVisible();
        });

        await test.step("Verify when add < 9 tag (valid)", async () => {
            await contactPage.removeOneTag();
            await contactPage.saveTags();
            await expect(contactPage.dashboardLoc.msgSuccess.first()).toBeVisible();
            await contactPage.dashboardLoc.btnClosePopupNotification.click();
            await expect(contactPage.dashboardLoc.tag.btnSaveTag).not.toBeVisible();

            const tagCount = await contactPage.getTagCount();
            expect(tagCount).toBe(9);
        });

        await test.step("Clear all tag", async () => {
            await contactPage.clearAllTags();
            await contactPage.saveTags();
            await expect(contactPage.dashboardLoc.msgSuccess.first()).toBeVisible();
            await contactPage.dashboardLoc.btnClosePopupNotification.click();
            await expect(contactPage.dashboardLoc.tag.btnSaveTag).not.toBeVisible();

            const tagCount = await contactPage.getTagCount();
            expect(tagCount).toBe(0);
        });
    })
});
