import React, {Component} from 'react';
import {View, Text, Image, Dimensions, Animated, Easing} from 'react-native';
import AsyncStorage from '@react-native-community/async-storage';
// import QRCode from 'react-native-qrcode-svg';
import {connect} from 'react-redux';
import Touch from '../components/Touch';
import PhoneModal from '../components/PhoneModal';
import VerifyCodeModal from '../components/VerifyCodeModal';
import OrderDetailsModal from '../components/OrderDetailsModal';
import NP from '../utils/np';
import delay from '../utils/delay';
import config from '../utils/config';
import Speech from '../utils/Speech';
import WxFacepay from '../utils/WxFacepay';

const {width, height} = Dimensions.get('screen');

const graph = {
  temperature: [1, 1, 1, 1, 1, 1, 1, 1],
  humidity: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
  shock: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
  trigger: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
  offset: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
};

const graphItemWidth = (width - 60) * 0.12;

const graphItemHeight = height * 0.0135;

const graphSpaceHeight = height * 0.006;

let qrHost = config.qrHost;

class FacePage extends Component {
  state = {
    tip: '',
    tipBg: '#FC4000',
    temperatureValue: new Animated.Value(0),
    humidityValue: new Animated.Value(0),
    shockValue: new Animated.Value(0),
    triggerValue: new Animated.Value(0),
    offsetValue: new Animated.Value(0),
    phoneModal: false, // 显示输入电话号码弹窗
    verifyCodeModal: false, // 显示输入验证码弹窗
    orderDetailsModal: false, // 显示订单详情弹窗
    goodsArr: [],
  };

  async componentWillMount() {
    this.storeKey = await AsyncStorage.getItem('KEY');
    if (!this.init) {
      this.init = await WxFacepay.init();
    }
  }

  async componentDidMount() {
    this.listen();
    clearInterval(this.noPersonInter);
    this.noPersonInter = setInterval(async () => {
      if (
        (this.state.qrcode || this.state.scaleBusy) &&
        (await this.noPerson())
      ) {
        this.initScale();
        this.setState({qrcode: null, tip: ''});
      }
    }, 5000);
  }

  onSubmit = async phone => {
    const res = await this.props.dispatch({
      type: 'store/sendsms',
      phone,
    });
    if (res.code === 1) {
      if (/^\d+$/.test(res.msg)) {
        Speech.speak(res.msg.split('').join(' '));
      } else {
        Speech.speak('请输入验证码');
      }
      this.phone = phone;
      this.setState({
        phoneModal: false,
        verifyCodeModal: true,
      });
    } else {
      Speech.speak(res.msg);
    }
  };

  onCodeSubmit = async code => {
    const res = await this.props.dispatch({
      type: 'store/verifysms',
      code,
      phone: this.phone,
      userId: this.userId,
    });
    if (res.code === 1) {
      this.setState({
        verifyCodeModal: false,
      });
      const ret = await this.props.dispatch({
        type: 'store/wxdoor',
        userId: res.data,
      });
      this.handleDoorLogin(ret);
    } else {
      Speech.speak(res.msg);
    }
  };

  handleClose = () => {
    this.setState({
      phoneModal: false,
    });
  };

  handleCodeClose = () => {
    this.setState({
      verifyCodeModal: false,
    });
  };

  handleOrderClose = () => {
    this.setState({
      orderDetailsModal: false,
    });
  };

  listen = async () => {
    while (!window.socket) {
      await delay(1000);
    }
    if (!window.socket.hasListeners('doorLogin')) {
      // 扫码验证成功
      window.socket.on('doorLogin', this.handleDoorLogin);
    }
    if (!window.socket.hasListeners('scale')) {
      // 重力感应变化
      window.socket.on('scale', this.handleScaleChange);
    }
  };

  // 判断传感器上没人
  noPerson = async () => {
    const data = await this.props.dispatch({
      type: 'store/scaleData',
    });
    return data && data.stableWeight === 0;
  };

  // device 代表当前打开的门
  handleScaleChange = ({count}) => {
    if (count === -1) {
      // 重力感应开始识别
      this.wechatFace();
      this.startScale();
    } else if (count === 0) {
      // 重力感应归零
      this.initScale();
      this.setState({qrcode: null, tip: ''});
    }
  };

  handleDoorLogin = async ret => {
    if (ret) {
      const key = this.storeKey;
      const prefix = `${qrHost}/#/store-${ret.action}-`;
      if (ret.code < 0 || ret.code === 401) {
        // 未授权，提示用户扫码验证
        let tipText = ret.msg;
        Speech.speak(tipText);
        let qrcode = `${prefix}j${key}`;
        if (ret.userId) {
          qrcode += `-${ret.userId}`;
        }
        this.userId = ret.userId;
        this.setState({qrcode, tip: tipText});
        if (ret.code === 401) {
          // 需要验证手机号
          this.setState({phoneModal: true});
        } else {
          let goodsArr = [];
          ret.orders.map(v1 => {
            v1.goods.map(v2 => {
              goodsArr.push(v2);
            });
          });
          this.setState({orderDetailsModal: true, goodsArr});
        }
      } else if (ret.msg) {
        let tipText = ret.msg.replace(/扫码/g, '人脸识别');
        if (ret.code === 1) {
          this.setState({qrcode: null});
        } else if (ret.qrcode) {
          this.setState({qrcode: `${prefix}j${key}`});
        }
        Speech.speak(tipText);
        this.setState({tip: tipText});
      }
    } else {
      Speech.speak('正在重新识别，请靠中间站稳');
    }
  };

  startAnimation = () => {
    let {ai} = this.props.store;
    let duration = 1000;
    let temperature =
      (ai.temperature + 20) * 10 > 600 ? 600 : (ai.temperature + 20) * 10;
    let humidity = ai.humidity > 100 ? 100 : ai.humidity;
    let shock = ai.shock > 150 ? 150 : ai.shock;
    let trigger = ai.trigger.data > 96 ? 96 : ai.trigger.data;
    let offset = ai.offset > 50 ? 50 : ai.offset;
    Animated.parallel([
      Animated.spring(this.state.temperatureValue, {
        toValue: temperature,
        duration,
        easing: Easing.linear,
      }),
      Animated.spring(this.state.humidityValue, {
        toValue: humidity,
        duration,
        easing: Easing.linear,
      }),
      Animated.spring(this.state.shockValue, {
        toValue: shock,
        duration,
        easing: Easing.linear,
      }),
      Animated.spring(this.state.triggerValue, {
        toValue: trigger,
        duration,
        easing: Easing.linear,
      }),
      Animated.spring(this.state.offsetValue, {
        toValue: offset,
        duration,
        easing: Easing.linear,
      }),
    ]).start(() => {
      this.state.temperatureValue.setValue(temperature);
      this.state.humidityValue.setValue(humidity);
      this.state.shockValue.setValue(shock);
      this.state.triggerValue.setValue(trigger);
      this.state.offsetValue.setValue(offset);
    });
  };

  // 初始化重力感应
  initScale = async () => {
    this.setState({scaleBusy: false});
    clearInterval(this.scaleInter);
    await this.props.dispatch({
      type: 'store/initScaleData',
    });
    this.startAnimation();
  };

  // 重力感应变化
  startScale = () => {
    this.setState({scaleBusy: true});
    clearInterval(this.scaleInter);
    this.scaleInter = setInterval(async () => {
      await this.props.dispatch({
        type: 'store/scaleData',
      });
      this.startAnimation();
    }, 1000);
  };

  authinfo = async () => {
    const rawdata = await WxFacepay.rawdata();
    const {data} = await this.props.dispatch({
      type: 'goods/faceinfo',
      rawdata,
    });
    return data;
  };

  // 微信人脸身份识别
  wechatFace = async () => {
    if (this.state.qrcode) {
      return;
    } // 出现二维码，不做人脸识别
    const tipText = '正在人脸识别，请看向屏幕，靠中间站稳';
    Speech.speak(tipText);
    this.setState({tip: tipText});
    let auth = (await this.authinfo()) || {};
    if (
      auth.return_code === 'SUCCESS' ||
      (auth.code === 1 && auth.data.bizCode === '0000')
    ) {
      if (auth.data) {
        auth = auth.data;
      }
      const params = {
        appid: auth.appid || auth.subAppId,
        mch_id: auth.mch_id || auth.subMchId,
        store_id: this.storeKey,
        authinfo: auth.authinfo || auth.authInfo,
        face_authtype: 'FACEID-ONCE',
        ask_unionid: 1,
      };
      let res = {};
      while (
        !res.openid &&
        !(await this.noPerson()) // 没识别到人脸，重新识别
      ) {
        res = await WxFacepay.faceinfo(params);
      }
      if (window.socket) {
        window.socket.connect();
      } // 返回结果，立即重新连接socket
      if (!res.openid) {
        return;
      } // 没识别到人脸不开门
      if (res.sub_openid) {
        res.openid = res.sub_openid;
      }
      const ret = await this.props.dispatch({
        type: 'store/wxdoor',
        openid: res.openid,
        wxtoken: res.token,
        nickname: res.nickname,
      });
      this.handleDoorLogin(ret);
    }
  };

  pressQrcode = async () => {
    await this.setState({qrcode: null});
    this.wechatFace();
  };

  render() {
    const {
      scaleBusy,
      tip,
      tipBg,
      verifyCodeModal,
      temperatureValue,
      humidityValue,
      wakeup,
      shockValue,
      triggerValue,
      offsetValue,
      phoneModal,
      orderDetailsModal,
      goodsArr,
    } = this.state;
    let {store} = this.props;
    return (
      <View style={{flex: 1, alignItems: 'center', backgroundColor: '#333'}}>
        <PhoneModal
          visible={phoneModal}
          transparent
          maskClosable
          onClose={this.handleClose}
          onRequestClose={this.handleClose}
          onSubmit={this.onSubmit}
        />
        <VerifyCodeModal
          visible={verifyCodeModal}
          transparent
          maskClosable
          onClose={this.handleCodeClose}
          onRequestClose={this.handleCodeClose}
          onSubmit={this.onCodeSubmit}
        />
        <OrderDetailsModal
          visible={orderDetailsModal}
          transparent
          maskClosable
          onClose={this.handleOrderClose}
          onRequestClose={this.handleOrderClose}
          goodsArr={goodsArr}
        />
        <View style={{alignItems: 'center', justifyContent: 'center', flex: 1}}>
          <Touch onPress={this.pressQrcode} style={{flex: 1}}>
            <Image
              source={require('../assets/ai/face.gif')}
              style={{flex: 1, width}}
            />
          </Touch>
          <Touch onPress={this.wechatFace}>
            <View style={{...styles.tip, backgroundColor: tipBg}}>
              <Text style={styles.tipText}>{tip}</Text>
            </View>
          </Touch>
        </View>
        <View
          style={{
            flex: 1,
            backgroundColor: scaleBusy || wakeup ? '#ffffff' : '#030303',
            flexDirection: 'row',
          }}>
          <View style={{width: 30}} />
          <View style={styles.aiItem}>
            <View style={styles.graph}>
              <View style={styles.graphView}>
                <Text
                  style={[
                    styles.graphText,
                    {color: scaleBusy || wakeup ? '#000000' : '#ffffff'},
                  ]}>
                  {store.ai.temperature >= 0
                    ? `+${store.ai.temperature}`
                    : store.ai.temperature}
                  ℃
                </Text>
              </View>
              <View style={styles.graphMain}>
                <View
                  style={{
                    zIndex: 999,
                  }}>
                  {graph.temperature.map((v, k) => {
                    return (
                      <View key={k}>
                        <View
                          style={[
                            styles.graphSpace,
                            {
                              backgroundColor:
                                scaleBusy || wakeup ? '#ffffff' : '#000000',
                            },
                          ]}
                        />
                        <View style={styles.graphItem} />
                      </View>
                    );
                  })}
                </View>
                <Animated.View
                  style={[
                    styles.graphData,
                    {
                      height: temperatureValue.interpolate({
                        inputRange: [0, 600],
                        outputRange: [
                          0,
                          (graphItemHeight + graphSpaceHeight) *
                            graph.temperature.length,
                        ],
                      }),
                      backgroundColor: '#fff100',
                    },
                  ]}
                />
                <View
                  style={[
                    styles.graphBg,
                    {
                      height:
                        (graphItemHeight + graphSpaceHeight) *
                        graph.temperature.length,
                    },
                  ]}
                />
              </View>
            </View>
            <Image
              style={styles.aiIcon}
              source={require('../assets/ai/temperature.png')}
            />
            <Text
              style={[
                styles.aiText,
                {color: scaleBusy || wakeup ? '#000000' : '#ffffff'},
              ]}>
              温度
            </Text>
          </View>
          <View style={styles.aiItem}>
            <View style={styles.graph}>
              <View style={styles.graphView}>
                <Text
                  style={[
                    styles.graphText,
                    {color: scaleBusy || wakeup ? '#000000' : '#ffffff'},
                  ]}>
                  {store.ai.humidity}%RH
                </Text>
              </View>
              <View style={styles.graphMain}>
                <View
                  style={{
                    zIndex: 999,
                  }}>
                  {graph.humidity.map((v, k) => {
                    return (
                      <View key={k}>
                        <View
                          style={[
                            styles.graphSpace,
                            {
                              backgroundColor:
                                scaleBusy || wakeup ? '#ffffff' : '#000000',
                            },
                          ]}
                        />
                        <View style={styles.graphItem} />
                      </View>
                    );
                  })}
                </View>
                <Animated.View
                  style={[
                    styles.graphData,
                    {
                      height: humidityValue.interpolate({
                        inputRange: [0, 100],
                        outputRange: [
                          0,
                          (graphItemHeight + graphSpaceHeight) *
                            graph.humidity.length,
                        ],
                      }),
                      backgroundColor: '#7d4d76',
                    },
                  ]}
                />
                <View
                  style={[
                    styles.graphBg,
                    {
                      height:
                        (graphItemHeight + graphSpaceHeight) *
                        graph.humidity.length,
                    },
                  ]}
                />
              </View>
            </View>
            <Image
              style={styles.aiIcon}
              source={require('../assets/ai/humidity.png')}
            />
            <Text
              style={[
                styles.aiText,
                {color: scaleBusy || wakeup ? '#000000' : '#ffffff'},
              ]}>
              湿度
            </Text>
          </View>
          <View style={styles.aiItem}>
            <View style={styles.graph}>
              <View style={styles.graphView}>
                <Text
                  style={[
                    styles.graphText,
                    {color: scaleBusy || wakeup ? '#000000' : '#ffffff'},
                  ]}>
                  {NP.round(store.ai.shock, 0).toFixed(0)}mm/s
                </Text>
              </View>
              <View style={styles.graphMain}>
                <View
                  style={{
                    zIndex: 999,
                  }}>
                  {graph.shock.map((v, k) => {
                    return (
                      <View key={k}>
                        <View
                          style={[
                            styles.graphSpace,
                            {
                              backgroundColor:
                                scaleBusy || wakeup ? '#ffffff' : '#000000',
                            },
                          ]}
                        />
                        <View style={styles.graphItem} />
                      </View>
                    );
                  })}
                </View>
                <Animated.View
                  style={[
                    styles.graphData,
                    {
                      height: shockValue.interpolate({
                        inputRange: [0, 150],
                        outputRange: [
                          0,
                          (graphItemHeight + graphSpaceHeight) *
                            graph.shock.length,
                        ],
                      }),
                      backgroundColor: '#fc615e',
                    },
                  ]}
                />
                <View
                  style={[
                    styles.graphBg,
                    {
                      height:
                        (graphItemHeight + graphSpaceHeight) *
                        graph.shock.length,
                    },
                  ]}
                />
              </View>
            </View>
            <Image
              style={styles.aiIcon}
              source={require('../assets/ai/shock.png')}
            />
            <Text
              style={[
                styles.aiText,
                {color: scaleBusy || wakeup ? '#000000' : '#ffffff'},
              ]}>
              震动
            </Text>
          </View>
          <View style={styles.aiItem}>
            <View style={styles.graph}>
              <View style={styles.graphView}>
                <Text
                  style={[
                    styles.graphText,
                    {color: scaleBusy || wakeup ? '#000000' : '#ffffff'},
                  ]}>
                  {store.ai.trigger.text}G
                </Text>
              </View>
              <View style={styles.graphMain}>
                <View
                  style={{
                    zIndex: 999,
                  }}>
                  {graph.trigger.map((v, k) => {
                    return (
                      <View key={k}>
                        <View
                          style={[
                            styles.graphSpace,
                            {
                              backgroundColor:
                                scaleBusy || wakeup ? '#ffffff' : '#000000',
                            },
                          ]}
                        />
                        <View style={styles.graphItem} />
                      </View>
                    );
                  })}
                </View>
                <Animated.View
                  style={[
                    styles.graphData,
                    {
                      height: triggerValue.interpolate({
                        inputRange: [0, 96],
                        outputRange: [
                          0,
                          (graphItemHeight + graphSpaceHeight) *
                            graph.trigger.length,
                        ],
                      }),
                      backgroundColor: '#8e8a7d',
                    },
                  ]}
                />
                <View
                  style={[
                    styles.graphBg,
                    {
                      height:
                        (graphItemHeight + graphSpaceHeight) *
                        graph.trigger.length,
                    },
                  ]}
                />
              </View>
            </View>
            <Image
              style={styles.aiIcon}
              source={require('../assets/ai/trigger.png')}
            />
            <Text
              style={[
                styles.aiText,
                {color: scaleBusy || wakeup ? '#000000' : '#ffffff'},
              ]}>
              触点
            </Text>
          </View>
          <View style={styles.aiItem}>
            <View style={styles.graph}>
              <View style={styles.graphView}>
                <Text
                  style={[
                    styles.graphText,
                    {color: scaleBusy || wakeup ? '#000000' : '#ffffff'},
                  ]}>
                  ±{NP.round(store.ai.offset, 0).toFixed(0)}G
                </Text>
              </View>
              <View style={styles.graphMain}>
                <View
                  style={{
                    zIndex: 999,
                  }}>
                  {graph.offset.map((v, k) => {
                    return (
                      <View key={k}>
                        <View
                          style={[
                            styles.graphSpace,
                            {
                              backgroundColor:
                                scaleBusy || wakeup ? '#ffffff' : '#000000',
                            },
                          ]}
                        />
                        <View style={styles.graphItem} />
                      </View>
                    );
                  })}
                </View>
                <Animated.View
                  style={[
                    styles.graphData,
                    {
                      height: offsetValue.interpolate({
                        inputRange: [0, 50],
                        outputRange: [
                          0,
                          (graphItemHeight + graphSpaceHeight) *
                            graph.offset.length,
                        ],
                      }),
                      backgroundColor: '#69d6c5',
                    },
                  ]}
                />
                <View
                  style={[
                    styles.graphBg,
                    {
                      height:
                        (graphItemHeight + graphSpaceHeight) *
                        graph.offset.length,
                    },
                  ]}
                />
              </View>
            </View>
            <Image
              style={styles.aiIcon}
              source={require('../assets/ai/offset.png')}
            />
            <Text
              style={[
                styles.aiText,
                {color: scaleBusy || wakeup ? '#000000' : '#ffffff'},
              ]}>
              误差
            </Text>
          </View>
          <View style={{width: 30}} />
        </View>
      </View>
    );
  }
}

const styles = {
  tip: {
    width,
    height: 60,
    justifyContent: 'center',
    alignItems: 'center',
  },
  tipText: {
    color: 'white',
    fontSize: 25,
  },
  aiIcon: {
    width: width * 0.08,
    height: width * 0.08,
  },
  aiText: {
    fontSize: 14,
    color: '#000000',
    fontWeight: 'bold',
    marginVertical: 12,
  },
  aiTriangle: {
    flexDirection: 'row',
    justifyContent: 'center',
    marginTop: 18,
    marginBottom: 26,
  },
  atLeft: {
    width: 0,
    height: 0,
    marginTop: 1,
    borderStyle: 'solid',
    borderTopWidth: 13,
    borderBottomWidth: 13,
    borderRightWidth: (width - 60) * 0.1,
    borderTopColor: '#fff',
    borderLeftColor: '#fff',
    borderBottomColor: '#fff',
  },
  atRight: {
    width: 0,
    height: 0,
    marginTop: 1,
    borderStyle: 'solid',
    borderTopWidth: 13,
    borderBottomWidth: 13,
    borderLeftWidth: (width - 60) * 0.1,
    borderTopColor: '#fff',
    borderBottomColor: '#fff',
    borderRightColor: '#fff',
  },
  aiItem: {
    flex: 1,
    alignItems: 'center',
  },
  graph: {
    width: graphItemWidth,
    flex: 1,
  },
  graphMain: {
    position: 'relative',
    marginBottom: 12,
  },
  graphItem: {
    width: graphItemWidth,
    height: graphItemHeight,
    backgroundColor: 'transparent',
  },
  graphSpace: {
    width: graphItemWidth,
    backgroundColor: '#ffffff',
    height: graphSpaceHeight,
  },
  graphBg: {
    width: graphItemWidth,
    position: 'absolute',
    top: 0,
    left: 0,
    backgroundColor: '#d7d2bb',
  },
  graphData: {
    width: graphItemWidth,
    position: 'absolute',
    bottom: -1,
    left: 0,
    zIndex: 9,
  },
  graphView: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'flex-end',
  },
  graphText: {
    marginBottom: 5,
    fontSize: 12,
    color: '#000000',
  },
};

export default connect(({store}) => ({store}))(FacePage);
