import { ofType } from 'redux-observable';
import { concat, defer, of } from 'rxjs';
import { switchMap } from 'rxjs/operators';

import { CALENDAR_FILTER_VALUE } from '../../constants';
import { TYPE_SUCCESS } from '@/modules/@common/notify/constants';

import { createMainMetrics, createTopSearches, createTopVideos } from '../../helpers/csv';
import * as selectors from '../selectors';
import { exportToCsvAction } from '../slices';
import { saveBlobAsFile } from '@/modules/@common/helpers/file-saver';
import { showNotificationAction } from '@/modules/layout/redux/slices';

export default (action$, state$) =>
  action$.pipe(
    ofType(exportToCsvAction.type),
    switchMap(() => {
      const state = state$.value;

      const calendar = selectors.calendarSelector(state);
      const calendarCustom = selectors.calendarCustomSelector(state);
      const topSearches = selectors.topSearchesSelector(state);
      const tableItems = selectors.tableItemsSelector(state);
      const metricViews = selectors.metricViewsSelector(state);
      const metricAttentionSpan = selectors.metricAttentionSpanSelector(state);
      const metricSearches = selectors.metricSearchesSelector(state);

      const interval = calendar === CALENDAR_FILTER_VALUE.custom ? calendarCustom.interval : calendar.interval;

      const stream$ = defer(async () => {
        const JSZip = (await import('jszip')).default;

        const zip = new JSZip();
        zip.file(
          'mainMetrics.csv',
          createMainMetrics({
            metricViews,
            metricAttentionSpan,
            metricSearches,
            interval,
          }),
        );
        zip.file('topSearches.csv', createTopSearches({ topSearches }));
        zip.file('topVideos.csv', createTopVideos({ videos: tableItems }));
        return zip.generateAsync({ type: 'blob' });
      }).pipe(
        switchMap((content) => {
          saveBlobAsFile(content, 'analyticsVideoContentPerformance.zip');

          return concat(
            of(
              showNotificationAction({
                type: TYPE_SUCCESS,
                message: 'Download was successful',
              }),
            ),
          );
        }),
      );

      return concat(stream$);
    }),
  );
