import Router from 'next/router';
import type { Action } from 'redux';
import { type Epic } from 'redux-observable';
import { concat, of } from 'rxjs';
import { filter, switchMap } from 'rxjs/operators';

import { GET_FEED_METADATA } from '@/graphql/services/feeds/constants';
import { TYPE_ERROR } from '@/modules/@common/notify/constants';

import type { MetadataFeed } from '@/modules/feeds/Editor/types';

import { getItemAction, getMetadataAction, setAction } from '../slices';
import { gqlRequest } from '@/modules/@common/request';
import { showNotificationAction } from '@/modules/layout/redux/slices';

import type { RootState } from '@/modules/@common/store/store';

type ResponseType<T extends string, Entity> = {
  data: {
    [key in T]: Entity;
  };
  errors: unknown[];
};

const query = `
  query ${GET_FEED_METADATA} {
    ${GET_FEED_METADATA} {
      languages {
        language
        id
        code
      }
      platformModels {
        provider
        providerDisplayName
        models {
          name
          category
          description
          features
        }
      }
      speechToTextLanguages {
        name
        value
        languages
      }
      timezones {
        name
        value
      }
    }
  }
`;

const getResponse = (data: MetadataFeed) => data;

const getAccountOptionsEpic: Epic<Action, Action, RootState> = (action$) =>
  action$.pipe(
    filter((action): action is ReturnType<typeof getMetadataAction> => action.type === getMetadataAction.type),
    switchMap((action) =>
      gqlRequest({
        query,
      }).pipe(
        switchMap((response: ResponseType<typeof GET_FEED_METADATA, MetadataFeed>) => {
          const actions = [];

          if (response.errors.length) {
            actions.push(
              of(
                showNotificationAction({
                  type: TYPE_ERROR,
                  message: "Can't get feed metadata",
                }),
              ),
            );

            Router.push('/feeds');
          } else {
            const metadata = getResponse(response.data[GET_FEED_METADATA]);
            actions.push(of(setAction({ metadata })));
            if (action.payload.id) {
              actions.push(of(getItemAction({ id: action.payload.id })));
            }
          }

          return concat(...actions);
        }),
      ),
    ),
  );

export default getAccountOptionsEpic;
