import { createSelector } from '@reduxjs/toolkit';
import { List as ImmutableList, Map as ImmutableMap } from 'immutable';

import { me, isHideItem } from '../initial_state';

import { getFilters } from './filters';

export { makeGetAccount } from "./accounts";
export { getStatusList, getSubStatusList } from "./statuses";

export const makeGetStatus = () => {
  return createSelector(
    [
      (state, { id }) => state.getIn(['statuses', id]),
      (state, { id }) => state.getIn(['statuses', state.getIn(['statuses', id, 'reblog'])]),
      (state, { id }) => state.getIn(['statuses', state.getIn(['statuses', id, 'quote_id'])]),
      (state, { id }) => state.getIn(['statuses', state.getIn(['statuses', state.getIn(['statuses', id, 'reblog']), 'quote_id'])]),
      (state, { id }) => state.getIn(['accounts', state.getIn(['statuses', id, 'account'])]),
      (state, { id }) => state.getIn(['accounts', state.getIn(['statuses', state.getIn(['statuses', id, 'reblog']), 'account'])]),
      getFilters,
      (_, { contextType }) => ['detailed', 'bookmarks', 'favourites'].includes(contextType),
    ],

    (statusBase, statusReblog, statusQuote, statusReblogQuote, accountBase, accountReblog, filters, warnInsteadOfHide) => {
      if (!statusBase || statusBase.get('isLoading')) {
        return null;
      }

      if (statusReblog) {
        statusReblog = statusReblog.set('account', accountReblog);
        statusQuote = statusReblogQuote;
      } else {
        statusReblog = null;
      }

      if (isHideItem('blocking_quote') && (statusReblog || statusBase).getIn(['quote', 'quote_muted'])) {
        return null;
      }

      let filtered = false;
      let mediaFiltered = false;
      if ((accountReblog || accountBase).get('id') !== me && filters) {
        let filterResults = statusReblog?.get('filtered') || statusBase.get('filtered') || ImmutableList();
        const quoteFilterResults = statusQuote?.get('filtered');
        if (quoteFilterResults) {
          const filterWithQuote = quoteFilterResults.some((result) => filters.getIn([result.get('filter'), 'with_quote']));
          if (filterWithQuote) {
            filterResults = filterResults.concat(quoteFilterResults);
          }
        }

        if (!warnInsteadOfHide && filterResults.some((result) => filters.getIn([result.get('filter'), 'filter_action']) === 'hide')) {
          return null;
        }

        let mediaFilters = filterResults.filter(result => filters.getIn([result.get('filter'), 'filter_action']) === 'blur');
        if (!mediaFilters.isEmpty()) {
          mediaFiltered = mediaFilters.map(result => filters.getIn([result.get('filter'), 'title']));
        }

        filterResults = filterResults.filter(result => filters.has(result.get('filter')) && filters.getIn([result.get('filter'), 'filter_action']) !== 'blur');
        if (!filterResults.isEmpty()) {
          filtered = filterResults.map(result => filters.getIn([result.get('filter'), 'title']));
        }
      }

      return statusBase.withMutations(map => {
        map.set('reblog', statusReblog);
        map.set('quote', statusQuote);
        map.set('account', accountBase);
        map.set('matched_filters', filtered);
        map.set('matched_media_filters', mediaFiltered);
      });
    },
  );
};

export const makeGetPictureInPicture = () => {
  return createSelector([
    (state, { id }) => state.picture_in_picture.statusId === id,
    (state) => state.getIn(['meta', 'layout']) !== 'mobile',
  ], (inUse, available) => ImmutableMap({
    inUse: inUse && available,
    available,
  }));
};

export const makeGetNotification = () => createSelector([
  (_, base)             => base,
  (state, _, accountId) => state.getIn(['accounts', accountId]),
], (base, account) => base.set('account', account));

export const makeGetReport = () => createSelector([
  (_, base) => base,
  (state, _, targetAccountId) => state.getIn(['accounts', targetAccountId]),
], (base, targetAccount) => base.set('target_account', targetAccount));