import React, { Component } from 'react';
import { Router, Route, Switch, Redirect } from 'react-router-dom';
import { Provider, connect } from 'react-redux';
import Async from './Async';

const StoreAsync = connect(state => state)(Async);
const UserStoreAsync = connect(state => {
  return { user: state.user };
})(Async);

export default class App extends Component {
  constructor(props) {
    super(props);
    this.moduleList = [];
    this.moduleMap = {};
    this.init();
  }

  init() {
    const { routes } = this.props;
    for (let i = 0; i < routes.length; i += 1) {
      this.pageRegister(routes[i]);
    }
  }

  pageRegister(config) {
    if (!config.index) return;
    if (!config.module) return;
    if (!this.moduleMap[config.module.key]) {
      this.moduleList.push(config.module.key);
      this.moduleMap[config.module.key] = { groupList: [], groupMap: {}, ...config.module, path: config.path };
    }
    if (!config.group) return;
    if (!this.moduleMap[config.module.key].groupMap[config.group.key] && config.group.key) {
      this.moduleMap[config.module.key].groupList.push(config.group.key);
      this.moduleMap[config.module.key].groupMap[config.group.key] = {
        subList: [],
        subMap: {},
        ...config.group,
        path: config.path,
      };
    }
    if (!this.moduleMap[config.module.key].groupMap[config.group.key].subMap[config.key]) {
      this.moduleMap[config.module.key].groupMap[config.group.key].subList.push(config.key);
      this.moduleMap[config.module.key].groupMap[config.group.key].subMap[config.key] = { ...config };
    }
  }

  render() {
    const { store } = this.props;
    return <Provider store={store}>{this.renderRouter()}</Provider>;
  }

  renderRouter() {
    const { project, routes, store, history } = this.props;
    return (
      <Router history={history}>
        <Switch>
          {project.rootPath && (
            <Route exact path="/">
              <Redirect to={project.rootPath} />
            </Route>
          )}
          {routes.map(route => {
            return (
              <Route
                exact
                key={route.key}
                path={route.matchPath || route.path}
                render={props => {
                  if (project.loginAuth && !project.loginAuth(route, store.getState())) {
                    return <Redirect to={project.loginPath || '/login'} />;
                  }
                  if (project.powerAuth && !project.powerAuth(route, store.getState())) {
                    return <Redirect to={project.powerPath || '/power'} />;
                  }
                  return this.renderMode(route, props);
                }}
              />
            );
          })}
          <Route path="*">
            <Redirect to={project.emptyPath || '/empty'} />
          </Route>
        </Switch>
      </Router>
    );
  }

  renderMode(route, props) {
    const { project } = this.props;
    let c;
    if (typeof project.mode === 'function') {
      c = project.mode;
    } else {
      switch (project.mode) {
        case 'admin':
          c = () => import('./Admin');
          break;
        case 'adminLeft':
          c = () => import('./AdminLeft');
          break;
        default:
          return this.renderPage(route, props);
      }
    }
    return (
      <UserStoreAsync
        config={route}
        {...props}
        key={props.location.key}
        moduleList={this.moduleList}
        moduleMap={this.moduleMap}
        project={project}
        component={c}
      >
        {this.renderPage(route, props)}
      </UserStoreAsync>
    );
  }

  renderPage(route, props) {
    return <StoreAsync isForm config={route} {...props} component={() => route.component()} />;
  }
}
