import { UniDriver } from '@wix/wix-ui-test-utils/unidriver';
import {
  CheckboxUniDriver,
  InfoIconUniDriver,
  SidePanelUniDriver,
  TooltipUniDriver,
  SearchUniDriver,
} from '@wix/design-system/dist/testkit/unidriver';
import { SlidingModalUniDriver } from '../SlidingModal/SlidingModal.uni.driver';
import { DragAndDropUniDriver } from '../DragAndDrop/DragAndDrop.uni.driver';
import { CustomFieldPopoverUniDriver } from '../CustomFieldsPanel/CustomFieldPopover.uni.driver';
import { CustomFieldsDisabledHintUniDriver } from '../CustomFields/CustomFieldsDisabledHint.uni.driver';
import { EmptyStateUniDriver } from '../EmptyState/EmptyState.uni.driver';
import { ArchivedItemsPanelUniDriver } from '../ArchivedItemsPanel/ArchivedItemsPanel.uni.driver';

export function CustomColumnsPanelUniDriver(base: UniDriver, body: UniDriver) {
  const panelBase = () => base.$('[data-hook="custom-columns-panel"]');
  const panel = () => SidePanelUniDriver(panelBase(), body);

  const slidingModal = () =>
    SlidingModalUniDriver(base.$('[data-hook="cairo-side-panel-modal"]'), body);

  const addItem = () =>
    CustomFieldsDisabledHintUniDriver(base, body, {
      dataHook: 'custom-columns-data-extension-add-new',
    });

  const list = () => panelBase().$('[data-hook="custom-columns-list"]');
  const getDragAndDropDriver = () => DragAndDropUniDriver(list());
  const items = () => panelBase().$$('[data-hook="custom-columns-list"] > div');
  const getItemAtBase = (i: number) => items().get(i);

  const getItemByIdBase = (id: string) =>
    list().$(`[data-hook="column-item-${id}"]`);

  const getSearch = () =>
    SearchUniDriver(panelBase().$('[data-hook="custom-columns-search"]'), body);

  const getNoResults = () =>
    EmptyStateUniDriver(
      panelBase().$('[data-hook="custom-columns-no-results-state"]'),
      body,
    );

  const getCheckboxAt = (i: number) => {
    const getCheckboxBase = () =>
      getItemAtBase(i).$('[data-hook="tableListItem-checkbox"]');

    return {
      wait: (timeout?: number) => getItemAtBase(i).wait(timeout),
      getLabel: () =>
        getItemAtBase(i).$('[data-hook="tableListItem-label"]').text(),
      getTooltipContent: () =>
        CheckboxUniDriver(getCheckboxBase(), body).getTooltipContent(),
      isChecked: () => CheckboxUniDriver(getCheckboxBase(), body).isChecked(),
      isDisabled: () => CheckboxUniDriver(getCheckboxBase(), body).isDisabled(),
      click: () => CheckboxUniDriver(getCheckboxBase(), body).click(),
      exists: () => getCheckboxBase().exists(),
    };
  };

  const customFieldPopoverMenuAt = (i: number) =>
    CustomFieldPopoverUniDriver(getItemAtBase(i), body);

  const getDragHandle = (base: UniDriver) =>
    base.$('[data-hook="tableListItem-dragHandle"]');

  const getCheckboxById = (id: string) => {
    const getCheckboxBase = () =>
      getItemByIdBase(id).$('[data-hook="tableListItem-checkbox"]');

    return {
      wait: (timeout?: number) => getItemByIdBase(id).wait(timeout),
      getLabel: () =>
        getItemByIdBase(id).$('[data-hook="tableListItem-label"]').text(),
      getTooltipContent: () =>
        CheckboxUniDriver(getCheckboxBase(), body).getTooltipContent(),
      isChecked: () => CheckboxUniDriver(getCheckboxBase(), body).isChecked(),
      isDisabled: () => CheckboxUniDriver(getCheckboxBase(), body).isDisabled(),
      click: () => CheckboxUniDriver(getCheckboxBase(), body).click(),
      exists: () => getCheckboxBase().exists(),
    };
  };

  const addNewExists = () => addItem().exists();
  const clickAddNew = () => addItem().click();

  // Archived items functionality
  const getArchivedItemsButton = () =>
    base.$('[data-hook="custom-columns-archived-items-button"]');

  const getArchivedPanel = () =>
    ArchivedItemsPanelUniDriver(base, body, 'custom-columns');

  return {
    exists: () => panelBase().exists(),
    isOpen: () =>
      Promise.all([slidingModal().isOpen(), panel().exists()]).then((arr) =>
        arr.every(Boolean),
      ),
    getTitle: () => panel().getTitleText(),
    getSubtitle: () => panel().getSubtitleText(),
    clickCloseButton: () => panel().clickClose(),
    closeButtonExists: () => panel().isCloseButtonExists(),
    checkOptions: async (ids: string[]) => {
      for (const id of ids) {
        const checkbox = getCheckboxById(id);
        await checkbox.wait();
        await checkbox.click();
      }
    },
    getCheckboxAt,
    getCheckboxById,
    dragHandleExistsAt: (i: number) => getDragHandle(getItemAtBase(i)).exists(),
    dragHandleLockedAt: async (i: number) =>
      (await getDragHandle(getItemAtBase(i))
        .$('[data-hook="drag-handle-button"]')
        .attr('data-disabled')) === 'true',
    _dragHandleTooltipById: (id: string) =>
      TooltipUniDriver(
        getItemByIdBase(id).$('[data-hook="tableListItem-dragHandle"]'),
        body,
      ),
    dragStart: async (sourceIndex: number) =>
      getDragAndDropDriver().dragStart(await getItemAtBase(sourceIndex)),
    dragMove: () => getDragAndDropDriver().dragMove(),
    dragEnd: async (targetIndex: number) =>
      getDragAndDropDriver().dragEnd(await getItemAtBase(targetIndex)),
    getCheckboxesCount: () => items().count(),
    getTitles: () =>
      items().map((item) => item.$('[data-hook="tableListItem-label"]').text()),
    getCustomColumnInfoIconAt: (index: number) =>
      InfoIconUniDriver(
        getItemAtBase(index).$('[data-hook="info-icon"]'),
        body,
      ),
    addNewExists,
    clickAddNew,
    getAddCustomFieldCTAButton: () => addItem(),
    customFieldPopoverMenuAt,
    getCustomFieldOptionsAt: (i: number) =>
      customFieldPopoverMenuAt(i).getCustomFieldOptionsAt(),
    customFieldPopoverMenuExistsAt: (i: number) =>
      customFieldPopoverMenuAt(i).exists(),
    _getDragAndDropDriver: getDragAndDropDriver,
    _getItemAtBase: getItemAtBase,
    // Search functionality
    searchExists: () => getSearch().inputDriver.exists(),
    enterSearchText: (value: string) =>
      getSearch().inputDriver.enterText(value),
    clearSearchText: () => getSearch().inputDriver.clearText(),
    getSearchText: () => getSearch().inputDriver.getText(),
    clickSearchClear: () => getSearch().inputDriver.clickClear(),
    getSearchPlaceholder: () => getSearch().inputDriver.getPlaceholder(),
    // No results functionality
    noResultsExists: () => getNoResults().exists(),
    getNoResultsTitle: () => getNoResults().getTitleText(),
    getNoResultsSubtitle: () =>
      panelBase().$('[data-hook="custom-columns-no-results-subtitle"]').text(),
    getNoResultsResetButton: () =>
      getNoResults().getButton('custom-columns-no-results-reset-button'),
    // Archived items functionality
    archivedItemsButtonExists: () => getArchivedItemsButton().exists(),
    clickArchivedItemsButton: () => getArchivedItemsButton().click(),
    getArchivedItemsButtonText: () =>
      getArchivedItemsButton().$('[data-hook="tableListItem-label"]').text(),
    getArchivedPanel: () => getArchivedPanel(),
  };
}
