import { test, expect } from '../../../fixtures/index';
import { LoginPage } from '../../../pom/login.page';
import { CasePage } from '../../../pom/case/case.page';
import { getTodayInTimeZone, randomDate } from '../../../pom/utils/utlisFunc';
import { takeScreenshot, verifyScreenshot } from '../../../utils/screenshot';

test.describe('Case Module - Advanced Features', async () => {
  let loginPage: LoginPage;
  let casePage: CasePage;

  test.beforeEach("Login and verify data", async ({ page, conf }) => {
    // Initialize page objects
    loginPage = new LoginPage(page);
    casePage = new CasePage(page);

    await test.step("Login and go to case page", async () => {
      await loginPage.open();
      await loginPage.login(conf.data.username, conf.data.password);
      await expect(loginPage.baseLoc.dashboardContainer).toBeVisible();
      await casePage.open();
    });

    await test.step("Search with exist case", async () => {
      if (conf.data.no_search) {
        return;
      }
      if (conf.data.only_search) {
        return casePage.search(conf.data.case);
      }
      await casePage.getDetailCase(conf.data.case);
      await casePage.waitForSecond(2);
      if (conf.data.not_update) {
        return;
      }
      await expect(casePage.caseLoc.detail.buttonUpdateCase).toBeVisible();
      await casePage.caseLoc.detail.buttonUpdateCase.click({ force: true });
      await expect(casePage.dashboardLoc.modal.headerModal("Case Detail")).toBeVisible();
    });

    // Bổ sung thêm check info detail và info modal update (sau sẽ có thêm api -> bổ sung sau)
  });

  test("CASE_019 - Verify when add tag to case", {
    tag: ['@CASE_019', '@case', '@function']
  }, async () => {
    test.setTimeout(180_000);
    try {
      await casePage.caseLoc.detail.listRequestTags.waitFor({ state: 'visible', timeout: 3_000 });
      await casePage.caseLoc.detail.listRequestTags.click();
      await casePage.dashboardLoc.tag.btnClearAllTag.click();
      await casePage.saveTags();
      await casePage.dashboardLoc.btnClosePopupNotification.click();
    } catch {
      // listRequestTags not visible within 3s, continue
    }
    await test.step("Verify add tags with tag count greater than 9 (invalid)", async () => {
      await casePage.addMultipleTags(10);
      await casePage.saveTags();
      await expect(casePage.dashboardLoc.tag.errorMaxTag).toBeVisible();
    });

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

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

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

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

  test("CASE_020 - Verify status when change status detail case", {
    tag: ['@CASE_020', '@case', '@function']
  }, async ({ apiHelper }) => {
    test.setTimeout(250_000);
    let firstCaseID: string = "";
    for (const { detail, expectedStatus } of casePage.statusTests) {
      await test.step(`Change Status Details to ${detail} and verify Status is ${expectedStatus}`, async () => {
        await casePage.caseLoc.detail.statusDetailsInput.nth(1).click();
        await casePage.waitForSecond(1);
        await casePage.caseLoc.detail.statusDetailsOption(detail).click();
        if (expectedStatus !== "Closed") {
          await expect(casePage.caseLoc.detail.statusDisplay).toContainText(expectedStatus);
        } else {
          await expect(casePage.dashboardLoc.modal.headerModal("Final Case Review")).toBeVisible();
          await casePage.caseLoc.detail.btnCancelFinalCaseReview.click();
          await expect(casePage.dashboardLoc.modal.headerModal("Final Case Review")).not.toBeVisible();
        }
      });
    }

    await test.step("Change status of request", async () => {
      // Change status to open modal Final Case Review
      await casePage.dashboardLoc.detail.tabName("Summary/ Dive Deeper").click();
      await casePage.caseLoc.detail.statusDetailsInput.nth(1).click();
      await casePage.waitForSecond(1);
      await casePage.caseLoc.detail.statusDetailsOption("Closed").click();
      await expect(casePage.dashboardLoc.modal.headerModal("Final Case Review")).toBeVisible();
      firstCaseID = await casePage.caseLoc.detail.modalFinalCaseReview.firstRequestID.innerText();

      // Verify filter request type
      await casePage.caseLoc.detail.modalFinalCaseReview.btnSelectFilterRequestType.first().click();
      await casePage.caseLoc.detail.modalFinalCaseReview.optionInSelectFilter("Letter of Protection").first().click();
      await expect(casePage.caseLoc.detail.modalFinalCaseReview.textFilter.first()).toContainText("Letter of Protection");
      await casePage.waitForSecond(2);
      const rowsTable = (await casePage.caseLoc.detail.modalFinalCaseReview.rowInTable.all()).length;
      expect(rowsTable).toBe(3);

      // Change status of first request
      await casePage.caseLoc.detail.modalFinalCaseReview.btnSelectStatusdetailFirst.click();
      await casePage.caseLoc.detail.modalFinalCaseReview.selectOption("Inquiry").last().click();
      await casePage.dashboardLoc.buttonByText("Update").last().click();

      await expect(casePage.dashboardLoc.modal.headerModal("Final Case Review")).not.toBeVisible();
      await expect(casePage.caseLoc.detail.statusDetailRequestActivityTable("Inquiry")).toBeVisible();
    });

    await test.step("Teardown - Change status to awaiting", async () => {
      await apiHelper.changeRequestStatus(firstCaseID, 136)
    });
  })

  test("CASE_021 - Verify when Assignee case", {
    tag: ['@CASE_021', '@case', '@function']
  }, async ({ conf }) => {
    test.setTimeout(200_000)
    let currentAssignee: string = "";

    await test.step("Verify list option assignee member", async () => {
      currentAssignee = await casePage.caseLoc.detail.fullnameAssignee.innerText();
      const totalMembers = await casePage.getTotalMemberInBusiness();
      await casePage.caseLoc.detail.btnAssignee.click();
      await casePage.caseLoc.detail.inputSearchMember.click();
      await casePage.waitForSecond(2);
      const totalMembersUI = (await casePage.caseLoc.detail.optionMember.all()).length;
      expect(totalMembers).toBe(totalMembersUI - 1);
    });

    await test.step("Verify when add member not in Business", async () => {
      await casePage.caseLoc.detail.inputSearchMember.clear();
      await casePage.caseLoc.detail.inputSearchMember.fill(conf.data.member_not_in_business);
      await casePage.waitForSecond(2);
      const options = await casePage.caseLoc.detail.optionMember.all();
      expect(options.length).toBe(1);
      await casePage.caseLoc.detail.inputSearchMember.clear();
    });

    await test.step("Verify when assignee to member in business", async () => {
      await casePage.caseLoc.detail.inputSearchMember.type(conf.data.member_in_business, { delay: 100 });
      await expect(casePage.caseLoc.detail.optionSearchExist(conf.data.member_in_business)).toBeVisible({ timeout: 15_000 });
      await casePage.caseLoc.detail.optionSearchExist(conf.data.member_in_business).click();
      await casePage.caseLoc.detail.btnSubmitAssignee.click();

      await expect(casePage.caseLoc.detail.fullnameAssignee).toContainText(conf.data.member_assignee);

      // Verify activity change
      const newestActivity = await casePage.getNewestActivity();
      expect(newestActivity).toContain(`changed the Assignee ${currentAssignee} ${conf.data.member_assignee} ${await getTodayInTimeZone()}`);
    });

    await test.step("Verify that the member who received the assignee gets a notification", async () => {
      await casePage.changeUser(conf.data.username_get_noti, conf.data.password_get_noti, casePage.page);
      await expect(loginPage.baseLoc.dashboardContainer).toBeVisible();
      await casePage.checkNotification("Assignee", true);
      await expect(casePage.caseLoc.detail.fullnameAssignee).toContainText(conf.data.member_assignee, { timeout: 25_000 });
    });

    await test.step("Teardown: Assignee to old member", async () => {
      await casePage.caseLoc.detail.btnAssignee.click();
      await casePage.caseLoc.detail.inputSearchMember.fill(conf.data.member_first_assignee);
      await expect(casePage.caseLoc.detail.optionSearchExist(conf.data.member_first_assignee)).toBeVisible({ timeout: 15_000 });
      await casePage.caseLoc.detail.optionSearchExist(conf.data.member_first_assignee).click();
      await casePage.caseLoc.detail.btnSubmitAssignee.click();
    });
  });

  test("CASE_022 - Dive deeper: Verify archive/unarchive a Business in case", {
    tag: ['@CASE_022', '@case', '@function']
  }, async ({ conf, casePage22 }) => {
    test.setTimeout(190_000);
    await test.step("Verify when archive business", async () => {
      await casePage22.clickButtonDropdownSelect("BTN_ARCHIVE_UNARCHIVE_BUSINESS_IN_CASE_DETAIL");

      await expect(casePage22.caseLoc.detail.popupSwal).toBeVisible();
      await casePage22.caseLoc.detail.btnCofirmArchive.click();

      await expect(casePage22.caseLoc.detail.addLegalModal.msgSuccess.first()).toBeVisible();
      await expect(casePage22.caseLoc.detail.btnViewArchivedBusiness).toBeVisible();
      await expect(casePage22.caseLoc.detail.singleBusinesses(conf.data.business_archive)).not.toBeVisible();

      // Verify activity
      const newestActivity = await casePage22.getNewestActivity();
      expect(newestActivity).toContain(`archive the business ${conf.data.business_archive} ${await getTodayInTimeZone()}`);
    });

    await test.step("Verify when unArchive business", async () => {
      await expect(casePage22.caseLoc.detail.btnViewArchivedBusiness).toBeVisible();
      await casePage22.gotoArchive(conf.data.case)
      await expect(casePage22.caseLoc.detail.singleBusinesses(conf.data.business_archive)).toBeVisible();

      await casePage22.clickButtonDropdownSelect("BTN_ARCHIVE_UNARCHIVE_BUSINESS_IN_CASE_DETAIL");
      await expect(casePage22.caseLoc.detail.addLegalModal.msgSuccess.first()).toBeVisible();
      await casePage22.waitForSecond(3);

      const listBusinesses = (await casePage22.caseLoc.detail.listBusinesses.all()).length;
      expect(listBusinesses).toBe(3);
      await expect(casePage22.caseLoc.detail.singleBusinesses(conf.data.business_archive)).toBeVisible();
      await expect(casePage22.caseLoc.detail.noDataRequest).toBeVisible();

      // Verify activity
      const newestActivity = await casePage22.getNewestActivity();
      expect(newestActivity).toContain(`unarchive the business ${conf.data.business_archive} ${await getTodayInTimeZone()}`);
    });

    await test.step("Unarchive all requests", async () => {
      let attempts = 0;

      while (attempts < 20) {
        const archiveLinks = casePage22.caseLoc.detail.listLinkArchiveRequests;
        const count = await archiveLinks.count();
        if (count === 0) {
          break;
        }
        try {
          await expect(archiveLinks.first()).toBeVisible({ timeout: 10_000 });
          await archiveLinks.first().click();
          await casePage22.caseLoc.detail.update.btnUnArchive.click();
          await casePage.dashboardLoc.buttonByText("Unarchive").click();
          await casePage.caseLoc.detail.btnClosePopup.click();
          await casePage22.caseLoc.btnCloseModal.click();
          await casePage22.caseLoc.linkToCase(conf.data.case).click();
          attempts++;
        } catch (error) {
          break;
        }
      }
      await expect(casePage22.caseLoc.detail.noDataRequest).not.toBeVisible({ timeout: 5000 });
    });
  });

  test("CASE_024 - Dive deeper: Verify when Start it in same type request", {
    tag: ['@CASE_024', '@case', '@function']
  }, async ({ conf, casePage24 }) => {
    await test.step("Verify request medical bill had star in table", async () => {
      await expect(casePage24.caseLoc.detail.requestHadStarIt(conf.data.case_had_star)).toBeVisible();
    });

    await test.step("Verify when change star it", async () => {
      await casePage24.changeStarFocus(conf.data.case_star_to);
      await expect(casePage24.caseLoc.detail.addLegalModal.msgSuccess.first()).toBeVisible();
      await expect(casePage24.caseLoc.detail.requestHadStarIt(conf.data.case_had_star)).not.toBeVisible();
      await expect(casePage24.caseLoc.detail.requestHadStarIt(conf.data.case_star_to)).toBeVisible();
    });
  });

  test("CASE_025 - Dive deeper: Customize column in request table", {
    tag: ['@CASE_025', '@case', '@function']
  }, async ({ conf }) => {
    // Verify default columns displayed
    await test.step("Verify default columns displayed", async () => {
      await casePage.dashboardLoc.detail.tabName("Summary/ Dive Deeper").click();

      const customizedColumns = casePage.caseProps.requestsColumns;
      for (let i = 0; i < customizedColumns.length; i++) {
        if (customizedColumns[i].default) {
          await expect(casePage.caseLoc.detail.headingTableRequest(customizedColumns[i].tableDisplayName).first()).toBeVisible();
        }
      }
    });

    // Verify customized column show disable items and active items
    await test.step("Verify customized columns popup state", async () => {
      await casePage.openThreedotMenu(casePage.caseProps.threeDotDropdownMenus.customizedColumn, casePage.caseLoc.detail.threeDotCustomizeColumnRequest.first(), false);

      // Verify enabled column and disabled column
      const customizedColumns = casePage.caseProps.requestsColumns;
      for (let i = 0; i < customizedColumns.length; i++) {
        if (customizedColumns[i].default) {
          await expect(casePage.dashboardLoc.listing.popup.customizedColumn.columnCheckboxRequestCase(customizedColumns[i].tableDisplayName).first()).toBeDisabled();
        } else {
          await expect(casePage.dashboardLoc.listing.popup.customizedColumn.columnCheckboxRequestCase(customizedColumns[i].tableDisplayName).first()).toBeEnabled();
        }
      }
      await casePage.caseLoc.buttonByText("Apply").first().click();
    });

    // Check each columns and verify it shown
    await test.step("Check each columns and verify it shown", async () => {
      const customizedColumns = casePage.caseProps.requestsColumns.filter(column => !column.default);
      for (const column of customizedColumns) {
        await casePage.openThreedotMenu(casePage.caseProps.threeDotDropdownMenus.customizedColumn, casePage.caseLoc.detail.threeDotCustomizeColumnRequest.first(), false);
        await casePage.dashboardLoc.listing.popup.customizedColumn.columnCheckboxRequestCase(column.tableDisplayName).first().setChecked(true);
        await casePage.caseLoc.buttonByText("Apply").first().click();
        await expect(casePage.caseLoc.detail.headingTableRequest(column.tableDisplayName).first()).toBeVisible();
      }
    });

    // Uncheck each columns and verify it hidden
    await test.step("Uncheck each columns and verify it hidden", async () => {
      const customizedColumns = casePage.caseProps.requestsColumns.filter(column => !column.default);
      // TODO: change to all columns. We're facing with some issues with the last column
      for (const column of customizedColumns) {
        await casePage.openThreedotMenu(casePage.caseProps.threeDotDropdownMenus.customizedColumn, casePage.caseLoc.detail.threeDotCustomizeColumnRequest.first(), false);
        await casePage.dashboardLoc.listing.popup.customizedColumn.columnCheckboxRequestCase(column.tableDisplayName).first().setChecked(false);
        await casePage.caseLoc.buttonByText("Apply").first().click();
        await expect(casePage.caseLoc.detail.headingTableRequest(column.tableDisplayName).first()).not.toBeVisible();
      }
    });
  });

  test("CASE_026 - Quick summary: Verify filter activity by action type", {
    tag: ['@CASE_026', '@case', '@function']
  }, async () => {
    await casePage.dashboardLoc.detail.tabName("Summary/ Dive Deeper").click();

    for (const { name, expectedRequests } of casePage.actionType) {
      await casePage.caseLoc.detail.dataRequestType(name).click();
      await expect(casePage.caseLoc.detail.textSummaryDisplay).toContainText(name);
      await casePage.waitForSecond(1);
      // Sau khi có api cần bổ sung thêm check request dựa và action type
    }
  });

  test("CASE_027 - Verify move request to another exist case", {
    tag: ['@CASE_027', '@case', '@function']
  }, async ({ conf, casePage27 }) => {
    test.setTimeout(100_000);
    await test.step("Verify business and request exist and open modal move request", async () => {
      await expect(casePage27.caseLoc.detail.singleBusinesses(conf.data.business)).toBeVisible();
      await casePage27.waitForSecond(1);
      expect((await casePage27.caseLoc.detail.listRequestOfBusiness.all()).length).toBeGreaterThan(0);

      await casePage27.clickButtonDropdownSelect("BTN_SHOW_MOVE_REQUEST_OF_BUSINESS_MODAL");
      await expect(casePage27.dashboardLoc.modal.headerModal("Move Requests")).toBeVisible();
    });

    await test.step("Verify when fill case and move request", async () => {
      await casePage27.caseLoc.detail.inputMoveRequest.click();
      await casePage27.caseLoc.detail.inputMoveRequest.type(conf.data.case_to_move, { delay: 100 });
      await casePage27.caseLoc.detail.transfer.boxOption(conf.data.case_to_move).click();
      await casePage27.caseLoc.buttonByText("Move").click();

      await expect(casePage27.caseLoc.detail.addLegalModal.msgSuccess.first()).toBeVisible();
      await casePage27.caseLoc.detail.btnClosePopup.click();
      await expect(casePage27.caseLoc.detail.textNoRequest).toBeVisible();

      // Verify activity
      const newestActivity = await casePage27.getNewestActivity();
      expect(newestActivity).toContain(`moved request from ${conf.data.business} Case: #${conf.data.case} #${conf.data.case_to_move} ${await getTodayInTimeZone()}`);
    });

    await test.step("Verify case and business exist ", async () => {
      await casePage27.open();
      await casePage27.getDetailCase(conf.data.case_to_move);
      await expect(casePage27.caseLoc.detail.singleBusinesses(conf.data.business)).toBeVisible();
      await casePage27.waitForSecond(2);
      expect((await casePage27.caseLoc.detail.listRequestOfBusiness.all()).length).toBeGreaterThan(0);
    });
  });

  test("CASE_028 - Verify move request to another new case", {
    tag: ['@CASE_028', '@case', '@function']
  }, async ({ conf, apiHelper }) => {
    let newCaseID: string = "";
    await test.step("Verify business and request exist and open modal move request", async () => {
      await casePage.dashboardLoc.detail.tabName("Summary/ Dive Deeper").click();
      await expect(casePage.caseLoc.detail.singleBusinesses(conf.data.business)).toBeVisible();
      expect((await casePage.caseLoc.detail.listRequestOfBusiness.all()).length).toBeGreaterThan(0);

      await casePage.clickButtonDropdownSelect("BTN_SHOW_MOVE_REQUEST_OF_BUSINESS_MODAL");
      await expect(casePage.dashboardLoc.modal.headerModal("Move Requests")).toBeVisible();
    });

    await test.step("Verify when move request to new case", async () => {
      await casePage.caseLoc.detail.radioCheckAddNew.click();
      await expect(casePage.caseLoc.detail.inputAddNewDOI).toBeVisible();
      await casePage.caseLoc.detail.inputAddNewDOI.fill(await randomDate());
      await casePage.dashboardLoc.modal.headerModal("Move Requests").click();
      await casePage.caseLoc.buttonByText("Move").click();

      await expect(casePage.caseLoc.detail.addLegalModal.msgSuccess.first()).toBeVisible();
      await casePage.dashboardLoc.btnClosePopupNotification.click();
      await expect(casePage.caseLoc.detail.textNoRequest).toBeVisible();
    });

    await test.step("Verify request in new case created and moved to", async () => {
      await casePage.waitForSecond(2);
      await casePage.dashboardLoc.buttonByText("Activity").click();
      await expect(casePage.dashboardLoc.modal.headerModal("Activity")).toBeVisible();
      const newMoveRequest = await casePage.caseLoc.detail.activity.spanInActivity.last().innerText();
      newCaseID = newMoveRequest.match(/#(\d+)/)?.[1] ?? '';

      await casePage.open();
      await casePage.getDetailCase(newCaseID);

      await expect(casePage.caseLoc.detail.singleBusinesses(conf.data.business)).toBeVisible();
      await casePage.waitForSecond(2);
      expect((await casePage.caseLoc.detail.listRequestOfBusiness.all()).length).toBeGreaterThan(0);
    });

    await test.step("Tear down move request to old case", async () => {
      await casePage.tearDownMoveToOldCase(conf.data.case);
      await apiHelper.archiveCase(newCaseID);
    });
  });

  test("CASE_030 - Verify discussion in detail case", {
    tag: ['@CASE_030', '@case', '@function']
  }, async ({ conf, browser }) => {
    test.setTimeout(150_000);
    const uniqueMsg = `${conf.data.message}_${Date.now()}`;
    const uniqueMsgReply = `${conf.data.message_reply}_${Date.now()}`;
    await test.step("User A send inbox to team discussion", async () => {
      await casePage.caseLoc.detail.discussionCase.hover();
      await expect(casePage.caseLoc.detail.teamDiscussion).toBeVisible();
      await casePage.caseLoc.detail.teamDiscussion.click();
      await casePage.caseLoc.detail.discussion.inputMsg.fill(uniqueMsg);
      await casePage.caseLoc.detail.discussion.inputMsg.press("Enter");
      await expect(casePage.caseLoc.detail.discussion.contentMsg(uniqueMsg)).toBeVisible();
    });

    await test.step("User B get noti and reply to user A", async () => {
      const { context: contextB, casePage: casePageB } = await casePage.loginInAnotherBrowser(browser, conf.data.user_recive_message, conf.data.password);
      await casePageB.checkNotification("New Discussion", true);
      await expect(casePage.caseLoc.detail.discussion.contentMsg(uniqueMsg)).toBeVisible();

      await casePageB.caseLoc.detail.discussion.inputMsg.fill(uniqueMsgReply);
      await casePageB.caseLoc.detail.discussion.inputMsg.press("Enter");

      await expect(casePageB.caseLoc.detail.discussion.contentMsg(uniqueMsgReply)).toBeVisible({ timeout: 20_000 });
      await contextB.close();
    });

    await test.step("User A revice noti and message", async () => {
      await casePage.page.reload();
      await casePage.checkNotification("New Discussion", true);
      await expect(casePage.caseLoc.detail.discussion.contentMsg(uniqueMsgReply)).toBeVisible({ timeout: 20_000 });
    });
  });

  test("CASE_031 - Verify when click New request from detail case only load 1 time", {
    tag: ['@CASE_031', '@case', '@function']
  }, async ({ page, conf }) => {
    let navigatedOnce = false;
    await casePage.dashboardLoc.detail.tabName("Summary/ Dive Deeper").click();

    page.on('framenavigated', (frame) => {
      if (frame === page.mainFrame() && frame.url().includes('/requests/create')) {
        if (navigatedOnce) {
          throw new Error('DOUBLE NAVIGATION DETECTED!');
        }
        navigatedOnce = true;
      }
    });

    await Promise.all([
      page.waitForURL(/.*\/requests\/create.*/, { timeout: 15_000 }),
      casePage.caseLoc.detail.btnCreateNewRequest.click(),
    ]);

    expect(navigatedOnce).toBe(true);

    await expect(casePage.caseLoc.detail.labelByStepCreateRequest(3))
      .toContainText(conf.data.patient_name);
    await expect(casePage.caseLoc.detail.labelByStepCreateRequest(2))
      .toContainText(conf.data.business_name);
  });

  test('CASE_007 - Verify feature Pin/Unpin for case', {
    tag: ['@CASE_007', '@case', '@function']
  }, async ({ conf }) => {
    await test.step('Search and verify icon Pin visible', async () => {
      await casePage.caseLoc.inputSearch.fill(conf.data.case_number);
      await expect(casePage.caseLoc.tableHeadingColumn('Pin')).toBeVisible();
    });

    await test.step('Verify Pin and unpin feature', async () => {
      await expect(casePage.dashboardLoc.table.itemInRow(conf.data.case_number)).toBeVisible();
      await casePage.waitForSecond(1);
      const isPinned = await casePage.caseLoc.pinnedIcon(conf.data.case_number).isVisible().catch(() => false);

      if (isPinned) {
        // Already pinned, click to unpin then pin again
        await casePage.caseLoc.pinnedIcon(conf.data.case_number).click();
        await expect(casePage.caseLoc.pinIcon(conf.data.case_number)).toBeVisible();

        // Now pin it
        await casePage.caseLoc.pinIcon(conf.data.case_number).click();
        await expect(casePage.caseLoc.pinnedIcon(conf.data.case_number)).toBeVisible();
        await expect(casePage.caseLoc.firstCaseNumber(conf.data.case_number)).toBeVisible();
      } else {
        // Not pinned, click to pin
        await casePage.caseLoc.pinIcon(conf.data.case_number).click();
        await expect(casePage.caseLoc.pinnedIcon(conf.data.case_number)).toBeVisible();
        await expect(casePage.caseLoc.firstCaseNumber(conf.data.case_number)).toBeVisible();
      }

      // Clean up: unpin to original state
      await casePage.caseLoc.pinnedIcon(conf.data.case_number).click();
      await expect(casePage.caseLoc.pinIcon(conf.data.case_number)).toBeVisible();
    });
  });

  test("CASE_032 - Verify data when add to request cart", {
    tag: ['@CASE_032', '@case', '@function']
  }, async ({ conf, checkCart }) => {
    await test.step("Add requests to cart", async () => {
      await casePage.open();
      await checkCart.search(conf.data.case);
      await checkCart.waitForSecond(1);
      await checkCart.dashboardLoc.table.itemInRow(conf.data.case).hover({ force: true });
      await checkCart.requestLoc.detail.cartRequest.optionCartHoverCaseID("Letter of Protection").click();
      await checkCart.requestLoc.detail.cartRequest.optionCartHoverCaseID("Medical Bill").click();
      await expect(checkCart.requestLoc.detail.cartRequest.quickSubmitButton("2")).toBeVisible();
    });

    await test.step("Verify cart data", async () => {
      await checkCart.page.mouse.move(0, 0);
      await checkCart.requestLoc.detail.cartRequest.quickSubmitButton("2").click();
      await expect(checkCart.requestLoc.detail.cartRequest.tdInTable("John Doe 65423").first()).toBeVisible();
      await checkCart.waitForSecond(1);
      await verifyScreenshot('list-request-by-case-overview.png', checkCart.requestLoc.create.overviewCreateFast, [], 0.01);
    });
  });

  test("CASE_043 - Change work type", {
    tag: ['@CASE_043', '@case', '@function']
  }, async ({ apiHelper }) => {
    let caseId: string = "";
    let customerId: string = "";
    let totalActiveEntries: number = 0;
    let totalReferenceEntries: number = 0;
    const firstName = `Auto${Date.now()}`;
    const lastName = `Test${Date.now()}`;
    const dob = await randomDate();
    const doi = await randomDate();

    await test.step("Preconditon: Create new case with existing customer", async () => {
      totalActiveEntries = await casePage.getTotalEntriesByTabs("cases", "0,1", false);
      totalReferenceEntries = await casePage.getTotalEntriesByTabs("cases", "2", false);

      const resultB = await apiHelper.createCustomerAndCase({
        first_name: firstName,
        last_name: lastName,
        birthday: dob,
        date_of_injury: doi,
        category_id: "10000"
      });

      caseId = resultB.case_id;
      customerId = resultB.customer_id;
      expect(totalActiveEntries + 1).toBe(await casePage.getTotalEntriesByTabs("cases", "0,1", false));
    });

    await test.step("Change case to referrence", async () => {
      await casePage.getDetailCase(caseId);
      await expect(casePage.dashboardLoc.detail.workType("Active")).toBeVisible();

      // Change work type to reference
      await casePage.dashboardLoc.detail.workType("Active").click();
      await expect(casePage.dashboardLoc.detail.optionWorkType("Reference")).toBeVisible();
      await casePage.dashboardLoc.detail.optionWorkType("Reference").click();
      await expect(casePage.dashboardLoc.detail.workType("Reference")).toBeVisible();
    });

    await test.step("Verify client in list client", async () => {
      await casePage.open();

      //Veriy total entries changed 
      expect(totalActiveEntries).toBe(await casePage.getTotalEntriesByTabs("cases", "0,1", false))
      expect(totalReferenceEntries + 1).toBe(await casePage.getTotalEntriesByTabs("cases", "2", false));

      //Veriy in tab Active
      await casePage.dashboardLoc.table.tabInTable("Active").click();
      await casePage.search(caseId);
      await expect(casePage.dashboardLoc.table.itemInRow(caseId)).not.toBeVisible();

      //Verify in tab Reference
      await casePage.dashboardLoc.table.tabInTable("Reference").click();
      await casePage.search(caseId);
      await expect(casePage.dashboardLoc.table.itemInRow(caseId)).toBeVisible();
      await expect(casePage.dashboardLoc.common.pTextContainsAll("Showing 1 to 1 of 1 entries")).toBeVisible();
    });

    await test.step("Change client back to active", async () => {
      await casePage.dashboardLoc.table.itemInRow(caseId).click();
      await expect(casePage.dashboardLoc.detail.workType("Reference")).toBeVisible();

      // Change work type to active
      await casePage.dashboardLoc.detail.workType("Reference").click();
      await expect(casePage.dashboardLoc.detail.optionWorkType("Active")).toBeVisible();
      await casePage.dashboardLoc.detail.optionWorkType("Active").click();
      await expect(casePage.dashboardLoc.detail.workType("Active")).toBeVisible();
    });

    await test.step("Verify client back to active in list client", async () => {
      await casePage.open();

      //Veriy total entries changed 
      expect(totalActiveEntries + 1).toBe(await casePage.getTotalEntriesByTabs("cases", "0,1", false));
      expect(totalReferenceEntries).toBe(await casePage.getTotalEntriesByTabs("cases", "2", false));

      //Veriy in tab Active
      await casePage.dashboardLoc.table.tabInTable("Active").click();
      await casePage.search(caseId);
      await expect(casePage.dashboardLoc.table.itemInRow(caseId)).toBeVisible();

      //Verify in tab Reference
      await casePage.dashboardLoc.table.tabInTable("Reference").click();
      await casePage.search(caseId);
      await expect(casePage.dashboardLoc.table.itemInRow(caseId)).not.toBeVisible();
    });

    await test.step("Teardown: Archive case and customer", async () => {
      await apiHelper.archiveCase(caseId);
      await apiHelper.archiveCustomer(customerId);
    })
  });

  test("CASE_044 - Verify tab view all ", {
    tag: ['@CASE_044', '@case', '@function']
  }, async ({ conf }) => {
    let totalBeforeSearch: number = 0;
    let totalAfterSearch: number = 0;
    const tabs = [
      { name: "All", types: "0,1,2" },
      { name: "Active", types: "0,1" },
      { name: "Reference", types: "2" }
    ];

    await test.step("Verify total in tab", async () => {
      // Fetch all API totals
      const apiTotals = await Promise.all(
        tabs.map(tab => casePage.getTotalEntriesByTabs("cases", tab.types, false))
      );
      expect(apiTotals[0]).toBe(apiTotals[1] + apiTotals[2]);

      // Fetch UI totals
      await casePage.waitAllRequestCompeleted();
      const uiTotals = await Promise.all(
        tabs.map(tab => casePage.dashboardLoc.common.spanCountByTab(tab.name).innerText().then(Number))
      );
      expect(uiTotals[0]).toBe(uiTotals[1] + uiTotals[2]);
      totalBeforeSearch = uiTotals[0];
      // Verify each tab shows correct total in table and compare API vs UI
      for (let i = 0; i < tabs.length; i++) {
        await casePage.dashboardLoc.table.tabInTable(tabs[i].name).click();
        await expect(casePage.dashboardLoc.table.entriesTotal).toContainText(`${uiTotals[i]}`);
        expect(uiTotals[i]).toBe(apiTotals[i]);
      }
    });

    await test.step("Verify when search and change tab", async () => {
      await casePage.search(conf.data.client_name);
      await casePage.waitAllRequestCompeleted();

      const apiTotals = await Promise.all(
        tabs.map(tab => casePage.getTotalEntriesByTabs("cases", tab.types, false, "s=Auto+Test+Duy+Nhat+123"))
      );
      expect(apiTotals[0]).toBe(apiTotals[1] + apiTotals[2]);

      await casePage.waitForSecond(2); // Wait for UI to update after search

      const uiTotals = await Promise.all(
        tabs.map(tab => casePage.dashboardLoc.common.spanCountByTab(tab.name).innerText().then(Number))
      );
      expect(uiTotals[0]).toBe(uiTotals[1] + uiTotals[2]);
      totalAfterSearch = uiTotals[0];
      expect(totalAfterSearch).toBeLessThan(totalBeforeSearch);

      // Verify each tab shows correct total in table and compare API vs UI
      for (let i = 0; i < tabs.length; i++) {
        await casePage.dashboardLoc.table.tabInTable(tabs[i].name).click();
        await expect(casePage.dashboardLoc.search.inputSearch).toHaveValue(conf.data.client_name);
        await expect(casePage.dashboardLoc.table.entriesTotal).toContainText(`${uiTotals[i]}`);
        expect(uiTotals[i]).toBe(apiTotals[i]);
      }
    });
  });
});
