import { test, expect } from '../../../fixtures/index';
import { LoginPage } from '../../../pom/login.page';
import { GeneralPage } from '../../../pom/setting/general.page';
import { randomString } from '../../../utils/array';

test.describe('UI case for hashtag tests', async () => {
  let loginPage: LoginPage;
  let generalPage: GeneralPage;

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

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

    await generalPage.open();
  });

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

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

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

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

  test('SETTING_015 - Verify feature sort Hashtags', {
    tag: ['@SETTING_015', '@general', '@function']
  }, async ({ page }) => {
    const displayNames = ['Hashtag', 'Category', 'Description'];
    const sortedFieldName = ['name', 'type', 'description'];
    const propertyNames = ['name', 'type', 'description'];
    const directions = ['asc', 'asc', 'asc'];
    const defaultPerPage = 10;
    const defaultPage = 1;
    for (let i = 0; i < displayNames.length; i++) {
      await expect(generalPage.dashboardLoc.table.headingColumn(displayNames[i])).toBeVisible();
      await generalPage.dashboardLoc.table.headingColumn(displayNames[i]).click();
      await expect(generalPage.page).toHaveURL(
        new RegExp(`.*sort=${sortedFieldName[i]}&direction=${directions[i]}`)
      );

      let apiDataUrl = `general/hashtags?return_type=json&per_page=${defaultPerPage}&page=${defaultPage}&sort=${propertyNames[i]}&direction=${directions[i]}`;
      const data = await generalPage.getDataInTableGenaral(displayNames[i], propertyNames[i], apiDataUrl);
      console.log(`Sort by: ${displayNames[i]}, direction: ${directions[i]}, property: ${propertyNames[i]}`)
      expect(data.dataApi).toEqual(data.dataUI);
    }
  });

  test('SETTING_016 - Verify UI Add new Hashtags', {
    tag: ['@SETTING_016', '@general', '@function']
  }, async ({ page }) => {
    await test.step("Click the 'Add New' button to open the Add Hashtag form", async () => {
      await generalPage.generalLoc.btnAddNew.click();
    })

    await test.step("Observe the form fields and buttons.", async () => {
      await expect(page.locator('#root')).toMatchAriaSnapshot(`
        - heading "Hashtag" [level=3]
        - button "Close"
        `);

      await expect(page.locator('#root')).toMatchAriaSnapshot(`
          - text: Category *
          - textbox "Category *"
          - text: Hashtag *
          - textbox "Hashtag *"
          - text: Description
          - textbox "Description"
          `);

      await expect(page.locator('#root')).toMatchAriaSnapshot(`
          - button "Cancel"
          - checkbox "Create another"
          - text: Create another
          - button "Create"
          `);
    })
  });

  test('SETTING_017 - Verify validation Add new Hashtags', {
    tag: ['@SETTING_017', '@general', '@function']
  }, async ({ page }) => {
    await test.step("Click the 'Add New' button to open the Add Hashtag form", async () => {
      await generalPage.generalLoc.btnAddNew.click();

      await expect(page.locator('#root')).toMatchAriaSnapshot(`
          - heading "Hashtag" [level=3]
          - button "Close"
          `);
    })

    await test.step("Leave the 'Category' field empty and click 'Create'.", async () => {
      await generalPage.dashboardLoc.modal.inputByPlaceHolder("Enter hashtag").fill('test');
      await generalPage.dashboardLoc.modal.inputByPlaceHolder("Enter description").fill('test');
      await page.getByRole('button', { name: 'Create' }).click();
      await expect(page.getByText('Category is required.')).toBeVisible();
    })

    await test.step("Leave the 'Category' field empty and click 'Create'.", async () => {
      await generalPage.dashboardLoc.modal.inputByPlaceHolder("Select a category").click();
      await generalPage.dashboardLoc.modal.headerModal("Hashtag").click();;
      await page.waitForTimeout(2000)
      await generalPage.dashboardLoc.modal.inputByPlaceHolder("Enter hashtag").fill('');
      await expect(page.getByText('The name field is required.')).toBeVisible();
    })
  });

  test('SETTING_018 - Verify when user create success hashtags without Create another', {
    tag: ['@SETTING_018', '@general', '@function']
  }, async ({ page }) => {
    let hashtag = {
      type_name: 'Contact',
      name: randomString(10),
      description: randomString(10),
      createAnother: false
    }

    await test.step("Leave the 'Category' field empty and click 'Create'.", async () => {
      await generalPage.addNewHashtag(hashtag);

      // Verify show notification
      await expect(generalPage.generalLoc.notificationAddNewHashtagSuccess).toBeVisible();
      await generalPage.generalLoc.btnClosePopupNotification.click();
      await expect(generalPage.generalLoc.notificationAddNewHashtagSuccess).not.toBeVisible();

      // Verify show hashtag info in table
      const { name, type_name, description } = generalPage.getXpathHashtagInfoBy(hashtag.name, hashtag.type_name, hashtag.description);
      await expect(generalPage.page.locator(name)).toBeVisible();
      await expect(generalPage.page.locator(type_name).first()).toBeVisible();
      await expect(generalPage.page.locator(description)).toBeVisible();
    })
  });

  test('SETTING_019 - Verify when user create success hashtags with Create another', {
    tag: ['@SETTING_019', '@general', '@function']
  }, async ({ page }) => {
    let hashtag = {
      type_name: 'Case',
      name: randomString(10),
      description: randomString(10),
      createAnother: true
    }

    await test.step("Add new hashtag", async () => {
      await generalPage.addNewHashtag(hashtag);

      // Verify show notification
      await expect(generalPage.generalLoc.notificationAddNewHashtagSuccess).toBeVisible();
      await generalPage.generalLoc.btnClosePopupNotification.click();
      await expect(generalPage.generalLoc.notificationAddNewHashtagSuccess).not.toBeVisible();

      // Verify form is still open
      await expect(page.locator('#root')).toMatchAriaSnapshot(`
          - heading "Hashtag" [level=3]
          - button "Close"
          `);

      await generalPage.generalLoc.btnClose.click();

      // Verify show hashtag info in table
      const { name, type_name, description } = generalPage.getXpathHashtagInfoBy(hashtag.name, hashtag.type_name, hashtag.description);
      await expect(generalPage.page.locator(name)).toBeVisible();
      await expect(generalPage.page.locator(type_name).first()).toBeVisible();
      await expect(generalPage.page.locator(description)).toBeVisible();
    })
  });

  test('SETTING_020 - Verify when user create fail with Category already contains this hashtag', {
    tag: ['@SETTING_020', '@general', '@function']
  }, async ({ page }) => {
    let hashtag = { 
      type_name: 'Contact',
      name: 'Member',
      description: randomString(10),
      createAnother: false
    }

    await test.step("Add new hashtag", async () => {
      await generalPage.addNewHashtag(hashtag);

      // Verify not show notification
      await expect(generalPage.generalLoc.notificationAddNewHashtagSuccess).not.toBeVisible();

      // Verify show error msg
      await expect(page.getByText('This category already')).toBeVisible();
    })
  });

  test('SETTING_021 - Verify when user edit hashtag (success, fail)', {
    tag: ['@SETTING_021', '@general', '@function']
  }, async ({ page }) => {
    let hashtag = {
      type_name: 'Contact',
      name: randomString(10),
      description: randomString(10),
      createAnother: false
    }

    let newHashtag: { name: any; description: any; };

    await test.step("Add new hashtag", async () => {
      await generalPage.addNewHashtag(hashtag);

      // Verify show notification
      await expect(generalPage.generalLoc.notificationAddNewHashtagSuccess).toBeVisible();
      await generalPage.generalLoc.btnClosePopupNotification.click();
    })

    await test.step("Edit hashtag", async () => {
      newHashtag = {
        name: randomString(10),
        description: randomString(10),
      }
      await generalPage.editHashtag(hashtag.description, newHashtag);

      // Verify show notification
      await generalPage.waitForSecond(0.5);
      await expect(generalPage.generalLoc.notificationUpdateHashtagSuccess).toBeVisible();
      await generalPage.generalLoc.btnClosePopupNotification.click();
      await expect(generalPage.generalLoc.notificationUpdateHashtagSuccess).not.toBeVisible();

      // Verify show hashtag info in table
      const { name, type_name, description } = generalPage.getXpathHashtagInfoBy(newHashtag.name, hashtag.type_name, newHashtag.description);
      await expect(generalPage.page.locator(name)).toBeVisible();
      await expect(generalPage.page.locator(type_name).first()).toBeVisible();
      await expect(generalPage.page.locator(description)).toBeVisible();
    })

    await test.step("Edit hashtag fail", async () => {
      const existHashtag = {
        name: 'Member',
        description: 'Data Auto Test',
      }
      await generalPage.editHashtag(newHashtag.description, existHashtag);

      // Verify error msg
      await expect(page.getByText('This category already')).toBeVisible();
    })
  });

  test('SETTING_022 - Verify when user delete hashtag', {
    tag: ['@SETTING_022', '@general', '@function']
  }, async ({ page }) => {
    let hashtag = {
      type_name: 'Contact',
      name: randomString(10),
      description: randomString(10),
      createAnother: false
    }

    await test.step("Add new hashtag", async () => {
      await generalPage.addNewHashtag(hashtag);

      // Verify show notification
      await expect(generalPage.generalLoc.notificationAddNewHashtagSuccess).toBeVisible();
      await generalPage.generalLoc.btnClosePopupNotification.click();
      await expect(generalPage.generalLoc.notificationAddNewHashtagSuccess).not.toBeVisible();
    })

    await test.step("Delete hashtag", async () => {
      await generalPage.deleteHashtag(hashtag.description);

      // Verify show notification
      await expect(generalPage.generalLoc.notificationDeleteHashtagSuccess).toBeVisible();
      await generalPage.generalLoc.btnClosePopupNotification.click();
      await expect(generalPage.generalLoc.notificationUpdateHashtagSuccess).not.toBeVisible();
    })
  });
});