import * as querystring from 'querystring';
import Base from './base';
import { STORE_LOADING, STORE_LOADED, STORE_UPDATE } from '../services/Constant';

export default class CoreStore extends Base {
  initState() {
    this.locationList = [window.location.pathname];
    this.isCallBack = false;
    this.loadNum = 0;
    return {
      pageCallBack: null,
      pageInit: null,
      needBack: false,
      isCallBack: this.isCallBack,
      location: window.location.pathname,
      query: querystring.parse(window.location.search.replace('?', '')),
      loading: false,
    };
  }

  initAfter() {
    this.History.listen(this.locationChange.bind(this));
  }

  registerCallBack(page, { init, callBack }, replace) {
    this.setState({ pageInit: init, pageCallBack: callBack });
    if (replace) {
      replaceLink(page);
    } else {
      linkTo(page);
    }
  }

  callBack(result) {
    this.setState({ pageInit: null, pageCallBack: null });
    goBack();
    if (this.state.pageCallBack) {
      this.state.pageCallBack(result);
    }
  }

  locationPush(location) {
    this.isCallBack = false;
    this.locationList.push(location.pathname);
  }

  locationPop() {
    if (this.locationList.length > 0) {
      this.locationList.pop();
      this.isCallBack = true;
    }
  }

  locationReplace(location) {
    this.locationList.pop();
    this.isCallBack = false;
    this.locationList.push(location.pathname);
  }

  locationChange(location, action) {
    if (action === 'POP') {
      this.locationPop(location);
    } else if (action === 'REPLACE') {
      this.locationReplace(location);
    } else {
      this.locationPush(location);
    }
    this.updateLocation(location);
  }

  updateLocation(location) {
    this.setState({
      location: location.pathname,
      isCallBack: this.isCallBack,
      query: querystring.parse(window.location.search.replace('?', '')),
    });
  }

  handle(state = this.state, action) {
    switch (action.type) {
      case STORE_LOADING:
        this.loadNum += 1;
        if (!state.loading) {
          state.loading = true;
          state = { ...state };
        }
        break;
      case STORE_LOADED:
        this.loadNum -= 1;
        if (state.loading && this.loadNum === 0) {
          state.loading = false;
          state = { ...state };
        }
        break;
      case STORE_UPDATE:
        state = action.key === this.key ? this.merge(state, action) : state;
        break;
      default:
        break;
    }
    this.state = state;
    return this.state;
  }
}

export const Core = new CoreStore({ key: 'core' });
