import { Locator } from '@playwright/test';
import { test, expect } from '../../../fixtures/index';
import { LoginPage } from '../../../pom/login.page';
import { MemberPage } from '../../../pom/member.page';

test.describe('Function case for member tests', async () => {
  let loginPage: LoginPage;
  let memberPage: MemberPage;

  test.beforeEach(async ({ page, conf }) => {
    loginPage = new LoginPage(page);
    memberPage = new MemberPage(page);

    await loginPage.open();
    await loginPage.login(conf.data.username, conf.data.password);
    await expect(loginPage.baseLoc.dashboardContainer).toBeVisible();

    await memberPage.open();
  });

  test('SETTING_008 - Verify when change entries per page', {
    tag: ['@SETTING_008', '@settings', '@function']
  }, async ({ page }) => {
    await test.step('Select "10" entries per page', async () => {
      await memberPage.dashboardLoc.search.perPage.input.fill('10');
      await memberPage.page.keyboard.press('Enter');

      await expect(async () => {
        const rowCount = await memberPage.getTableRowCount();
        expect(rowCount).toBeLessThanOrEqual(10);
      }).toPass();
    });

    await test.step('Select "25" entries per page', async () => {
      await memberPage.dashboardLoc.search.perPage.input.fill('25');
      await memberPage.page.keyboard.press('Enter');

      await expect(async () => {
        const rowCount = await memberPage.getTableRowCount();
        expect(rowCount).toBeLessThanOrEqual(25);
      }).toPass();
    });
  });

  test('SETTING_009 - Verify feature sort member', {
    tag: ['@SETTING_009', '@settings', '@function']
  }, async ({ page }) => {
    const displayNames = ['Full Name', 'Phone Number', 'Email Address', 'Address', 'Status'];
    const sortedFieldName = ['full_name', 'phone_number', 'user_id', 'user_id', 'status'];
    const propertyNames = ['full_name', 'phone_number', 'email_address', 'address', 'status'];
    const directions = ['asc', 'asc', 'asc', 'desc', 'asc'];
    const defaultPerPage = 10;
    const defaultPage = 1;
    for (let i = 0; i < displayNames.length; i++) {
      await expect(memberPage.dashboardLoc.table.headingColumn(displayNames[i])).toBeVisible();
      await memberPage.dashboardLoc.table.headingColumn(displayNames[i]).click();
      await expect(memberPage.page).toHaveURL(
        new RegExp(`.*sort=${sortedFieldName[i]}&direction=${directions[i]}`)
      );

      let apiDataUrl = `setting/members?return_type=json&per_page=${defaultPerPage}&page=${defaultPage}&sort=${propertyNames[i]}&direction=${directions[i]}`;
      const data = await memberPage.getDataInTable(displayNames[i], propertyNames[i], apiDataUrl);
      console.log(`Sort by: ${displayNames[i]}, direction: ${directions[i]}, property: ${propertyNames[i]}`)
      if (displayNames[i] === 'Status') {
        expect(data.dataApi).toEqual(data.dataUI.map(item => item.toUpperCase()));
      } else {
        expect(data.dataApi).toEqual(expect.arrayContaining(data.dataUI));
      }
    }
  });

  test('SETTING_007 - Verify feature customized columns', {
    tag: ['@SETTING_007', '@settings', '@function']
  }, async ({ page }) => {
    // Verify default columns displayed
    await test.step("Verify default columns displayed", async () => {
      const customizedColumns = memberPage.memberProps.customizedColumns;
      for (let i = 0; i < customizedColumns.length; i++) {
        if (customizedColumns[i].default) {
          await expect(memberPage.dashboardLoc.table.headingColumn(customizedColumns[i].tableDisplayName)).toBeVisible();
        }
      }
    });

    // Verify customized column show disable items and active items
    await test.step("Verify customized columns popup state", async () => {
      await memberPage.openCustomizedColumn();

      // Verify enabled column and disabled column
      const customizedColumns = memberPage.memberProps.customizedColumns;
      for (let i = 0; i < customizedColumns.length; i++) {
        if (customizedColumns[i].default) {
          await expect(memberPage.dashboardLoc.listing.popup.customizedColumn.columnCheckbox(customizedColumns[i].name)).toBeDisabled();
        } else {
          await expect(memberPage.dashboardLoc.listing.popup.customizedColumn.columnCheckbox(customizedColumns[i].name)).toBeEnabled();
        }
      }
    });

    // Pre-condition: disable all enabled column
    await test.step("Pre-condition: disable all enabled column", async () => {
      const customizedColumns = memberPage.memberProps.customizedColumns;
      for (let i = 0; i < customizedColumns.length; i++) {
        if (!customizedColumns[i].default) {
          await memberPage.dashboardLoc.listing.popup.customizedColumn.columnCheckbox(customizedColumns[i].name).setChecked(false);
        }
      }
    });

    // Check each columns and verify it shown
    await test.step("Check each columns and verify it shown", async () => {
      await memberPage.open();
      const customizedColumns = memberPage.memberProps.customizedColumns.filter(column => !column.default);
      for (let i = 0; i < customizedColumns.length; i++) {
        await memberPage.openCustomizedColumn();
        await memberPage.waitForSecond(0.5);
        await memberPage.dashboardLoc.listing.popup.customizedColumn.columnCheckbox(customizedColumns[i].name).setChecked(true);
        await memberPage.dashboardLoc.listing.popup.customizedColumn.btnApply.click();
        await expect(memberPage.dashboardLoc.listing.heading.headingColumn(customizedColumns[i].tableDisplayName)).toBeVisible();
      }
    });

    // Uncheck each columns and verify it hidden
    await test.step("Uncheck each columns and verify it hidden", async () => {
      await memberPage.open();
      await memberPage.waitAllRequestCompeleted();
      const customizedColumns = memberPage.memberProps.customizedColumns.filter(column => !column.default);
      // TODO: change to all columns. We're facing with some issues with the last column
      for (let i = 0; i < customizedColumns.length - 1; i++) {
        await memberPage.openCustomizedColumn();
        await memberPage.dashboardLoc.listing.popup.customizedColumn.columnCheckbox(customizedColumns[i].name).setChecked(false);
        await memberPage.dashboardLoc.listing.popup.customizedColumn.btnApply.click();
        await expect(memberPage.dashboardLoc.listing.heading.headingColumn(customizedColumns[i].tableDisplayName)).not.toBeVisible();
      }
    });
  });

  
  test("SETTING_023 - Verify update detail member", {
    tag: ['@SETTING_023', '@settings', '@function']
  }, async ({ conf }) => {
    let inputFields = memberPage.memberDetail.inputDetailForm;

    await test.step("Verify search member exist", async () => {
      await memberPage.dashboardLoc.search.inputSearch.fill(conf.data.member_exist);

      await expect(memberPage.dashboardLoc.table.itemInRow(conf.data.member_exist)).toBeVisible();
      await memberPage.dashboardLoc.table.itemInRow(conf.data.member_exist).click();
      await expect(memberPage.memberLoc.detailPage).toBeVisible();
    })

    await test.step("Fill invalid data", async () => {
      for (let i = 0; i < inputFields.length; i++) {
        const fieldLocator = memberPage.memberDetail.inputField(inputFields[i].name);
        await fieldLocator.fill(conf.data.invalid_data);
        await expect(fieldLocator).toHaveValue(conf.data.invalid_data);
        await memberPage.waitForSecond(1);
        await memberPage.memberLoc.btnUpdateDetail.click();
        await expect(memberPage.dashboardLoc.creating.errorInput(inputFields[i].error)).toBeVisible();
      }
    })

    await test.step("Fill valid data", async () => {
      for (let i = 0; i < inputFields.length; i++) {
        const fieldLocator = memberPage.memberDetail.inputField(inputFields[i].name);
        await fieldLocator.fill(conf.data.valid_data);
        await expect(fieldLocator).toHaveValue(conf.data.valid_data);
      }
      
      await memberPage.waitForSecond(1);
      await memberPage.memberLoc.btnUpdateDetail.click();
      await expect(memberPage.baseLoc.updateSuccessNotification).toBeVisible();
    })
  })
});