import http, { request } from 'utils/fetch';
import { api } from 'constants/config';
import { actionTypes } from 'constants/action-types';
import { uploadAssets } from 'utils/upload';
import { updateComponentConfig } from './component';
import { Utils } from '@easyv/react-gui';
import message from 'components/message';
import { ComponentItem } from './component.types';
import { getTopScreenId } from 'utils/screen';
import { PatchScreensTheme, ThemeType } from './theme.types';
import { Type } from './theme.types';
import { EditThemeConfigType } from 'components/EasyvEditTheme';
const { mergeStyleConfig } = Utils;

export async function applyThemeOfScreen({ themeId, screenId, status }: PatchScreensTheme) {
  const result = await request(
    api.applyThemeOfScreen,
    undefined,
    undefined,
    JSON.stringify({
      themeId,
      screenId,
      status
    })
  );
  return result;
}

// 获取主题配置项
export function getThemesConfig(themesPackType?: Type) {
  return async (dispatch) => {
    dispatch({
      type: actionTypes.THEME_GET_CONFIG_LIST_START
    });
    const query = themesPackType && { type: themesPackType };
    const result = await request(api.getThemes, undefined, query);
    if (result && Array.isArray(result)) {
      dispatch({
        type: actionTypes.THEME_GET_CONFIG_LIST_SUCCESS,
        payload: result
      });
    } else {
      dispatch({
        type: actionTypes.THEME_GET_CONFIG_LIST_FAILURE
      });
    }
    return result;
  };
}

// 新建主题包
export function addThemesPack(data: EditThemeConfigType) {
  return async (dispatch) => {
    const result = await request(
      api.addThemeByNameAndConfig,
      undefined,
      undefined,
      JSON.stringify({ name: data.name, type: Type.SYSTEM, config: data.config })
    );
    if (result) {
      dispatch(getThemesConfig(Type.SYSTEM));
    }
    return result;
  };
}

// 编辑主题包
export function updateThemesPack(data: ThemeType) {
  const { id } = data;
  return async (dispatch) => {
    const result = await request(
      `${api.updateThemeById}/${id}`,
      undefined,
      undefined,
      JSON.stringify({ name: data.name, type: Type.SYSTEM, config: data.config })
    );
    if (result) {
      dispatch(getThemesConfig(Type.SYSTEM));
    }
    return result;
  };
}

// 删除主题包
export function deleteThemesPack(ids: number[]) {
  return async (dispatch) => {
    dispatch({
      type: actionTypes.THEME_PACK_LOADING,
      payload: true
    });
    const result = await request(`${api.deleteThemesPack}/${ids.join(',')}`);
    if (result) {
      dispatch(getThemesConfig(Type.SYSTEM));
      message.success('删除成功');
    }
    dispatch({
      type: actionTypes.THEME_PACK_LOADING,
      payload: false
    });
  };
}

// 发布或者下架主题包
export function publishThemesPack(ids: number[], published: boolean) {
  return async (dispatch) => {
    dispatch({
      type: actionTypes.THEME_PACK_LOADING,
      payload: true
    });
    const result = await request(
      `${api.updateThemeById}/${ids.join(',')}`,
      undefined,
      undefined,
      JSON.stringify({ type: Type.SYSTEM, published })
    );
    if (result) {
      dispatch(getThemesConfig(Type.SYSTEM));
    }
    dispatch({
      type: actionTypes.THEME_PACK_LOADING,
      payload: false
    });
  };
}

// 导入主题包
export function importThemesPack(data) {
  return async (dispatch) => {
    const result = await request(api.uploadThemesPack, undefined, undefined, JSON.stringify({ info: JSON.parse(data.configs) }));
    if (result) {
      return result;
    }
  };
}

// 主题包排序
export function sortThemesPack(param) {
  return async (dispatch) => {
    const result = await request(api.updateThemeById, undefined, undefined, JSON.stringify({ type: Type.SYSTEM, ids: param }));

    dispatch(getThemesConfig(Type.SYSTEM));

    return result;
  };
}

export function themeComponentBackUp(
  payload: {
    components: ComponentItem[];
  } = {
    components: []
  }
) {
  return async (dispatch, getState) => {
    const state = getState();
    const { components } = payload;
    const screenId = getTopScreenId();
    const screen = state.screensById[screenId];
    if (!Array.isArray(components)) {
      return;
    }
    let themeScreenConfig = {};
    if (screen) {
      themeScreenConfig = {
        //根屏的配置项
        screenId,
        config: screen.config
      };
    }
    const themeComponentById = {};
    components.map((d) => {
      themeComponentById[d.id] = d;
    });
    await dispatch({
      type: actionTypes.THEME_COMPONENT_BACKUP,
      payload: {
        themeComponentById,
        themeScreenConfig
      }
    });
  };
}

export function clearThemeComponentBackUp() {
  return async (dispatch) => {
    dispatch({
      type: actionTypes.CLEAR_THEME_COMPONENT_BACKUP,
      payload: {
        themeComponentById: {},
        themeScreenConfig: {}
      }
    });
  };
}

// 获取主题列表
export function getThemes() {
  return async (dispatch) => {
    dispatch({
      type: actionTypes.THEME_GET_LIST_START
    });

    const result = await http.get(api.themeList, { type: '1,2' });
    if (result) {
      dispatch({
        type: actionTypes.THEME_GET_LIST_SUCCESS,
        payload: result
      });
    } else {
      dispatch({
        type: actionTypes.THEME_GET_LIST_FAILURE
      });
    }

    return result;
  };
}

// 保存组件样式为主题
export function createTheme({ name, thumb, isDefault, published }) {
  return async (dispatch, getState) => {
    const { createApp, componentsById } = getState();
    const { layersSelected } = createApp;
    const componentId = layersSelected[0];
    const component = componentsById[componentId];
    const { children = [] } = component;

    let thumbPath;
    if (typeof thumb === 'object') {
      const result = await uploadAssets({
        path: `thumb/${thumb.name}`,
        file: thumb,
        prefix: 'thumb'
      });
      if (!result) {
        return;
      }
      thumbPath = result;
    }

    const result = await http.post(api.themeCreate, {
      id: componentId,
      name,
      thumb: thumbPath || '',
      isDefault,
      published,
      children
    });

    if (result) {
      dispatch(getThemes());
    }

    return result;
  };
}

// 发布或者下架主题
export function publishThemes(param) {
  return async (dispatch) => {
    dispatch({
      type: actionTypes.THEME_LOADING,
      payload: true
    });
    const result = await http.post(api.themePublish, param);
    if (result) {
      dispatch(getThemes());
    }
    dispatch({
      type: actionTypes.THEME_LOADING,
      payload: false
    });
  };
}

// 更新主题信息
export function updateTheme({ id, name, thumb, isDefault, published, isCover }) {
  return async (dispatch, getState) => {
    let componentId, children;
    if (isCover) {
      const { createApp, componentsById } = getState();
      const { layersSelected } = createApp;
      componentId = layersSelected[0];
      children = componentsById[componentId].children;
    }

    let thumbPath = thumb;
    if (typeof thumb === 'object') {
      const result = await uploadAssets({
        path: `thumb/${thumb.name}`,
        file: thumb
      });
      if (!result) {
        return;
      }
      thumbPath = result;
    }

    const result = await http.post(api.themeUpdate, {
      id,
      name,
      thumb: thumbPath || '',
      isDefault,
      published,
      componentId,
      children
    });

    if (result) {
      dispatch(getThemes());
      return result;
    }
  };
}

// 删除主题
export function deleteThemes(ids) {
  return async (dispatch) => {
    dispatch({
      type: actionTypes.THEME_LOADING,
      payload: true
    });
    const result = await http.post(api.themeDelete, { ids });
    if (result) {
      dispatch(getThemes());
      message.success('删除成功');
    }
    dispatch({
      type: actionTypes.THEME_LOADING,
      payload: false
    });
  };
}

// 组件应用主题
export function applyTheme(id) {
  return async (dispatch, getState) => {
    const { themes, createApp, componentsById } = getState();
    const { list } = themes;
    const { layersSelected, id: screenId } = createApp;

    const hide = message.loading('正在应用主题...', 0);
    const selectedId = layersSelected[0];
    const currentComponent = componentsById[selectedId];
    const { base, name, children = [], config } = currentComponent;
    const childrenComponent = children.map((d) => componentsById[d]);
    let configs: any = [];
    if (id) {
      const themeInfo = list.find((d) => d.id === id);
      let themeIds = [id];
      if (childrenComponent.length) {
        const childrenModuleNames = childrenComponent.map((d) => d.base.module_name);
        const childrenThemes = list.filter(
          (d) => d.from === base.module_name && childrenModuleNames.includes(d.moduleName) && d.name === themeInfo.name
        );
        themeIds = themeIds.concat(childrenThemes.map((d) => d.id));
      }

      const result = await http.get(api.themeList, { ids: themeIds, config: true });
      if (!result || !Array.isArray(result)) {
        return;
      }
      const componentThemeDetail = result?.find((d) => d.id === id);
      if (!componentThemeDetail) {
        hide();
        message.error('主题可能已被删除，请刷新后重试');
        return;
      }

      configs = [
        {
          component_id: currentComponent.id,
          component_name: name,
          component_config: mergeStyleConfig(config, componentThemeDetail.config)
        }
      ];

      configs = configs.concat(
        childrenComponent.map((d) => {
          const childThemeDetail = result?.find((o) => o.moduleName === d.base.module_name);
          const mergedConfig = childThemeDetail ? mergeStyleConfig(d.config, childThemeDetail.config) : d.config;

          return {
            component_id: d.id,
            component_name: d.name,
            component_config: mergedConfig
          };
        })
      );
    } else {
      const component = window.component[`${base.module_name}@${base.version}`];
      const defaultConfig = component.getDefaultConfig().configuration;
      configs = [
        {
          component_id: selectedId,
          component_config: mergeStyleConfig(config, defaultConfig)
        }
      ];
      if (childrenComponent.length) {
        const childrenDefaultConfigs = component.getDefaultChildrenConfig();
        configs = configs.concat(
          childrenComponent.map((d) => {
            const childDefaultConfig = childrenDefaultConfigs.find((o) => o.base.module_name === d.base.module_name).configuration;
            return {
              component_id: d.id,
              component_config: mergeStyleConfig(d.config, childDefaultConfig)
            };
          })
        );
      }
    }

    const updates = configs.map((d) => {
      return {
        componentId: d.component_id,
        updateData: {
          config: d.component_config
        }
      };
    });
    const result = await dispatch(updateComponentConfig(updates));

    hide();

    if (result) {
      message.success('主题应用成功');
    }
  };
}

// 导出主题
export function exportThemes(ids) {
  return async () => {
    const result = await http.post(api.themeExport, { ids });
    if (result) {
      return result;
    }
  };
}

// 导入主题
export function importThemes(data, signal) {
  return async () => {
    const result = await http.post(api.themeImport, { configs: JSON.parse(data.configs) }, { signal });
    if (result) {
      return result;
    }
  };
}

export function sortThemes(param) {
  return async (dispatch) => {
    const result = await http.post(api.themeSort, param);

    dispatch(getThemes());

    return result;
  };
}

const initialState = {
  loading: false,
  list: [],
  themeConfigList: [], // 主题列表
  themeComponentById: {},
  themeScreenConfig: {}
};

/*
  screenId,
  config: screen.config
*/

export default function reducer(state = initialState, { type, payload }) {
  switch (type) {
    case actionTypes.THEME_GET_LIST_START: {
      return { ...state, loading: true };
    }
    case actionTypes.THEME_GET_LIST_SUCCESS: {
      return { ...state, loading: false, list: payload };
    }
    case actionTypes.CLEAR_THEME_COMPONENT_BACKUP:
    case actionTypes.THEME_COMPONENT_BACKUP: {
      return {
        ...state,
        themeComponentById: payload.themeComponentById,
        themeScreenConfig: payload.themeScreenConfig
      };
    }
    case actionTypes.THEME_GET_LIST_FAILURE: {
      return { ...state, loading: false };
    }
    case actionTypes.THEME_GET_CONFIG_LIST_START: {
      return { ...state, loading: true };
    }
    case actionTypes.THEME_GET_CONFIG_LIST_SUCCESS: {
      return { ...state, loading: false, themeConfigList: payload };
    }
    case actionTypes.THEME_GET_CONFIG_LIST_FAILURE: {
      return { ...state, loading: false };
    }
    case actionTypes.THEME_PACK_LOADING: {
      return { ...state, loading: payload };
    }
    case actionTypes.THEME_LOADING: {
      return { ...state, loading: payload };
    }
    default:
      return state;
  }
}
