import http, { request } from 'utils/fetch';
import { api } from 'constants/config';
import message from 'components/message';
import { getScreen } from 'models/screen';

export const constants = {
  INTERACTION_EDIT_APP_GET_BEGIN: 'INTERACTION_EDIT_APP_GET_BEGIN',
  INTERACTION_EDIT_APP_GET_SUCCESS: 'INTERACTION_EDIT_APP_GET_SUCCESS',
  INTERACTION_EDIT_APP_GET_FAILURE: 'INTERACTION_EDIT_APP_GET_FAILURE',
  INTERACTION_EDIT_APP_RENAME_SUCCESS: 'INTERACTION_EDIT_APP_RENAME_SUCCESS',
  INTERACTION_EDIT_PAGE_ADD_START: 'INTERACTION_EDIT_PAGE_ADD_START',
  INTERACTION_EDIT_PAGE_ADD_SUCCESS: 'INTERACTION_EDIT_PAGE_ADD_SUCCESS',
  INTERACTION_EDIT_PAGE_ADD_FAILURE: 'INTERACTION_EDIT_PAGE_ADD_FAILURE',
  INTERACTION_EDIT_PAGE_DELETE_BEGIN: 'INTERACTION_EDIT_PAGE_DELETE_BEGIN',
  INTERACTION_EDIT_PAGE_DELETE_SUCCESS: 'INTERACTION_EDIT_PAGE_DELETE_SUCCESS',
  INTERACTION_EDIT_PAGE_DELETE_FAILURE: 'INTERACTION_EDIT_PAGE_DELETE_FAILURE',
  INTERACTION_EDIT_PAGE_COPY_BEGIN: 'INTERACTION_EDIT_PAGE_COPY_BEGIN',
  INTERACTION_EDIT_PAGE_COPY_SUCCESS: 'INTERACTION_EDIT_PAGE_COPY_SUCCESS',
  INTERACTION_EDIT_PAGE_COPY_FAILURE: 'INTERACTION_EDIT_PAGE_COPY_FAILURE',
  INTERACTION_EDIT_PAGE_RENAME_SUCCESS: 'INTERACTION_EDIT_PAGE_RENAME_SUCCESS',
  INTERACTION_EDIT_PAGE_SORT_SUCCESS: 'INTERACTION_EDIT_PAGE_SORT_SUCCESS',
  INTERACTION_EDIT_UPDATE_LEFT_WIDTH: 'INTERACTION_EDIT_UPDATE_LEFT_WIDTH'
};

export const actions = {
  getApp(id) {
    return async (dispatch) => {
      dispatch({
        type: constants.INTERACTION_EDIT_APP_GET_BEGIN,
        payload: {
          id
        }
      });
      interface Result {
        id: number;
        name: string;
        config: any;
        leftBarWidth: string | number;
        pages: Array<any>;
      }
      const result: Result = await http.get(api.interactionGet, { id });

      if (result) {
        const { id, name, config, leftBarWidth, pages } = result;

        dispatch({
          type: constants.INTERACTION_EDIT_APP_GET_SUCCESS,
          payload: {
            id,
            name,
            pages,
            config,
            leftBarWidth
          }
        });

        pages.map((d) => dispatch(getScreen(d.id)));
      } else {
        dispatch({
          type: constants.INTERACTION_EDIT_APP_GET_FAILURE
        });
      }

      return result;
    };
  },
  updateAppName({ id, name }) {
    return async (dispatch) => {
      const data = await http.post(api.interactionEdit, { id, updateList: [{ key: 'name', value: name }] });
      if (data) {
        dispatch({
          type: constants.INTERACTION_EDIT_APP_RENAME_SUCCESS,
          payload: {
            name
          }
        });
      }
    };
  },
  addPage(id) {
    return async (dispatch) => {
      const result = await request(api.interactionPageAdd, { id });

      if (result) {
        dispatch({
          type: constants.INTERACTION_EDIT_PAGE_ADD_SUCCESS,
          payload: {
            id: result.id,
            name: result.name,
            uniqueTag: result.uniqueTag,
            deleted: false
          }
        });

        dispatch(getScreen(result.id));
        return result;
      }
    };
  },
  deletePage({ id, uniqueTag }) {
    return async (dispatch) => {
      const data = await http.post(api.interactionPageDelete, { id, uniqueTag });
      if (data) {
        dispatch({
          type: constants.INTERACTION_EDIT_PAGE_DELETE_SUCCESS,
          payload: {
            uniqueTag
          }
        });
      }
    };
  },
  copyPage({ origin, target, uniqueTag }) {
    return async (dispatch) => {
      dispatch({
        type: constants.INTERACTION_EDIT_PAGE_COPY_BEGIN
      });
      interface Result {
        current: {
          uniqueTag: any;
          name: string;
          pageId: number;
        };
      }
      const result: Result | null = await http.post(api.interactionPageCopy, { origin, target, uniqueTag });
      if (result) {
        message.success('复制成功');
        if (origin !== target) {
          dispatch({
            type: constants.INTERACTION_EDIT_PAGE_COPY_SUCCESS
          });
        } else {
          dispatch({
            type: constants.INTERACTION_EDIT_PAGE_COPY_SUCCESS,
            payload: {
              uniqueTag: result.current.uniqueTag,
              name: result.current.name,
              id: result.current.pageId,
              deleted: false
            }
          });

          dispatch(getScreen(result.current.pageId));
          return result.current;
        }
      } else {
        dispatch({
          type: constants.INTERACTION_EDIT_PAGE_COPY_FAILURE
        });
      }
    };
  },
  updatePageName({ id, value }) {
    return async (dispatch) => {
      const data = await http.post(api.interactionEdit, {
        id,
        updateList: [
          {
            key: 'pages',
            value: [
              {
                key: value.id,
                value: [
                  {
                    key: 'name',
                    value: value.value
                  }
                ]
              }
            ]
          }
        ]
      });
      if (data) {
        dispatch({
          type: constants.INTERACTION_EDIT_PAGE_RENAME_SUCCESS,
          payload: {
            pageId: value.id,
            name: value.value
          }
        });
      }
    };
  },
  sortPages({ id, origin, target }) {
    return async (dispatch) => {
      dispatch({
        type: constants.INTERACTION_EDIT_PAGE_SORT_SUCCESS,
        payload: {
          sourceId: origin,
          destinationId: target
        }
      });

      const result = await http.post(api.interactionEdit, {
        id,
        updateList: [
          {
            key: 'pageOrder',
            value: [origin, target]
          }
        ]
      });

      return result;
    };
  },
  updateLeftWidth(width) {
    return async (dispatch, getState) => {
      const { interactionEdit } = getState();
      const { leftBarWidth, id } = interactionEdit;

      dispatch({
        type: constants.INTERACTION_EDIT_UPDATE_LEFT_WIDTH,
        payload: {
          width
        }
      });

      const result = await http.post(api.interactionEdit, { id, updateList: [{ key: 'leftBarWidth', value: width }] });

      if (!result) {
        dispatch({
          type: constants.INTERACTION_EDIT_UPDATE_LEFT_WIDTH,
          payload: {
            width: leftBarWidth
          }
        });
      }
    };
  }
};

export function reducers(state, { type, payload }) {
  switch (type) {
    case constants.INTERACTION_EDIT_APP_GET_BEGIN: {
      return {
        ...state,
        id: payload.id,
        loading: true
      };
    }
    case constants.INTERACTION_EDIT_APP_GET_SUCCESS: {
      return {
        ...state,
        loading: false,
        ...payload
      };
    }
    case constants.INTERACTION_EDIT_APP_GET_FAILURE: {
      return {
        ...state,
        loading: false
      };
    }
    case constants.INTERACTION_EDIT_APP_RENAME_SUCCESS: {
      return {
        ...state,
        name: payload.name
      };
    }
    case constants.INTERACTION_EDIT_PAGE_ADD_SUCCESS: {
      return {
        ...state,
        pages: state.pages.concat(payload)
      };
    }
    case constants.INTERACTION_EDIT_PAGE_DELETE_SUCCESS: {
      return {
        ...state,
        pages: state.pages.map((d) => (d.uniqueTag === payload.uniqueTag ? { ...d, deleted: true } : d))
      };
    }
    case constants.INTERACTION_EDIT_PAGE_COPY_BEGIN: {
      return {
        ...state,
        loading: true
      };
    }
    case constants.INTERACTION_EDIT_PAGE_COPY_SUCCESS: {
      return {
        ...state,
        loading: false,
        pages: payload ? state.pages.concat(payload) : state.pages
      };
    }
    case constants.INTERACTION_EDIT_PAGE_COPY_FAILURE: {
      return {
        ...state,
        loading: false
      };
    }
    case constants.INTERACTION_EDIT_PAGE_RENAME_SUCCESS: {
      return {
        ...state,
        pages: state.pages.map((d) => (d.uniqueTag === payload.id ? { ...d, name: payload.name } : d))
      };
    }
    case constants.INTERACTION_EDIT_PAGE_SORT_SUCCESS: {
      const result: { id: number }[] = Array.from(state.pages);
      const sourceIndex = result.findIndex((d) => d.id === payload.sourceId);
      const destinationIndex = payload.destinationId != -1 ? result.findIndex((d) => d.id === payload.destinationId) : result.length;
      const [removed] = result.splice(sourceIndex, 1);
      result.splice(destinationIndex, 0, removed);

      return {
        ...state,
        pages: result
      };
    }
    case constants.INTERACTION_EDIT_UPDATE_LEFT_WIDTH: {
      return { ...state, leftBarWidth: payload.width };
    }
    default:
      return state;
  }
}
