import { UniDriver } from '@wix/wix-ui-test-utils/unidriver';
import {
  AddItemUniDriver,
  DropdownUniDriver,
  IconButtonUniDriver,
  SidePanelUniDriver,
} from '@wix/design-system/dist/testkit/unidriver';
import { SlidingModalUniDriver } from '../SlidingModal/SlidingModal.uni.driver';
import { DragAndDropUniDriver } from '../DragAndDrop/DragAndDrop.uni.driver';
import { baseUniDriverFactory } from '../../unidriver';

export function MultiLevelSortingPanelUniDriver(
  base: UniDriver,
  body: UniDriver,
) {
  const panelBase = () => base.$('[data-hook="multi-level-sorting-panel"]');
  const panel = () => SidePanelUniDriver(panelBase(), body);
  const slidingModal = () =>
    SlidingModalUniDriver(base.$('[data-hook="cairo-side-panel-modal"]'), body);
  const list = () => panelBase().$('[data-hook="multi-level-sorting-list"]');
  const getDragAndDropDriver = () => DragAndDropUniDriver(list());
  const items = () =>
    panelBase().$$('[data-hook="multi-level-sorting-list"] > div');
  const getItemAtBase = (i: number) => items().get(i);
  const addItemButton = () =>
    AddItemUniDriver(
      base.$(`[data-hook="multi-level-sorting-add-sort"]`),
      body,
    );

  const clickSortRemoveAtIndex = (index: number) =>
    IconButtonUniDriver(
      getItemAtBase(index).$(`[data-hook="multi-level-sorting-remove-sort"]`),
      body,
    ).click();
  const changeSortOrderAtIndex = (index: number, order: 'asc' | 'desc') => {
    const dropdown = DropdownUniDriver(
      getItemAtBase(index).$(`[data-hook="multi-level-sorting-select-order"]`),
      body,
    );
    return dropdown.dropdownLayoutDriver.clickAtOption(order === 'asc' ? 0 : 1);
  };
  const getSortOrderAtIndex = async (index: number) => {
    const dropdown = DropdownUniDriver(
      getItemAtBase(index).$(`[data-hook="multi-level-sorting-select-order"]`),
      body,
    );
    return dropdown.dropdownLayoutDriver.getSelectedOptionId();
  };
  const changeColumnAtIndex = (index: number, columnIndex: number) => {
    const dropdown = DropdownUniDriver(
      getItemAtBase(index).$(
        `[data-hook="multi-level-sorting-select-column-${index}"]`,
      ),
      body,
    );
    return dropdown.dropdownLayoutDriver.clickAtOption(columnIndex);
  };
  const getColumnAtIndex = (index: number) => {
    const dropdown = DropdownUniDriver(
      getItemAtBase(index).$(
        `[data-hook="multi-level-sorting-select-column-${index}"]`,
      ),
      body,
    );
    return dropdown.dropdownLayoutDriver.getSelectedOptionId();
  };

  return {
    /**
     * Wait until root element to exist
     * @param timeout - time to wait until bailing
     */
    wait: (timeout?: number) => base.wait(timeout),
    ...baseUniDriverFactory(base),
    /** Checks if the panel exist */
    exists: () => panelBase().exists(),
    /** Checks if the SidePanel is open */
    isOpen: () =>
      Promise.all([slidingModal().isOpen(), panel().exists()]).then((arr) =>
        arr.every(Boolean),
      ),
    getTitle: () => panel().getTitleText(),
    getSubtitle: () => panel().getSubtitleText(),
    clickCloseButton: () => panel().clickClose(),
    closeButtonExists: () => panel().isCloseButtonExists(),
    clickAddSortButton: () => addItemButton().click(),
    /** Removes a sort item at index */
    clickSortRemoveAtIndex,
    /** Changes a sort order at index */
    changeSortOrderAtIndex,
    getSortOrderAtIndex,
    /** Changes a sort column at index */
    changeColumnAtIndex,
    getColumnAtIndex,
    getItemsCount: () => items().count(),
    dragHandleExistsAt: (i: number) =>
      getItemAtBase(i)
        .$('[data-hook="multi-level-sorting-item-drag-handle"]')
        .exists(),
    dragStart: async (sourceIndex: number) =>
      getDragAndDropDriver().dragStart(await getItemAtBase(sourceIndex)),
    dragMove: () => getDragAndDropDriver().dragMove(),
    dragEnd: async (targetIndex: number) =>
      getDragAndDropDriver().dragEnd(await getItemAtBase(targetIndex)),
  };
}

export default MultiLevelSortingPanelUniDriver;
