import { UniDriver } from '@wix/wix-ui-test-utils/unidriver';
import { baseUniDriverFactory } from '../../../../unidriver';
import {
  CustomModalLayoutUniDriver,
  TagUniDriver,
  SearchUniDriver,
  AddItemUniDriver,
  ListItemEditableUniDriver,
  TextButtonUniDriver,
  FormFieldUniDriver,
  IconButtonUniDriver,
  MessageModalLayoutUniDriver,
  StatusToastUniDriver,
} from '@wix/design-system/dist/testkit/unidriver';

export function ManageTagsModalUniDriver(base: UniDriver, body: UniDriver) {
  const modalBase = () => body.$(`[data-hook="manage-tags-modal-layout"]`);

  const getManageTagsModal = () =>
    CustomModalLayoutUniDriver(modalBase(), body);

  const exists = () => getManageTagsModal().exists();

  const getModalTitle = () => getManageTagsModal().getTitleText();

  const getTags = () => body.$$(`[data-hook="manage-tags-modal-tag"]`);

  const getTagsCount = () => getTags().count();

  const getTagByIdx = (idx: number) => TagUniDriver(getTags().get(idx), body);

  const getTagById = (tagId: string) =>
    TagUniDriver(body.$(`[id="${tagId}"]`), body);

  const getTagRows = () => body.$$(`[data-hook="manage-tags-modal-tag-row"]`);

  const getTagRowByIdx = (idx: number) => getTagRows().get(idx);

  const clickTagRenameButtonByIdx = (idx: number) =>
    IconButtonUniDriver(
      getTagRowByIdx(idx).$(`[data-hook="manage-tags-modal-tag-action-edit"]`),
      body,
    ).click();

  const clickTagDeleteButtonByIdx = (idx: number) =>
    IconButtonUniDriver(
      getTagRowByIdx(idx).$(
        `[data-hook="manage-tags-modal-tag-action-delete"]`,
      ),
      body,
    ).click();

  const getCreateBtnDriver = () =>
    TextButtonUniDriver(
      body.$(`[data-hook="manage-tags-modal-create-btn"]`),
      body,
    );

  const getNotificationDriver = () => {
    const notificationBase = body.$(
      `[data-hook="manage-tags-modal-notification"]`,
    );
    const statusToast = StatusToastUniDriver(notificationBase, body);
    const actionButton = TextButtonUniDriver(
      notificationBase.$(`[data-hook="manage-tags-modal-notification-action"]`),
      body,
    );
    return {
      ...statusToast,
      getText: () =>
        notificationBase
          .$('[data-hook="manage-tags-modal-notification-message"]')
          .text(),
      clickTextButton: () => actionButton.click(),
      getTextButtonLabel: () => actionButton.getButtonTextContent(),
    };
  };

  const getNotificationButtonExists = () =>
    body
      .$(`[data-hook="manage-tags-modal-notification"]`)
      .$(`[data-hook="manage-tags-modal-notification-action"]`)
      .exists();

  const clickCloseButton = async () => {
    await getManageTagsModal().clickCloseButton();
  };

  const getSearchDriver = () =>
    SearchUniDriver(body.$('[data-hook="manage-tags-modal-search"]'), body);

  const getAddItem = () =>
    AddItemUniDriver(body.$(`[data-hook="manage-tags-modal-list-add"]`), body);

  const getFormField = () =>
    FormFieldUniDriver(
      body.$(`[data-hook="manage-tags-modal-tag-form-field"]`),
      body,
    );
  const getListItemEditable = () =>
    ListItemEditableUniDriver(
      body.$(`[data-hook="manage-tags-modal-tag-editable"]`),
      body,
    );

  const getMessageModalLayout = () =>
    MessageModalLayoutUniDriver(
      body.$(`[data-hook="manage-tags-modal-confirm-delete-modal"]`),
      body,
    );

  // Dispatches a scroll event on the tags list container — the element the
  // infinite-scroll listener subscribes to. jsdom can't emit real scrolls, so
  // we trigger it directly (encapsulated here so specs stay DOM-free).
  const scrollListToBottom = async () => {
    const listElement = await body
      .$(`[data-hook="manage-tags-modal-tags-list"]`)
      .getNative();
    listElement.dispatchEvent(new Event('scroll'));
  };

  return {
    ...baseUniDriverFactory(base),
    exists,
    getTagsCount,
    getTagByIdx,
    getTagById,
    getModalTitle,
    getCreateBtnDriver,
    getNotificationDriver,
    getNotificationButtonExists,
    clickCloseButton,
    getSearchDriver,
    getAddItem,
    getFormField,
    getListItemEditable,
    clickTagRenameButtonByIdx,
    clickTagDeleteButtonByIdx,
    getTagRows,
    getMessageModalLayout,
    scrollListToBottom,
  };
}
