import { test, expect } from '../../../fixtures/index';
import { ApiHelper } from '../../../helper/api.helper';
import { CasePage } from '../../../pom/case/case.page';
import { LoginPage } from '../../../pom/login.page';
import { RequestPage } from '../../../pom/request/request.page';
import { SharedRequestPage } from '../../../pom/share-request.page';
import { randomDate } from '../../../pom/utils/utlisFunc';
import { extractIdFromUrl, randomString } from '../../../utils/array';
import { verifyScreenshot } from '../../../utils/screenshot';

test.describe("Verify feature link case", () => {
    let loginPage: LoginPage;
    let casePage: CasePage;
    let requestPage: RequestPage;

    // Shared variables for both tests
    let firstName: string, lastName: string, clientName: string, doi: string, dob: string;
    let caseIdA: string, customerIdA: string, requestIdA: string;
    let caseIdB: string, customerIdB: string, requestIdB: string;
    let casePageB: CasePage, requestPageB: RequestPage, sharedRequestPageB: SharedRequestPage;
    let conf: any, browser: any, apiHelper: any, page: any;
    let contextB: any; // Store User B's context for cleanup

    test.beforeEach(async ({ page: testPage, conf: testConf, apiHelper: testApiHelper, browser: testBrowser }) => {
        // Initialize User A
        loginPage = new LoginPage(testPage);
        casePage = new CasePage(testPage);
        requestPage = new RequestPage(testPage);
        await loginPage.open();
        await loginPage.login(testConf.data.username, testConf.data.password);
        await expect(loginPage.baseLoc.dashboardContainer).toBeVisible({ timeout: 25_000 });

        // Store fixtures for use in tests and afterEach
        conf = testConf;
        browser = testBrowser;
        apiHelper = testApiHelper;
        page = testPage;

        // Generate test data
        firstName = `Linkcaseoff${randomString(3)}`;
        lastName = `Test${randomString(3)}`;
        clientName = `${firstName} ${lastName}`;
        doi = await randomDate();
        dob = await randomDate();

        // Reset IDs
        caseIdA = "";
        customerIdA = "";
        requestIdA = "";
        caseIdB = "";
        customerIdB = "";
        requestIdB = "";

        await test.step("User B: Login and create a case via API", async () => {
            const { context: userBContext, requestPage: reqPageB } = await requestPage.loginInAnotherBrowser(browser, conf.data.user_receive, conf.data.password);
            contextB = userBContext; // Store context for cleanup
            requestPageB = reqPageB;
            casePageB = new CasePage(requestPageB.page);
            sharedRequestPageB = new SharedRequestPage(requestPageB.page);
            const apiHelperB = new ApiHelper(requestPageB.page, requestPageB.page.context().request);

            const resultB = await apiHelperB.createCustomerAndCase({ 
                first_name: firstName, 
                last_name: lastName, 
                birthday: dob, 
                date_of_injury: doi, 
                category_id: conf.data.category_id 
            });

            caseIdB = resultB.case_id;
            customerIdB = resultB.customer_id;
        });

        await test.step("User A: Login, create case with same info and send request to User B", async () => {
            const result = await apiHelper.createCustomerAndCase({ 
                first_name: firstName, 
                last_name: lastName, 
                birthday: dob, 
                date_of_injury: doi, 
                category_id: conf.data.category_id 
            });
            caseIdA = result.case_id;
            customerIdA = result.customer_id;

            const requestResult = await apiHelper.createRequestForExistingCase({
                customer_id: customerIdA,
                case_id: caseIdA,
                date_of_injury: doi,
                message_text: '<p>Request from User A - Full match case (automation OFF)</p>',
                intent_type: conf.data.intent_type,
                request_type_id: conf.data.request_type_id,
                business_provider_id: conf.data.business_provider_id,
                emails: [conf.data.user_receive],
                send_email_notification: 1,
                switch: conf.data.switch
            });
            requestIdA = requestResult.requestData.id;

            await apiHelper.archiveCase(caseIdA);
            await apiHelper.archiveBusinessParticipant(caseIdA, conf.data.business_provider_id);
            await apiHelper.archiveCustomer(customerIdA);
            // Close User A's context safely
            if (page && page.context()) {
                await page.context().close();
            }
        });

        await test.step("User B: Verify case unread and request NOT auto-linked (automation OFF)", async () => {
            await sharedRequestPageB.open();
            await sharedRequestPageB.search(clientName);
            await expect(sharedRequestPageB.dashboardLoc.common.aText(clientName)).toBeVisible();
            await sharedRequestPageB.resetToDefaultColumn(sharedRequestPageB.shareRequestProps.customizedColumns, 1);
            await verifyScreenshot('automation-off-request-unread.png', sharedRequestPageB.shareRequestLoc.linkcase.rowUnread, [sharedRequestPageB.dashboardLoc.common.aText(clientName), sharedRequestPageB.shareRequestLoc.linkcase.requestNewID(requestIdA)], 0.02);

            await sharedRequestPageB.dashboardLoc.common.aText(clientName).click();
            await expect(requestPageB.requestLoc.linkcase.bannerAssignToCase).toBeVisible();
            expect(requestPageB.page.url()).toContain(`${requestPageB.baseUrl}requests`);
        });

        await test.step("User B: Click Assign to Case", async () => {
            await requestPageB.dashboardLoc.buttonByText('Assign to Case').click();

            await expect(requestPageB.requestLoc.linkcase.informationsInModal(clientName)).toBeVisible();
            await expect(requestPageB.requestLoc.linkcase.informationsInModal(doi)).toBeVisible();
            await expect(requestPageB.requestLoc.linkcase.informationsInModal(dob)).toBeVisible();
        });
    });

    test.afterEach(async () => {
        if (caseIdB && customerIdB) {
            await test.step("Cleanup: Archive User B's case", async () => {
                const apiHelperB = new ApiHelper(casePageB.page, casePageB.page.context().request);
                await apiHelperB.archiveCase(caseIdB);
                await apiHelperB.archiveBusinessParticipant(caseIdB, conf.data.business_provider_id);
                await apiHelperB.archiveCustomer(customerIdB);
            });
        }

        // Close User B's context to ensure test isolation
        if (contextB) {
            await test.step("Cleanup: Close User B's browser context", async () => {
                await contextB.close();
                contextB = null;
            });
        }
    });

    test("ALC_OFF_001 - Verify link case quickly for request with full match case (never been linked before) (Content 16).", {
        tag: ['@ALC_OFF_001', '@link_case_off', '@function']
    }, async () => {
        await test.step("User B: Click Review & Confirm and verify modal Compare", async () => {
            await requestPageB.dashboardLoc.buttonByText('Review & Confirm Match').click();
            
            await expect(requestPageB.page.locator('#root')).toMatchAriaSnapshot(
                requestPageB.linkCaseOffSnapshot.reviewLinkExistingCaseNoDoiChange(clientName, dob, doi)
            );
        });

        await test.step("User B: Finalize linking case", async () => {
            await requestPageB.dashboardLoc.buttonByText('Finalize').click();
            await expect(requestPageB.page.locator('#root')).toMatchAriaSnapshot(
                requestPageB.linkCaseOffSnapshot.successVerifiedLinkedToCase(doi)
            );
            await requestPageB.dashboardLoc.buttonByText('Ok, I got it').click();
            await expect(requestPageB.requestLoc.linkcase.bannerAssignToCase).not.toBeVisible();
            await expect(requestPageB.requestLoc.linkcase.bannerRequestRelevant).toBeVisible();
            requestIdB = extractIdFromUrl(requestPageB.page.url());

            // Verify request in case
            await requestPageB.dashboardLoc.common.spanText(`#${caseIdB}`).click();
            await requestPageB.dashboardLoc.detail.tabName("Summary/ Dive Deeper").click();
            await expect(casePageB.caseLoc.detail.requestExitInRequestTable(requestIdB)).toBeVisible();
        });
    });

    test("ALC_OFF_002 - Verify link case manually for request with full match case (never been linked before).", {
        tag: ['@ALC_OFF_002', '@link_case_off', '@function']
    }, async () => {
        await test.step("User B: Click I want to do Manually", async () => {
            await requestPageB.dashboardLoc.common.spanText("I want to do Manually").click();

            await expect(requestPageB.dashboardLoc.modal.headerModalh2("Manual Case Association")).toBeVisible();
            await expect(requestPageB.requestLoc.linkcase.boxInformationCase(clientName)).toBeVisible();
            await expect(requestPageB.requestLoc.linkcase.boxInformationCase(doi)).toBeVisible();
            await expect(requestPageB.requestLoc.linkcase.boxInformationCase(dob)).toBeVisible();
        });

        await test.step("User B: Verify Manual link case", async () => {
            await requestPageB.requestLoc.linkcase.boxSuggestClient(clientName).click();
            await expect(requestPageB.dashboardLoc.modal.inputByID("autocomplete_customer")).toHaveValue(clientName);

            await requestPageB.waitForSecond(1);
            await requestPageB.requestLoc.linkcase.boxSuggestDOI(doi).click();
            await expect(requestPageB.requestLoc.linkcase.doiLinkBlue).toHaveText(doi);
        });

        await test.step("User B: Click Next to verify modal Compare", async () => {
            await requestPageB.dashboardLoc.buttonByText('Next').first().click();
            await expect(requestPageB.page.locator('#root')).toMatchAriaSnapshot(
                requestPageB.linkCaseOffSnapshot.reviewLinkExistingCaseNoDoiChange(clientName, dob, doi)
            );
        });

        await test.step("User B: Finalize linking case", async () => {
            await requestPageB.dashboardLoc.buttonByText('Finalize').click();
            await expect(requestPageB.page.locator('#root')).toMatchAriaSnapshot(
                requestPageB.linkCaseOffSnapshot.successVerifiedLinkedToCase(doi)
            );
            await requestPageB.dashboardLoc.buttonByText('Ok, I got it').click();
            await expect(requestPageB.requestLoc.linkcase.bannerAssignToCase).not.toBeVisible();
            await expect(requestPageB.requestLoc.linkcase.bannerRequestRelevant).toBeVisible();
            requestIdB = extractIdFromUrl(requestPageB.page.url());

            // Verify request in case
            await requestPageB.dashboardLoc.common.spanText(`#${caseIdB}`).click();
            await requestPageB.dashboardLoc.detail.tabName("Summary/ Dive Deeper").click();
            await expect(casePageB.caseLoc.detail.requestExitInRequestTable(requestIdB)).toBeVisible();
        });
    });

});