import http, { request } from 'utils/fetch';
import { api } from 'constants/config';
import { actionTypes } from 'constants/action-types';
import { uploadAssets } from 'utils/upload';

// action types
export const types = {
  LIST: 'template/list',
};

export function getAllTemplates(params = {}) {
  return async () => {
    return await request(api.templateList, undefined, { page: 1, size: 9999, ...params }).then(
      ({ templates }) => templates
    );
  };
}

export function getTemplates() {
  return async (dispatch) => {
    dispatch({
      type: actionTypes.TEMPLATE_GET_LIST_START,
    });
    const query = {
      page: 1,
      size: 99999,
    };

    const result = await request(api.templateList, undefined, query);
    if (result) {
      dispatch({
        type: actionTypes.TEMPLATE_GET_LIST_SUCCESS,
        payload: {
          list: result.templates,
          pagination: {
            current: 1,
            showCount: result.pagination.showCount,
            total: result.pagination.total,
          },
        },
      });
    } else {
      dispatch({
        type: actionTypes.TEMPLATE_GET_LIST_FAILURE,
      });
    }
  };
}

async function getImagePath(image) {
  let thumbPath = image;
  if (image != null && typeof image === 'object') {
    const path = `template/${image.name}`;
    const result = await uploadAssets({ path: path, file: image });
    if (!result) {
      return new Error('upload assets failure');
    }
    thumbPath = result;
  }
  return thumbPath;
}

export function addTemplate({ name, info, category, screenId, thumb, previewThumb }) {
  return async () => {
    const [thumbPath, previewThumbPath] = await Promise.all([
      getImagePath(thumb),
      getImagePath(previewThumb),
    ]);

    const result = await request(
      api.templateAdd,
      undefined,
      undefined,
      JSON.stringify({
        name,
        info,
        category,
        screenId,
        thumb: thumbPath,
        previewThumb: previewThumbPath,
      }),
    );

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

export function updateTemplate({ id, name, info, category, screenId, thumb, previewThumb }) {
  return async () => {
    const [thumbPath, previewThumbPath] = await Promise.all([
      getImagePath(thumb),
      getImagePath(previewThumb),
    ]);

    const result = await request(
      api.templateUpdate,
      { id },
      undefined,
      JSON.stringify({
        name,
        info,
        category,
        screenId,
        thumb: thumbPath,
        previewThumb: previewThumbPath,
      }),
    );

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

export function sortTemplate(orders) {
  return async () => {
    const orderKeys = Object.keys(orders);
    if (!orderKeys.length) return;

    await Promise.all(
      orderKeys.map(async (categoryId) => {
        const templateIds = orders[categoryId].map((o) => o.id);
        await request(api.templateSort, undefined, undefined, JSON.stringify({ templateIds }));
      }),
    );
  };
}

export function deleteTemplates({ templates }) {
  return async (dispatch) => {
    dispatch({
      type: actionTypes.TEMPLATE_LOADING,
      payload: true,
    });
    const result = await request(api.templateDelete,undefined, { ids:templates.join(',') })

    dispatch({
      type: actionTypes.TEMPLATE_LOADING,
      payload: false,
    });

    return result;
  };
}

export function getCategorys() {
  return async (dispatch) => {
    const result = await request(api.templateCategories);
    if (result) {
      dispatch({
        type: actionTypes.TEMPLATE_CATEGORY_GET_LIST_SUCCESS,
        payload: result,
      });
    }
  };
}

export function addCategory(name) {
  return async (dispatch) => {
    const result = await request(
      api.templateCategoryAdd,
      undefined,
      undefined,
      JSON.stringify({ name }),
    );
    if (result) {
      dispatch({
        type: actionTypes.TEMPLATE_CATEGORY_CREATE_SUCCESS,
        payload: result,
      });
    }
  };
}

export function updateCategory({ id, name }) {
  return async (dispatch) => {
    const result = await request(
      api.templateCategoryUpdate,
      { id },
      undefined,
      JSON.stringify({ name }),
    );
    if (result) {
      dispatch({
        type: actionTypes.TEMPLATE_CATEGORY_UPDATE_SUCCESS,
        payload: {
          id,
          name,
        },
      });
    }
  };
}

export function deleteCategory(id) {
  return async (dispatch) => {
    const result = await request(api.templateCategoryDelete, { id });
    if (result) {
      dispatch({
        type: actionTypes.TEMPLATE_CATEGORY_DELETE_SUCCESS,
        payload: {
          id,
        },
      });
    }
  };
}

export function sortCategory({ oldIndex, newIndex }) {
  return async (dispatch, getState) => {
    if (oldIndex === newIndex) {
      return;
    }

    const { templates } = getState();
    const { categorys } = templates;
    const def = categorys.shift();
    const source = categorys[oldIndex];
    const clonedCategorys = categorys.slice();
    clonedCategorys.splice(oldIndex, 1);
    clonedCategorys.splice(newIndex, 0, source);
    dispatch({
      type: actionTypes.TEMPLATE_CATEGORY_SORT_SUCCESS,
      payload: [def].concat(clonedCategorys),
    });

    const categorieIds = [def].concat(clonedCategorys).map((o) => o.id);

    await request(
      api.templateCategorySort,
      undefined,
      undefined,
      JSON.stringify({
        categories: categorieIds,
      }),
    );
  };
}

// 上架/下架
export function publish({ keys, isPublish }) {
  return async (dispatch) => {
    dispatch({
      type: actionTypes.TEMPLATE_LOADING,
      payload: true,
    });
    const result = await Promise.all(
      keys.map((id) =>
        request(api.templateUpdate, { id }, undefined, JSON.stringify({ published: isPublish })),
      ),
    );

    dispatch({
      type: actionTypes.TEMPLATE_LOADING,
      payload: false,
    });

    return result;
  };
}

// 我的模板
export function getMyTemplates() {
  return async (dispatch) => {
    const result = await request(api.myTemplates, undefined, { pageNum: 1, pageSize: 9999 });
    if (result && result.length) {
      dispatch({
        type: actionTypes.MY_TEMPLATES,
        payload: result,
      });
    }
  };
}

// 推荐模板
export function getRecommendTemplates() {
  return async (dispatch) => {
    const result = await request(api.recommendTemplates, undefined, {
      sort: '-createdAt',
      recommend: true,
      published: true,
      needPaid: false,
      page: 1,
      size: 8,
    });
    if (result && Array.isArray(result.templates)) {
      dispatch({
        type: actionTypes.RECOMMEND_TEMPLATES,
        payload: result.templates,
        // payload: result.templates.filter((d) => !(!d.purchased && d.needPaid)),
      });
    }
  };
}

export function addToMyTemplate(templateId) {
  return async () => {
    const result = await request(
      api.templateAddToMy,
      { templateId: templateId },
    );
    return result;
  };
}

const initialState = {
  list: [],
  pagination: { current: 1, showCount: 10, total: 0 },
  categorys: [],
  myTemplates: [],
  recommendTemplates: [],
  loading: false,
};

export default function reducer(state = initialState, { type, payload }) {
  switch (type) {
    case actionTypes.TEMPLATE_GET_LIST_START: {
      return { ...state, loading: true };
    }
    case actionTypes.TEMPLATE_GET_LIST_SUCCESS: {
      return { ...state, list: payload.list, pagination: payload.pagination, loading: false };
    }
    case actionTypes.TEMPLATE_GET_LIST_FAILURE: {
      return { ...state, loading: false };
    }
    case actionTypes.TEMPLATE_LOADING: {
      return { ...state, loading: payload };
    }
    case actionTypes.TEMPLATE_CATEGORY_GET_LIST_SUCCESS: {
      return { ...state, categorys: payload };
    }
    case actionTypes.TEMPLATE_CATEGORY_CREATE_SUCCESS: {
      const newCategorys = state.categorys.concat(payload);
      return { ...state, categorys: newCategorys };
    }
    case actionTypes.TEMPLATE_CATEGORY_DELETE_SUCCESS: {
      const newCategorys = state.categorys.filter((d: any) => d.id !== payload.id);
      return { ...state, categorys: newCategorys };
    }
    case actionTypes.TEMPLATE_CATEGORY_UPDATE_SUCCESS: {
      const newCategorys = state.categorys.map((d: any) =>
        d.id === payload.id ? { ...d, name: payload.name } : d,
      );
      return { ...state, categorys: newCategorys };
    }
    case actionTypes.TEMPLATE_CATEGORY_SORT_SUCCESS: {
      return { ...state, categorys: payload };
    }
    case actionTypes.MY_TEMPLATES: {
      return { ...state, myTemplates: payload };
    }
    case actionTypes.RECOMMEND_TEMPLATES: {
      return { ...state, recommendTemplates: payload };
    }
    default:
      return state;
  }
}
