package com.jeequan.jeepay.pay.service.payorderpush.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.components.mq.model.PushSpeakerMQ;
import com.jeequan.jeepay.core.interfaces.device.ISpeakerService;
import com.jeequan.jeepay.core.model.device.PayOrderInfo4Device;
import com.jeequan.jeepay.core.utils.SpringBeansUtil;
import com.jeequan.jeepay.db.entity.*;
import com.jeequan.jeepay.pay.service.payorderpush.AbstractPushService;
import com.jeequan.jeepay.service.impl.MchQrcDeviceRelaService;
import com.jeequan.jeepay.service.impl.MchStoreDeviceService;
import com.jeequan.jeepay.service.impl.MemberAccountHistoryService;
import com.jeequan.jeepay.service.impl.PayOrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

/*
* 支付成功 云喇叭播报 service
*
* @author zx
*
* @date 2021/6/8 17:43
*/
@Slf4j
@Service
public class PushSpeakerService extends AbstractPushService {

    @Autowired private PayOrderService payOrderService;
    @Autowired private MchStoreDeviceService mchStoreDeviceService;
    @Autowired private MchQrcDeviceRelaService mchQrcDeviceRelaService;
    @Autowired private MemberAccountHistoryService memberAccountHistoryService;

    /**
     * orderType --订单类型，1-支付订单，2-会员余额支付流水ID
     * orderId --支付订单号 或 会员余额支付流水记录ID
    */
    public void send(String orderId, Byte orderType){

        log.info("云喇叭播报，播报订单类型为：{}", getOrderType(orderType));

        PayOrderInfo4Device speakInfo; // 播报内容对象

        if (orderType == PushSpeakerMQ.MsgPayload.ORDER_TYPE_PAY) {
            // 查询订单、订单状态
            PayOrder payOrder = payOrderService.getById(orderId);
            if (!preCheck(payOrder)) {
                return;
            }

            speakInfo = getSpeakInfo(payOrder);
        }else  if (orderType == PushSpeakerMQ.MsgPayload.ORDER_TYPE_MEMBER) {
            // 查询订单、订单状态
            MemberAccountHistory accountHistory = memberAccountHistoryService.getById(orderId);
            if (accountHistory == null || accountHistory.getBizType() != MemberAccountHistory.BIZ_CONSUME) {
                return;
            }
            // 超出播报时间的订单  不再播报
            if(DateUtil.compare(DateUtil.date(), DateUtil.offsetMinute(accountHistory.getCreatedAt(), PayOrderInfo4Device.EXPIRED_TIME)) > 0) {
                log.error("订单超出{}分钟，不再播报，orderId={}，订单时间={}", PayOrderInfo4Device.EXPIRED_TIME, accountHistory.getHid(), accountHistory.getCreatedAt());
                return;
            }

            speakInfo = getOrderInfo(accountHistory);
        }else {
            log.info("云喇叭播报失败，orderType错误");
            return;
        }

        // 查询播报设备，条件：门店ID + 云喇叭设备类型
        List<JSONObject> deviceList = mchStoreDeviceService.selectAvailableDeviceList(speakInfo.getMchNo(), speakInfo.getStoreId(),
                Collections.singletonList(DeviceProvideConfig.DEVICE_TYPE_SPEAKER));
        if (CollectionUtils.isEmpty(deviceList)) {
            return;
        }

        // 所有绑定类型为【码牌】的设备ID集合
        List<Long> deviceIdList = deviceList.stream()
                .filter(item -> item.getByte("bindType") == MchStoreDevice.DEVICE_BIND_TYPE_QRC)
                .map(item -> item.getLong("deviceId"))
                .collect(Collectors.toList());

        // 查询订单所属门店，所有绑定类型为【码牌】的设备，与订单码牌ID有绑定关系的设备
        List<Long> speakerList = new LinkedList<>();
        if (!CollectionUtils.isEmpty(deviceIdList) && speakInfo.getQrcId() != null) {
            List<MchQrcDeviceRela> relaList = mchQrcDeviceRelaService.list(MchQrcDeviceRela.gw()
                    .in(MchQrcDeviceRela::getDeviceId, deviceIdList)
                    .eq(MchQrcDeviceRela::getQrcId, speakInfo.getQrcId())
            );
            speakerList = relaList.stream().map(MchQrcDeviceRela::getDeviceId).collect(Collectors.toList());
            log.info("云喇叭播报成功，所有绑定类型为【码牌】的设备，与订单码牌ID有绑定关系的设备speakerList={}, {}orderId={}", speakerList, getOrderType(orderType), orderId);
        }

        // 循环调用单个设备播报
        for (JSONObject deviceParams : deviceList) {
            try {

                // 设备绑定类型为【门店】，播报门店下的全部订单
                if (deviceParams.getByte("bindType") == MchStoreDevice.DEVICE_BIND_TYPE_STORE) {
                    // 设备类型
                    String provider = deviceParams.getString("provider");
                    ISpeakerService speakerService = SpringBeansUtil.getBean(provider + "SpeakerService", ISpeakerService.class);
                    if (null == speakerService) {
                        continue;
                    }

                    speakerService.send(deviceParams, speakInfo);
                    log.info("云喇叭播报成功，设备厂商provider={}, {}orderId={}", provider, getOrderType(orderType), orderId);
                }

                // 设备绑定类型为【码牌】，播报该码牌的订单
                else if (deviceParams.getByte("bindType") == MchStoreDevice.DEVICE_BIND_TYPE_QRC) {

                    // 非码牌订单  ||  码牌和设备无绑定关系，不播报
                    if (speakInfo.getQrcId() == null || CollectionUtils.isEmpty(speakerList) || !speakerList.contains(deviceParams.getLong("deviceId"))) {
                        continue;
                    }

                    // 设备类型
                    String provider = deviceParams.getString("provider");
                    ISpeakerService speakerService = SpringBeansUtil.getBean(provider + "SpeakerService", ISpeakerService.class);
                    if (null == speakerService) {
                        continue;
                    }

                    speakerService.send(deviceParams, speakInfo);
                    log.info("云喇叭播报成功，设备厂商provider={}, {}orderId={}", provider, getOrderType(orderType), orderId);
                }


            } catch (Exception e) {
                log.error("error", e);
            }
        }
    }

}
