import React from 'react';
import {View, Dimensions, Text, Image} from 'react-native';
import Touch from '../components/Touch';
import {scaleSize, setSpText} from '../utils/screen';
import {login} from '../utils/config';
import QRCode from 'react-native-qrcode-svg';
import {connect} from 'react-redux';
import delay from '../utils/delay';
import Speech from '../utils/Speech';
import Toast from './Toast';
import Smilepay from '../utils/Smilepay';
import KeyEvent from 'react-native-keyevent';

const {width, height} = Dimensions.get('screen');
const paidTime = 30; // 支付完成等待时间 30s
const wait = t => new Promise(resolve => setTimeout(resolve, t));
@connect(({admin}) => ({admin}))
class Settles extends React.Component {
  state = {
    faceType: 'alipay',
  };

  componentDidUpdate(snapshot) {
    this.listenOrder();
  }

  listenOrder = () => {
    let {settleVisible} = this.props;
    if (settleVisible) {
      window.scan = this.submitBarcode;
      const handleScan = this.submitBarcode;
      KeyEvent.onKeyDownListener(async e => {
        const {keyCode, pressedKey} = e;
        if (keyCode === 66) {
          // 回车事件
          await handleScan();
          this.barcode = '';
        } else if (keyCode >= 7 && keyCode <= 16) {
          this.barcode += keyCode - 7;
        } else if (keyCode >= 29 && keyCode <= 54) {
          this.barcode += pressedKey;
        }
      });
      this.listen();
    }
  };

  listen = async () => {
    while (!window.socket) {
      await delay(1000);
    }
    window.socket.on(
      'counterOrder',
      ({type, msg, sid, payType, token, orderId}) => {
        let {num, total, goodsMap} = this.props;
        let totalPrice = total;
        let totalCount = num;
        if (type === 'waiting') {
          // 客户端等待，响应购物车列表
          this.token = token;
          const {ids, noBarcode} = this.getGoods(goodsMap);
          window.socket.emit(
            'counterGoods',
            sid,
            JSON.stringify(ids),
            totalPrice,
            totalCount,
            payType,
            JSON.stringify(noBarcode),
          );
        } else if (type === 'fail') {
          // 下单失败
          Speech.speak(msg);
        } else if (type === 'paying') {
          // 下单成功，等待用户支付
          let count = 0;
          this.props.dispatch({
            // 扫码付款步骤
            type: 'app/step',
            step: 2,
          });
          clearInterval(this.payInter); // 清除定时查询订单
          this.payInter = setInterval(async () => {
            count++;
            if (count >= 30) {
              // 一分钟，超时关闭付款
              this.props.dispatch({
                // 返回商品扫码步骤
                type: 'app/step',
                step: 1,
              });
              clearInterval(this.payInter);
              this.setState({voiceModal: false});
            }
          }, 2000);
          this.setState({voiceModal: true, voiceTitle: msg});
          // Speech.speak(msg);
        } else if (type === 'paid') {
          if (orderId) {
            let count = 0;
            this.props.dispatch({
              // 扫码付款步骤
              type: 'app/step',
              step: 2,
            });
            clearInterval(this.payInter); // 清除定时查询订单
            this.payInter = setInterval(async () => {
              if (!this.state.voiceModal) {
                clearInterval(this.payInter);
              }
              count++;
              const order = await this.props.dispatch({
                type: 'goods/status',
                orderId, // 订单号,
              });
              if (order.code === 1 && order.data === 1) {
                this.successPay();
                clearInterval(this.payInter); // 清除定时查询订单
                this.isPaid = true; // 支付成功，暂停检测秤的重量
                this.paidTimeout = setTimeout(() => {
                  this.isPaid = false;
                }, paidTime * 1000);
                setTimeout(() => {
                  this.props.dispatch({
                    // 返回商品扫码步骤
                    type: 'app/step',
                    step: 1,
                  });
                  this.setState({voiceModal: false});
                }, 1200);
              }
              if (count >= 20) {
                // 一分钟，超时关闭付款
                this.props.dispatch({
                  // 返回商品扫码步骤
                  type: 'app/step',
                  step: 1,
                });
                clearInterval(this.payInter);
                this.setState({voiceModal: false});
              }
            }, 3000);
          } else {
            this.props.dispatch({
              // 购物完成步骤
              type: 'app/step',
              step: 3,
            });
            this.clearList();
            this.setState({voiceModal: true, voiceTitle: msg});
            Speech.speak(msg);
            clearInterval(this.payInter); // 清除定时查询订单
            this.isPaid = true; // 支付成功，暂停检测重力感应器的重量
            this.paidTimeout = setTimeout(() => {
              this.isPaid = false;
            }, paidTime * 1000);
            setTimeout(() => {
              this.props.dispatch({
                // 返回商品扫码步骤
                type: 'app/step',
                step: 1,
              });
              this.setState({voiceModal: false});
            }, 1200);
          }
        }
      },
    );
  };
  getGoods = goodsMap => {
    let ids = {};
    const noBarcode = [];
    goodsMap.map(({barcode, num, prePrice, name}) => {
      if (barcode !== '000000') {
        //非无码商品
        if (!ids[barcode]) {
          ids[barcode] = num;
        } else {
          ids[barcode] += num;
        }
      } else {
        noBarcode.push({
          name,
          barcode,
          price: 0,
          purPrice: 0,
          prePrice,
          num,
          weight: 0,
        });
      }
    });
    return {ids, noBarcode};
  };

  successPay = () => {
    Toast.hide();
    const msg = '付款成功，祝您生活愉快~';
    Speech.speak(msg);
    this.props.dispatch({
      // 购物完成步骤
      type: 'app/step',
      step: 3,
    });
    let {emptyCar, closeSettle} = this.props;
    closeSettle();
    emptyCar();
  };

  alipayinfo = async () => {
    const {data} = await this.props.dispatch({type: 'goods/alipayinfo'});
    this.alipayInfo = await Smilepay.init(data);
    if (this.alipayInfo.code === '1000')
      this.alipayInfo.metaInfo = JSON.parse(this.alipayInfo.metaInfo);
    return this.alipayInfo;
  };

  smilepay = async () => {
    const {goodsMap} = this.props;
    if (goodsMap.length === 0) {
      this.props.speak('请先扫描商品条码，再刷脸支付', true);
      return;
    }
    await this.alipayinfo();
    if (!this.alipayInfo || !this.alipayInfo.metaInfo) {
      this.props.speak('刷脸支付启动失败，请重新刷脸或扫码支付', true);
      return;
    }
    const {data} = await this.props.dispatch({
      type: 'goods/smilepay',
      zimmetainfo: this.alipayInfo.metaInfo,
    });
    if (data.code === 1) {
      const res = await Smilepay.verify(JSON.parse(data.data));
      if (res.code !== '1000') {
        Toast.show(res.msg);
        return;
      }
      await this.barcodepay(res.fToken, true, null, res.fToken, res.uid);
    }
  };

  // 付款码支付
  barcodepay = async (code, facepay, openid, fToken, uid) => {
    if (this.barcodeBusy) {
      return true;
    }
    Toast.loading('正在付款，请稍后~');
    const isWxpay = code.toString().match(/1[0-5]\d{16}/);
    const isAlipay = fToken || code.toString().match(/^(2[5-9]|30)\d{14,22}$/);
    if (!isWxpay && !isAlipay) {
      return false;
    }
    this.barcodeBusy = true;
    let successPay = false;
    let {goodsMap} = this.props;
    const {ids, noBarcode} = this.getGoods(goodsMap);
    const res = await this.props.dispatch({
      type: 'goods/barcodepay',
      ids,
      code,
      facepay,
      noBarcode,
      openid,
      fToken,
      uid,
    });
    if (res.code !== 1) {
      await this.setState({voiceModal: true, voiceTitle: res.msg});
      Speech.speak(res.msg);
    }
    if (res.code === 1) {
      // 付款成功
      this.orderId = res.data.orderId;
      if (res.data.users) {
        this.barcodeUser = res.data;
        await this.selectUserModal();
      }
      if (res.data.alipayUserId) {
        // 没有匹配到支付宝用户
        const voiceTitle =
          '为了正常出店，首次使用支付宝付款码，请用进店微信扫描屏幕二维码';
        // this.orderId = res.data.orderId;
        this.alipayUserId = res.data.alipayUserId;
        Speech.speak(voiceTitle);
        this.setState({voiceTitle});
      } else {
        this.successPay();
        successPay = true;
        await wait(1200);
        // await wait(res.data.timeout);
      }
    } else if (res.code === 2) {
      // 等待付款
      for (let i = 0; i < 20; i++) {
        await wait(3000);
        if (!this.state.voiceModal) {
          break;
        }
        const status = await this.props.dispatch({
          type: 'goods/status',
          orderId: res.data.orderId, // 订单号,
        });
        if (status.code === 1 && status.data === 1) {
          this.successPay();
          successPay = true;
          await wait(1200);
          break;
        }
      }
    } else if (res.code === 3) {
      // 付款失败
      await wait(res.data.timeout);
    } else {
      await wait(1200);
    }
    await this.setState({voiceModal: false});
    this.barcodeBusy = false;
    if (successPay) {
      return 'SUCCESS';
    }
    return true;
  };

  submitBarcode = async () => {
    this.errGood = null;
    if (!window.auth) {
      const msg = '系统未授权，无法查询商品';
      this.setState({voiceModal: true, voiceTitle: msg});
      Speech.speak(msg);
      clearTimeout(this.noAuthTimeout);
      this.noAuthTimeout = setTimeout(() => {
        this.setState({voiceModal: false});
      }, 3000);
      return;
    }
    const barcode = this.barcode;
    if (await this.barcodepay(barcode)) {
      return;
    }
    window.count = window.defaultCount;
    if (barcode) {
      const goods = this.goodsMap[barcode];
      if (!goods) {
        Toast.loading('正在查询商品');
      }
      this.setDelay();
      let {goodsArr} = this.state;
      let {data} = goods
        ? {data: {code: 1, data: goods}}
        : await this.props.dispatch({
            type: 'goods/getGoods',
            barcode,
          });
      if (!data) {
        return;
      }
      if (data.code < 0) {
        this.barcode = '';
        this.speak(data.msg);
        return;
      }
      let stopSpecial = false;
      if (data.data.category === '特价') {
        for (let i = 0; i < goodsArr.length; i++) {
          if (goodsArr[i].name === data.data.name) {
            stopSpecial = true;
            break;
          }
        }
      }
      let price = Number(data.data.price || data.data.prePrice);
      if (data.code === 1 && price > 0 && !stopSpecial) {
        if (!data.data.num) {
          data.data.numChange = true;
        } // 称重计价不可修改数量
        this.goodsMap[barcode] = data.data;
        let dataReal = data.data;
        dataReal.num = data.data.num || 1;
        goodsArr.push({...dataReal});
        const current = Math.ceil(goodsArr.length / window.pageSize);
        this.setState({
          current,
          goodsArr,
          modalS: false,
        });
        Toast.hide();
      } else if (data.code === 1 && price <= 0) {
        Toast.info('商品价格异常，请联系客服人员处理', 2);
      } else if (data.code === 1 && stopSpecial) {
        Toast.info('特价商品每人限购一次哦', 2);
      } else if (data.code === 2) {
        Toast.fail(data.data, 1.5);
      }
    }
  };

  render() {
    let {settleVisible, closeSettle, num, total, admin} = this.props;
    const facepay =
      this.state.faceType === 'wxpay' ? this.wxFacepay : this.smilepay;
    return (
      <View style={settleVisible ? styles.body : styles.display}>
        <View style={styles.settle}>
          <View style={styles.settleBox}>
            <Text style={styles.close} onPress={() => closeSettle()}>
              ×
            </Text>
            <Text style={styles.total}>
              共
              <Text style={{color: 'red', fontSize: setSpText(50)}}>
                {' '}
                {num}{' '}
              </Text>
              件,共计
              <Text style={{color: 'red', fontSize: setSpText(50)}}>
                {' '}
                {total.toFixed(2)}{' '}
              </Text>
              元
            </Text>
            <Text style={styles.title}>请使用微信或支付宝扫码付款</Text>
            <View style={styles.payCode}>
              <QRCode
                logoSize={width > 801 ? 60 : scaleSize(70)}
                // logoBackgroundColor="#fc4000"
                logo={require('../assets/logo2.png')}
                size={height * 0.15}
                value={`${login}/#/counter-order-${admin.socket}`}
              />
            </View>
            <Text style={styles.title}>刷脸支付或使用付款码</Text>
            <Touch style={styles.choose} onPress={facepay}>
              <View style={styles.chooseItem}>
                <View style={styles.payImg}>
                  <Image
                    style={styles.img}
                    source={require('../assets/Vertical/faceScan.png')}
                  />
                </View>
                <Text style={styles.payText}>刷脸支付</Text>
              </View>
            </Touch>
            <Touch style={styles.choose} onPress={this.payCode}>
              <View style={styles.chooseItem}>
                <View style={styles.payImg}>
                  <Image
                    style={styles.img}
                    source={require('../assets/Vertical/payCode.png')}
                  />
                </View>
                <Text style={styles.payText}>付款码支付</Text>
              </View>
            </Touch>
          </View>
        </View>
      </View>
    );
  }
}

const styles = {
  body: {},
  display: {
    display: 'none',
  },
  settle: {
    width,
    height,
    backgroundColor: 'rgba(0,0,0,0.6)',
    position: 'absolute',
    zIndex: 9,
    alignItems: 'center',
    justifyContent: 'center',
  },
  payCode: {
    width: height * 0.15,
    height: height * 0.15,
  },
  settleBox: {
    position: 'relative',
    width: width * 0.7,
    height: height * 0.6,
    backgroundColor: '#fff',
    alignItems: 'center',
  },
  close: {
    position: 'absolute',
    top: 20,
    right: 10,
    width: 50,
    height: 50,
    fontSize: setSpText(80),
    textAlign: 'center',
    lineHeight: 50,
  },
  total: {
    height: height * 0.6 * 0.15,
    lineHeight: height * 0.6 * 0.2,
    fontSize: setSpText(30),
  },
  title: {
    height: height * 0.6 * 0.12,
    lineHeight: height * 0.6 * 0.12,
    fontSize: setSpText(30),
  },
  choose: {
    width: width * 0.7,
    height: height * 0.6 * 0.15,
    marginBottom: 20,
  },
  chooseItem: {
    width: width * 0.7,
    height: height * 0.6 * 0.15,
    backgroundColor: '#f3f4f5',
    flexDirection: 'row',
    alignItems: 'center',
  },
  payImg: {
    width: height * 0.6 * 0.1,
    height: height * 0.6 * 0.1,
    marginLeft: 50,
    borderRadius: 10,
  },
  img: {
    width: '100%',
    height: '100%',
  },
  payText: {
    fontSize: setSpText(50),
    marginLeft: 20,
  },
};

export default Settles;
