import React from 'react';
import {View, Dimensions} from 'react-native';
import AsyncStorage from '@react-native-community/async-storage';
import {connect} from 'react-redux';
import qs from 'qs';
import axios from 'axios';
import io from 'socket.io-client';
import Toast from './components/Toast';
import router from './router';
import models from './models';
import dva from './utils/dva';
import Restart from './utils/Restart';
import Installer from './utils/Installer';
import {counterInterval} from './utils/authInterval';
import {host} from './utils/config';

const {width: _width, height: _height} = Dimensions.get('window');

// axios.defaults.baseURL = host; // 配置接口地址
window.qs = qs;
window.axios = axios;
axios.defaults.headers.post['Content-Type'] =
  'application/x-www-form-urlencoded;charset=UTF-8';
axios.interceptors.request.use(config => {
  // 请求拦截器，自动添加token
  if (window.auth) {
    // 门店Token
    config.headers.common.Authorization = `Bearer ${window.auth.token}`;
  }
  return config;
});
axios.interceptors.response.use(res => {
  // 请求拦截器，自动添加token
  if (res.data.code < 0) {
    Toast.fail(res.data.msg);
  }
  return res;
});

const dvaApp = dva({
  models,
  onError(e) {
    console.warn(e);
  },
});

const delay = t => new Promise(resolve => setTimeout(resolve, t));
window.retryTimeout = 15000; // 重试间隔时间

@connect()
class App extends React.Component {
  state = {
    ready: false,
    curRoute: 'auth',
  };

  async componentWillMount() {
    // await AsyncStorage.clear(); // 清除数据
    window.dispatch = this.props.dispatch;
    const HOST = await AsyncStorage.getItem('HOST');
    axios.defaults.baseURL = HOST || host; // 配置接口地址
    const auth = await AsyncStorage.getItem('auth');
    this.device = await AsyncStorage.getItem('login'); // 设备类型
    if (auth) {
      await this.refresh();
    } else {
      window.socket =
        window.socket ||
        io(axios.defaults.baseURL, {query: {client: this.device}});
      this.listen();
    }
    this.setState({ready: true});
  }

  listen = () => {
    const {dispatch} = this.props;
    window.socket.on('connect', () => {
      window.socketDisconnected = false; // 重新连接
      dispatch({type: 'admin/setSocket', socket: window.socket.id});
    });
    window.socket.on('disconnect', () => {
      window.socket.connect();
    });
    if (!window.socket.hasListeners('restart')) {
      window.socket.on('restart', Restart.restartApp);
    }
    if (!window.socket.hasListeners('version')) {
      window.socket.on('version', () => {
        dispatch({type: 'admin/version'});
      });
    }
    if (!window.socket.hasListeners('installApp')) {
      window.socket.on('installApp', ({url}) => {
        if (!url) {
          Toast.show('下载链接不能为空');
          return;
        }
        const match = url.match(/http(s*):\/\/.+\/(.+)/);
        if (!match) {
          Toast.show('下载链接错误');
          return;
        }
        const file = match[2];
        Installer.download(url, file).then(apk => {
          if (apk) {
            Installer.install(apk);
          }
        });
      });
    }
    if (!window.socket.hasListeners('uninstallApp')) {
      window.socket.on('uninstallApp', ({pkg}) => {
        // packageName eg: com.vsu.package
        Installer.uninstall(pkg);
      });
    }
  };

  refresh = async () => {
    const {dispatch} = this.props;
    const res = await dispatch({type: 'admin/auth'});
    if (res && res.code === 1) {
      // 门店助手授权登录成功
      if (window.socket) {
        window.socket.disconnect();
      }
      if (window.authInterval) {
        clearInterval(window.authInterval);
      }
      if (window.socketInterval) {
        clearInterval(window.socketInterval);
      }
      if (this.device === 'counter') {
        // 收银设备
        let curRoute = 'home';
        if (_height > _width) {
          curRoute = 'vertical';
        }
        await this.setState({curRoute});
        dispatch({type: 'admin/version'});
        dispatch({type: 'goods/getBags'});
      } else if (this.device === 'face') {
        // 人脸设备
        await this.setState({curRoute: 'face'});
      }
      await counterInterval(dispatch, res.data.expiresIn);
      this.listen();
    } else {
      await delay(window.retryTimeout);
      await this.refresh();
    }
  };

  render() {
    const {ready, curRoute} = this.state;
    const route = Object.keys(router).filter(name => curRoute === name)[0];
    const Component = router[route];
    return ready ? <Component route={curRoute} /> : <View />;
  }
}

export default dvaApp.start(<App />);
