/*
 * <<
 * Davinci
 * ==
 * Copyright (C) 2016 - 2017 EDP
 * ==
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * >>
 */

import React from 'react'
import Helmet from 'react-helmet'
import { connect } from 'react-redux'
import { createStructuredSelector } from 'reselect'
import { Route, HashRouter as Router, Switch, Redirect, withRouter } from 'react-router-dom'
import { RouteComponentWithParams } from 'utils/types'

import { compose } from 'redux'
import { logged, logout, getServerConfigurations, getUserByToken } from './actions'
import injectReducer from 'utils/injectReducer'
import reducer from './reducer'
import injectSaga from 'utils/injectSaga'
import saga from './sagas'

import { makeSelectLogged } from './selectors'

import checkLogin from 'utils/checkLogin'
import request, { setToken } from 'utils/request'
import { statistic } from 'utils/statistic/statistic.dv'
import FindPassword from 'containers/FindPassword'

import { Background } from 'containers/Background/Loadable'
import { Main } from 'containers/Main/Loadable'
import { Activate } from 'containers/Register/Loadable'
import api from 'utils/api'

type MappedStates = ReturnType<typeof mapStateToProps>
type MappedDispatches = ReturnType<typeof mapDispatchToProps>
type AppProps = MappedStates & MappedDispatches & RouteComponentWithParams

export class App extends React.PureComponent<AppProps> {

  constructor(props: AppProps) {
    super(props)
    this.checkTokenLink()
  }

  private getQs = () => {
    const search = this.props.history.location.search
    const qs = search ? search.substr(1) : ''
    if (qs) {
      return qs
        .split('&')
        .reduce((rdc, val) => {
          const pair = val.split('=')
          rdc[pair[0]] = pair[1]
          return rdc
        }, {})
    } else {
      return false
    }
  }

  private checkTokenLink = async() => {
    const {
      history,
      onGetLoginUser
    } = this.props

    const qs = this.getQs()
    const token = qs['usertoken']
    // TODO allow take other parameters
    // const dashboard = qs['dashboard']

    // @FIXME login with token from url query

    const logged = await this.checkNormalLogin()
    if (!logged) {
      window.location.href = 'http://taihu.xt.wenhq.top:8083'
      return
    }
    this.props.onGetServerConfigurations()
  }

  private checkNormalLogin = async() => {
    if (checkLogin()) {
      const token = localStorage.getItem('TOKEN')
      const loginUser = localStorage.getItem('loginUser')
      setToken(token)
      this.props.onLogged(JSON.parse(loginUser))
      statistic.sendPrevDurationRecord()
      return true
    } else {
      const qs = this.getQs()
      const ticket = qs['ticket']
      if (ticket) {
        try {
          await request(api.getUserInfo + `?ticket=${ticket}`, { method: 'get' })
            .then((data) => {
              if (data?.code === 200 && data?.data) {
                setToken(data.data?.token)
                const loginUser = data.data.userInfo
                this.props.onLogged(JSON.parse(loginUser))
                localStorage.setItem('loginUser', loginUser)
                statistic.sendPrevDurationRecord()
              }
            })
          return true
        } catch (e) {
          console.log(e)
          return false
        }

      } else {
        console.log('onLogout')
        this.props.onLogout()
      }
    }
  }

  private renderRoute = () => {
    const { logged } = this.props

    return (
      // logged ? (
      <Redirect to='/project/1/dataManager' />
      // ) : (
      //   <Redirect to='/login' />
      // )
    )
  }

  public render() {
    const { logged } = this.props
    if (typeof logged !== 'boolean') {
      return null
    }

    return (
      <div>
        <Helmet
          titleTemplate='%s - 聚合平台'
          defaultTitle='聚合平台'
          meta={[
            {
              name: 'description',
              content: '聚合平台'
            }
          ]}
        />
        <Router>
          <Switch>
            <Route path='/activate' component={Activate} />
            <Route path='/joinOrganization' exact component={Background} />
            <Route path='/findPassword' component={FindPassword} />
            <Route path='/' exact render={this.renderRoute} />
            <Route path='/' component={logged ? Main : Background} />
          </Switch>
        </Router>
      </div>
    )
  }
}

const withReducer = injectReducer({ key: 'global', reducer })
const withSaga = injectSaga({ key: 'global', saga })

const mapStateToProps = createStructuredSelector({
  logged: makeSelectLogged()
})

const mapDispatchToProps = (dispatch) => ({
  onLogged: (user) => dispatch(logged(user)),
  onLogout: () => dispatch(logout()),
  onGetLoginUser: (token: string) => dispatch(getUserByToken(token)),
  onGetServerConfigurations: () => dispatch(getServerConfigurations())
})

const withConnect = connect(
  mapStateToProps,
  mapDispatchToProps
)

export default compose(
  withReducer,
  withSaga,
  withConnect,
  withRouter
)(App)
