import { Model } from 'dva';
import { Mines, MineBasic } from '@/types/common';
import { getMineList, getMineBasic, refresh, RefreshData } from './service';
import { message } from 'antd';
import { loadMineList } from '@/utils/storage';

export interface HomeMineModelState {
  refreshingList: boolean;
  errorList: boolean;
  data: Mines | null;

  refreshingBasic: boolean;
  errorBasic: boolean;
  info: MineBasic | null;
}

const MineModel: Model = {
  namespace: 'homeMine',

  state: {
    refreshingList: false,
    errorList: false,
    data: null,

    refreshingBasic: false,
    errorBasic: false,
    info: null,
  } as HomeMineModelState,

  effects: {
    *load(_, { put, all }) {
      const cached = loadMineList();
      if (cached && cached.length) {
        yield all([
          put({ type: 'loadList', payload: false }),
          put({ type: 'loadBasic' }),
        ]);
      } else {
        yield put({ type: 'refresh' });
      }
    },

    *loadList({ payload: refresh }, { put, call, select }) {
      const { refreshingList } = yield select((state: any) => state.homeMine);
      if (refreshingList) return;

      yield put({
        type: 'onUpdateState',
        refreshingList: true,
        errorList: false,
      });
      try {
        const data = yield call(getMineList, refresh);
        yield put({
          type: 'onUpdateState',
          data,
          refreshingList: false,
          errorList: false,
        });
      } catch (e) {
        yield put({
          type: 'onUpdateState',
          refreshingList: false,
          errorList: true,
          data: null,
        });
      }
    },

    *loadBasic(_, { put, call, select }) {
      const { refreshingBasic } = yield select((state: any) => state.homeMine);
      if (refreshingBasic) return;

      yield put({
        type: 'onUpdateState',
        refreshingBasic: true,
        errorBasic: false,
      });
      try {
        const info = yield call(getMineBasic);
        yield put({
          type: 'onUpdateState',
          info,
          refreshingBasic: false,
          errorBasic: false,
        });
      } catch (e) {
        yield put({
          type: 'onUpdateState',
          refreshingBasic: false,
          errorBasic: true,
        });
      }
    },

    *refresh(_, { put, call, select }) {
      const {
        homeMine: { refreshingBasic, refreshingList },
        user: { user },
      } = yield select();
      if (refreshingBasic || refreshingList || !user) return;

      yield put({
        type: 'onUpdateState',
        refreshingBasic: true,
        refreshingList: true,
        errorBasic: false,
        errorList: false,
      });
      try {
        const info = (yield call(refresh, user.inviter)) as RefreshData;
        if (info && info.basic && info.list) {
          yield put({
            type: 'onUpdateState',
            info: info.basic,
            data: info.list,
            refreshingBasic: false,
            refreshingList: false,
            errorBasic: false,
            errorList: false,
          });
        } else {
          yield put({
            type: 'onUpdateState',
            refreshingBasic: false,
            refreshingList: false,
            errorBasic: false,
            errorList: false,
          });
        }
      } catch (e) {
        message.error(e.message);
        yield put({
          type: 'onUpdateState',
          refreshingBasic: false,
          refreshingList: false,
          errorBasic: true,
          errorList: true,
        });
      }
    },
  },

  reducers: {
    onUpdateState(state, payload) {
      return {
        ...state,
        ...payload,
      };
    },
  },
};

export default MineModel;
