import {
  CollectionState,
  FiltersMap,
  ReportBI,
  withoutIrrelevant,
} from '@wix/bex-core';
import {
  cairoCtaClicked,
  cairoItemSelectionToggled,
  cairoTpaSCtaClicked,
  newItemCreationStart,
  cairoSectionCtaClicked,
  loadStart,
  loadEnd,
  newItemCreationEnd,
} from '@wix/bex-core/bi';
import { ToolbarCollectionState } from './ToolbarCollectionState';
import { action } from 'mobx';

export type CTAClickedParams = {
  location: ButtonLocations;
  ctaIndex: number;
  ctaName: string;
  moreActionsIndex?: number;
  numCtas: number;
  itemId?: string;
  itemIndex?: number;
  componentId?: string;
  appId?: string;
};

export type ButtonLocations =
  | 'multiBulkActionToolbar'
  | 'bulkActionToolbar'
  | 'actionCell';

export interface ToolbarBIReporterParams<T, F extends FiltersMap> {
  readonly collection: CollectionState<T, F>;
  readonly toolbar: ToolbarCollectionState<T, F>;
  readonly reportBi: ReportBI;
}

const withoutDefaults = withoutIrrelevant<
  | 'currentTab'
  | 'currentView'
  | 'currentFilters'
  | 'currentSortOrder'
  | 'listSize'
  | 'filteredListSize'
  | 'initialItems'
>();

export class ToolbarBIReporter<T, F extends FiltersMap> {
  readonly collection;
  readonly toolbar;
  readonly reportBi;

  constructor(params: ToolbarBIReporterParams<T, F>) {
    this.collection = params.collection;
    this.toolbar = params.toolbar;
    this.reportBi = params.reportBi;
  }

  ctaClicked({
    location,
    ctaIndex,
    ctaName,
    moreActionsIndex,
    numCtas,
    itemId,
    itemIndex,
    componentId,
    appId,
  }: CTAClickedParams) {
    this.reportBi(
      withoutDefaults(cairoCtaClicked)({
        ctaIndex,
        ctaName,
        location,
        numCtas,
        moreActionsIndex,
        numItems: this.collection.bulkSelect.selectedCountOrTotal,
        isSelectAll: this.collection.bulkSelect.allSelected,
        itemId,
        itemIndex,
        url: typeof window !== 'undefined' ? window.location.href : '',
      }),
    );

    if (componentId) {
      this.reportBi(
        withoutDefaults(cairoTpaSCtaClicked)({
          ctaIndex,
          ctaName,
          location,
          numCtas,
          appId,
          tpaComponentId: componentId,
        }),
      );
    }
  }

  itemSelectionToggledStarted({
    itemId,
    clickType,
  }: {
    itemId: string;
    clickType: 'Selection' | 'Deselection';
  }) {
    const { reportBi, collection } = this;
    const {
      bulkSelect,
      query: { search },
    } = collection;

    const numItemsBefore = bulkSelect.selectedCountOrTotal;

    return action(() => {
      reportBi(
        withoutDefaults(cairoItemSelectionToggled)({
          isSelectAll: false,
          isFromSearch: !search.isEmpty,
          searchQuery: search.value,
          itemId,
          clickType,
          numItemsBefore,
          numItemsAfter: bulkSelect.selectedCountOrTotal,
        }),
      );
    });
  }

  selectAllToggledStart({
    location,
  }: {
    location?: 'TableToolbar CTA' | 'Checkbox';
  }) {
    const {
      reportBi,
      toolbar: { bulk },
      collection: {
        bulkSelect,
        query: { search },
      },
    } = this;

    const numItemsBefore = bulkSelect.selectedCountOrTotal;

    return action(() => {
      const { hasClickableRows } = bulk;
      reportBi(
        withoutDefaults(cairoItemSelectionToggled)({
          url: typeof window !== 'undefined' ? window.location.href : '',
          isSelectAll: true,
          isFromSearch: !search.isEmpty,
          searchQuery: search.value,
          itemId: hasClickableRows ? undefined : 'All',
          clickType: hasClickableRows ? 'Deselection' : 'Selection',
          numItemsBefore,
          numItemsAfter: bulkSelect.selectedCountOrTotal,
          location,
          timeFromAction: Math.round(
            performance.now() - bulk._selectionStartTime,
          ),
        }),
      );
    });
  }

  onAddItemClick = (origin?: string) => {
    this.reportBi(
      newItemCreationStart({
        origin: origin ?? 'Card CTA',
      }),
    );
  };

  onPrimaryActionButtonClick = () => {
    this.reportBi(
      cairoSectionCtaClicked({
        ctaName: 'Primary action button',
        ctaType: 'Main',
        location: 'Collection Toolbar',
      }),
    );
  };

  loadStart = () => {
    this.reportBi(
      withoutDefaults(loadStart)({
        ...(this.toolbar._commonDynamicBiParams() as {}),
        url: typeof window !== 'undefined' ? window.location.href : '',
        featuresAvailability: JSON.stringify({
          isShowingSelection:
            this.toolbar.selectionProps.value.showSelection ?? false,
          isUsingApplyInFiltersPanel: !!this.toolbar.AddApplyFiltersButton,
          isUsingCustomColumns: !!this.toolbar.customColumnsProps,
          isUsingOptimisticActions: !!this.collection._optimisticActions,
          isUsingViews: !!this.toolbar.viewsProps,
          isUsingSorting: this.toolbar.columns.some(
            (col) => col.sortable === true,
          ),
          isUsingLoadSelectedColumns:
            this.collection.query.refreshOnColumnsChange ?? false,
          isUsingDataExtension:
            !!this.toolbar.collectionDataExtension?.dataExtension,
          ...this.toolbar.featuresAvailability,
        }),
        additionalFeaturesAvailability: JSON.stringify({
          isUsingActionsCell: !!this.toolbar.actionCell.value,
          ...this.toolbar.additionalFeaturesAvailability,
        }),
      }),
    );
  };

  loadEnd = (startTime: DOMHighResTimeStamp) => {
    this.reportBi(
      withoutDefaults(loadEnd)({
        ...this.toolbar._commonDynamicBiParams(),
        url: typeof window !== 'undefined' ? window.location.href : '',
        route: typeof window !== 'undefined' ? window.location.pathname : '',
        loadingTime: Math.round(performance.now() - startTime),
      }),
    );
  };

  newItemCreationEnd = (items: T[]) => {
    const { itemKey } = this.collection;
    this.reportBi(
      newItemCreationEnd({
        itemId: JSON.stringify(items.map(itemKey)),
        resultType: 'success',
      }),
    );
  };
}
