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

import { CARDS_FILTERS_ALL, CARDS_FILTERS_FOR_SOURCES } from '../../constants';
import { TYPE_SUCCESS } from '@/modules/@common/notify/constants';

import { createChart, createCountries, createDevices, createTotal } from '../../helpers/exportCSV';
import * as selectors from '../selectors';
import { exportToCSVAction } from '../slices';
import { saveBlobAsFile } from '@/modules/@common/helpers/file-saver';
import { getUserTimezoneSelector } from '@/modules/@common/user/redux/selectors';
import { showNotificationAction } from '@/modules/layout/redux/slices';

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

      const totals = selectors.totalsSelector(state);
      const chartData = selectors.chartDataSelector(state);
      const activeCardFilter = selectors.activeCardFilterSelector(state);
      const demandSources = selectors.demandSourcesSelector(state);

      const userTimezone = getUserTimezoneSelector(state$.value);

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

        const zip = new JSZip();
        zip.file(
          'Total.csv',
          createTotal({
            totals,
            cards: demandSources?.length ? CARDS_FILTERS_FOR_SOURCES : CARDS_FILTERS_ALL,
          }),
        );

        if (totals?.devices?.length) {
          zip.file('Devices.csv', createDevices({ devices: totals.devices }));
        }

        if (totals?.countries?.length) {
          zip.file('Countries.csv', createCountries({ countries: totals.countries }));
        }

        if (totals?.total?.[activeCardFilter.key] && chartData?.length) {
          zip.file('Chart.csv', createChart({ chartData, activeCardFilter, userTimezone }));
        }

        return zip.generateAsync({ type: 'blob' });
      }).pipe(
        switchMap((content) => {
          saveBlobAsFile(content, 'Monetization.zip');

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

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