import { faker } from '@faker-js/faker';
import { expect } from '@playwright/test';

// Generate current date in proper form
let date = new Date();
let day = date.getDate();
let month = date.getMonth() + 1;
let year = date.getFullYear();
let todaysDate = `${day}.${month}.${year}`;

export async function loginAsUser(page, login, password) {
  await page.getByTestId('Uživatelské jméno').fill(login);
  await page.getByTestId('Heslo').fill(password);
  await page.getByTestId('Přihlásit').click();
}

export async function logOut(page) {
  await page.getByTestId('settings').click();
  await page.getByTestId('Odhlásit').click();
}

export async function pruchodStavyLafa(page, states) {
  for (let i = 0; i < states.length - 1; i++) {
    const tlacitko = `${states[i]}_to_${states[i + 1]}`;
    await expect(page.locator('body')).toContainText(states[i]);
    await page.click(`[data-testid = "${tlacitko}"]`);
    await expect(page.locator('body')).toContainText(states[i + 1]);
  }
}

export async function pruchodStavy(page, states) {
  await page.click(`[data-testid = "${states[0]}"]`);
  await pruchodStavyLafa(page, states);
}

export function randomInt(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

export function buttonFromPosition(page, line, column) {
  const selector = `[data-cy="button-1-${line}-${column}-0"]`;
  return page.locator(selector);
}

export async function testovaniHodnotRadku(page, line, column) {
  const button = buttonFromPosition(page, line, column);
  const hodnota = parseInt(await button.getAttribute('data-testid'));

  for (let i = 1; i < column; i++) {
    const btn = buttonFromPosition(page, line, i);
    const val = parseInt(await btn.getAttribute('data-testid'));
    if (val > hodnota) {
      throw new Error(
        `Value at column ${i} is greater than the value in column ${column}`
      );
    }
  }

  for (let i = column; i <= 10; i++) {
    const btn = buttonFromPosition(page, line, i);
    const val = parseInt(await btn.getAttribute('data-testid'));
    if (val < hodnota) {
      throw new Error(
        `Value at column ${i} is less than the value in column ${column}`
      );
    }
  }
}

export async function testovaniHodnotMaximalniDopad(page) {
  for (let i = 1; i <= 10; i++) {
    let max = 0;
    for (let j = 0; j <= 4; j++) {
      const button = buttonFromPosition(page, j, i);
      const value = parseInt(await button.getAttribute('data-testid'));
      if (value > max) max = value;
    }
    const badge = page.locator(`[data-cy="badge-1-5-${i}-0"]`);
    const badgeValue = parseInt(await badge.getAttribute('data-testid'));
    if (max !== badgeValue) {
      throw new Error(
        `Max value (${max}) does not match badge value (${badgeValue}) for column ${i}`
      );
    }
  }
}

export async function formControlFilling(page, dtid, input = ' ') {
  const form = page.locator(`[data-testid="${dtid}"]`).first();
  await form.click();
  await form.fill(input);
  await expect(form).toHaveValue(new RegExp(input, 'i'));
}

export async function textboxFilling(page, dtid, input = ' ') {
  const inputField = page
    .locator(`[data-testid="${dtid}"]`)
    .getByRole('textbox')
    .first();
  await inputField.fill(input);
}

export async function searchInputFilling(page, dtid, input = ' ') {
  const inputField = page.locator(`[data-testid="${dtid}"]`);
  await inputField.getByTestId('icon-angle-down').click();
  await inputField.type(input);
  await expect(page.getByText('Vyhledávám možnosti.')).not.toBeVisible({
    timeout: 90000,
  });
  const option = page.locator('[data-testid^="option-"]').first();
  await option.click();
  await inputField.waitFor({ state: 'visible' });
}

export async function textInputFilling(page, dtid, input = ' ') {
  const inputField = page.locator(`[data-testid="${dtid}"]`).first();
  await expect(inputField).toBeVisible();
  await inputField.fill(input);
  await expect(inputField).toHaveValue(input);
}

export async function nameCreate(page, dtid, input) {
  let counter = 1;
  const inputField = page.locator(`[data-testid="${dtid}"]`).locator('input');
  await inputField.fill(`${input} ${counter} ${todaysDate}`);
  counter++;
}

export async function dropdownInputFilling(page, dtid) {
  //používám v případě, kdy je jedno jakou možnost z výběru použiju
  await page.locator(`[data-testid="${dtid}"]`).first().click();
  await page.locator('[data-testid^="option-"]').nth(1).click({ force: true });
}

export async function selectInputFilling(page, dtid, input = ' ') {
  const inputField = page.locator(`[data-testid="${dtid}"]`);
  await inputField.waitFor({ state: 'visible', timeout: 10000 });
  await inputField.click();
  await inputField.type(input, { delay: 100 });
  await page.waitForTimeout(3000);
  await page
    .locator('[data-testid^="option-"]')
    .first()
    .waitFor({ state: 'visible', timeout: 10000 });
  await page.locator('[data-testid^="option-"]').first().click();
  await expect(inputField).toContainText(new RegExp(input, 'i'));
}

export async function pickOption(page, dtid, select) {
  const dropdown = page
    .locator(`[data-testid = "${dtid}"]`)
    .getByTestId('icon-angle-down')
    .first();
  await dropdown.click();
  await page.getByText(select, { exact: true }).first().click({ force: true });
}

export async function navigateToApp(page) {
  await page.getByTestId('Aplikace').click();
  await expect(page).toHaveURL(/.*eam/);
  await page.getByTestId('Aplikace').click();
  await expect(page).toHaveURL(/.*Application/);
  await expect(page.getByText('Načítám data z registru.')).toBeHidden();
  await expect(page.locator('.table-striped')).toBeVisible();
}

export async function navigateToSoftwarePack(page) {
  await page.getByTestId('Aplikace').click();
  await expect(page).toHaveURL(/.*eam/);
  await page.getByTestId('Software Packy').click();
  await expect(page).toHaveURL(/.*SoftwarePack/);
  await expect(page.getByText('Načítám data z registru.')).toBeHidden();
  await expect(page.locator('.table-striped')).toBeVisible();
}

export async function navigateToTRMProdukt(page) {
  await page.getByTestId('IT Platformy').click();
  await expect(page).toHaveURL(/.*\/gui\/kma/);
  await page.getByText('TRM Produkty').click();
  await expect(page).toHaveURL(/.*\/gui\/TrmAssetClass/);
  await expect(page.getByText('Načítám data z registru.')).toBeHidden();
  await expect(page.locator('.table-striped')).toBeVisible();
}

export async function navigateToTRMAsset(page) {
  await page.getByTestId('IT Platformy').click();
  await expect(page).toHaveURL(/.*\/gui\/kma/);
  await page.getByText('TRM Assety').click();
  await expect(page).toHaveURL(/.*\/gui\/TrmAsset/);
  await expect(page.getByText('Načítám data z registru.')).toBeHidden();
  await expect(page.locator('.table-striped')).toBeVisible();
}

export async function navigateToTRMAssetInstance(page) {
  await page.getByTestId('IT Platformy').click();
  await expect(page).toHaveURL(/.*\/gui\/kma/);
  await page.getByText('Instance TRM Assetů').click();
  await expect(page).toHaveURL(/.*\/gui\/TrmAssetInstance/);
  await expect(page.getByText('Načítám data z registru.')).toBeHidden();
  await expect(page.locator('.table-striped')).toBeVisible();
}

export async function navigateToTRMFLC(page) {
  await page.getByTestId('IT Platformy').click();
  await expect(page).toHaveURL(/.*\/gui\/kma/);
  await page.getByText('TRM FLC').click();
  await expect(page).toHaveURL(/.*\/gui\/TrmFlc/);
  await expect(page.getByText('Načítám data z registru.')).toBeHidden();
  await expect(page.locator('.table-striped')).toBeVisible();
}

export async function navigateToFLCApplication(page) {
  await page.getByTestId('Aplikace').click();
  await expect(page).toHaveURL(/.*eam/);
  await page.getByTestId('FLC Aplikace').click();
  await expect(page).toHaveURL(/.*EamFlc/);
  await expect(page.getByText('Načítám data z registru.')).toBeHidden();
  await expect(page.locator('.table-striped')).toBeVisible();
}

export async function navigateToExtApp(page) {
  await page.getByTestId('Aplikace').click();
  await expect(page).toHaveURL(/.*eam/);
  await page.getByTestId('Externí apl. služby').click();
  await expect(page).toHaveURL(/.*ExternalApplication/);
  await expect(page.getByText('Načítám data z registru.')).toBeHidden();
  await expect(page.locator('.table-striped')).toBeVisible();
}

export async function navigateToBia(page) {
  await page.getByTestId('icon-tools').click();
  await page.getByTestId('BIA Procesní').click();
  await expect(page).toHaveURL(/.*ProcesniBia/);
  await expect(page.getByText('Načítám data z registru.')).toBeHidden();
  await page.waitForTimeout(5000);
  await expect(page.getByTestId('data-table')).toBeVisible();
}

export async function navigateToBacklogArea(page) {
  await page.getByTestId('NDB Backlog').click();
  await page.getByTestId('Oblasti (Area)').click();
  await expect(page).toHaveURL(/.*ClientNeedArea/);
  await expect(page.getByTestId('data-table')).toBeVisible();
}

export async function navigateToReports(page) {
  await page.getByTestId('Administrace').click();
  await page.getByTestId('Reporty').click();
  await expect(page).toHaveURL(/.*reports/);
  await page.getByText('BIA').click();
}

export async function tab(page, tabName) {
  await page
    .locator('.nav-item', { hasText: tabName })
    .first()
    .click({ force: true });
  await expect(page).toHaveURL(new RegExp(`.*${tabName}`));
  await expect(page.getByText('Načítám data z registru.')).not.toBeVisible();
}

export async function futureDate(page, fieldLabel) {
  // open calendar dropdown
  await expect(page.getByText(fieldLabel)).toBeVisible();
  page.getByText(fieldLabel).click();
  await expect(page.locator('.react-datepicker__year-select')).toBeVisible();

  const randomfutureDate = faker.date.future(0.25);
  const year = randomfutureDate.getFullYear();
  const month = randomfutureDate.getMonth();
  const day = randomfutureDate.getDate();

  await page.locator('.react-datepicker__year-select').selectOption(year.toString());
  await page.locator('.react-datepicker__month-select').selectOption(month.toString());
  await page.locator(`.react-datepicker__day:has-text("${day}")`).first().click();
}

export async function checkReport(page) {
  await expect(page).toHaveURL(/.*detail/);
  await expect(page.getByText('Přerušit úlohu')).toBeVisible();
  await expect(page.getByText('Generování dokumentu')).toBeVisible();
  await expect(page.getByText('Načítám data z registru.')).not.toBeVisible();
  await expect(page.getByText(/Spuštěno/)).toBeVisible();
  await expect(page.getByText(/Výstup ke stažení/)).toBeVisible();
}

export async function disabledFields(page) {
  await expect(page.getByText('Načítám data z registru.')).not.toBeVisible();
  const elements = page.locator('.form-control');
  const count = await elements.count();
  for (let i = 0; i < count; i++) {
    const element = elements.nth(i);
    await expect(element).toBeDisabled();
  }
}

export async function handleFilterRow(page) {
  const filterRow = page.locator('[data-testid="filter-row"]');
  await expect(page.locator('.table ')).toBeVisible();

  if (await filterRow.isVisible()) {
    await page.getByTestId('icon-trash').click({ force: true });
  } else {
    await page.getByTestId('DT-filter-control-switcher').click();
    await expect(filterRow).toBeVisible();
    await page.getByTestId('icon-trash').click({ force: true });
  }
}
