import http from 'utils/fetch';
import { api } from 'constants/config';
import { actionTypes } from 'constants/action-types';
import { getTopScreenId } from 'utils/screen';
import { parseSearchParams } from 'utils/utils';
import { setScreenResult } from 'models/screen-detail';
import { getSharedPortalId, pathNameIsSharedPortal } from 'utils/spaceship';
import { isAppPage, urlCacheReplace } from 'utils/utils';
import { getFilterScreenId } from 'models/create-app';
import { FiltersType } from './filter.types';

export function getFilters(id, type = 'screen', params: any = {}) {
  return async (dispatch, getState) => {
    const {
      screenDetail,
      user: { userInfo },
    } = getState();
    const pathname = window.location.pathname;
    const portalId = getSharedPortalId(pathname);
    const url = pathNameIsSharedPortal()
      ? api.sharedGatewayFilterList
      : /\/sharescreen\//i.test(pathname)
      ? urlCacheReplace(api.sharedFilterList)
      : /\/insert\/screen\//i.test(pathname)
      ? api.appFilterList
      : /checkMode=login/.test(window.location.href) || userInfo?.userId
      ? api.filterList
      : api.filterListByCode;
    let result,
      param: any = { id, type };
    const token = parseSearchParams()?._easyv_token;
    if (token) {
      param = {
        ...param,
        token: token,
      };
    }
    if (params.byControlCode) {
      param = { ...param, controlCode: params.byControlCode };
      result = await http.get(url, portalId ? { ...param, portalId } : param);
    } else {
      result = await http.get(url, portalId ? { ...param, portalId } : param);
    }

    if (result && Array.isArray(result)) {
      dispatch({
        type: actionTypes.FILTER_GET,
        payload: {
          filters: result.reverse().map((d) => ({ ...d, screenId: id })),
        },
      });
    }
    if (screenDetail.id === param.id) {
      dispatch(setScreenResult(result));
    }
    return result;
  };
}

export function addFilter({ name, content, callbackKeys }) {
  return async (dispatch) => {
    const _isAppPage = isAppPage();
    const topScreenId = getTopScreenId();
    const result: any = await http.post(api.filterAdd, {
      screenId: topScreenId,
      name,
      content,
      callbackKeys,
    });

    if (result) {
      dispatch({
        type: actionTypes.FILTER_ADD,
        payload: {
          filter: {
            ...result,
            screenId: _isAppPage ? getFilterScreenId() : topScreenId,
          },
        },
      });
      return result;
    }
  };
}

export function updateFilter({ id, name, content, callbackKeys }) {
  return async (dispatch) => {
    const result = await http.post(api.filterUpdate, { id, name, content, callbackKeys });

    if (result) {
      const param: any = {
        id,
      };
      if (name) {
        param.name = name;
      }
      if (content) {
        param.content = content;
      }
      if (callbackKeys) {
        param.callbackKeys = callbackKeys;
      }
      dispatch({
        type: actionTypes.FILTER_UPDATE,
        payload: {
          filter: param,
        },
      });
      return result;
    }
  };
}

export function deleteFilter({ ids, components }) {
  return async (dispatch, getState) => {
    const result = await http.post(api.filterDelete, { ids: ids, components });

    if (result) {
      dispatch({
        type: actionTypes.FILTER_DELETE,
        payload: {
          ids,
        },
      });

      const { componentsById } = getState();

      const newComponents = components.map((componentId) => {
        const component = componentsById[componentId];
        const { filters } = component;
        const newFilters = filters.filter((o) => !ids.includes(o.id));
        return {
          ...component,
          filters: newFilters,
        };
      });

      dispatch({
        type: actionTypes.COMPONENT_DATA_UPDATE,
        payload: {
          list: newComponents,
        },
      });
      // 同步数据容器过滤器
      dispatch({
        type: actionTypes.DATA_COMPONENT_FILTER_UPDATE,
        payload: {
          filterIds: ids,
        },
      });
      return result;
    }
  };
}

const initialState: FiltersType = {
  list: [],
};

export default function reducer(state = initialState, { type, payload }): FiltersType {
  switch (type) {
    case actionTypes.FILTER_GET: {
      const { filters } = payload;
      const addedFilters = filters.filter((d) => !state.list.find((o: any) => o.id === d.id));
      return { ...state, list: state.list.concat(addedFilters) };
    }

    case actionTypes.FILTER_UPDATE: {
      const { filter } = payload;
      const newList = state.list.map((d: any) => {
        if (d.id === filter.id) {
          return {
            ...d,
            ...filter,
          };
        } else {
          return d;
        }
      });
      return { ...state, list: newList };
    }

    case actionTypes.FILTER_ADD: {
      let { filter } = payload;

      if (!filter) {
        return {
          ...state,
        };
      }

      filter = Array.isArray(filter) ? filter : [filter];

      return { ...state, list: filter.concat(state.list) };
    }

    case actionTypes.FILTER_DELETE: {
      const newList = state.list.filter((d: any) => {
        return !payload.ids.includes(d.id);
      });

      return { ...state, list: newList };
    }

    default:
      return state;
  }
}
