package com.hfkj.service.meal.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.hfkj.common.exception.BaseException;
import com.hfkj.common.exception.ErrorCode;
import com.hfkj.common.exception.ErrorHelp;
import com.hfkj.common.exception.SysCode;
import com.hfkj.common.utils.GenerateUtil;
import com.hfkj.config.SpPrinterConfig;
import com.hfkj.config.SpPrinterTemplate;
import com.hfkj.config.mqtt.MqttProviderService;
import com.hfkj.dao.BsMealTableOrderChildMapper;
import com.hfkj.dao.BsMealTableOrderChildProductMapper;
import com.hfkj.dao.BsMealTableOrderProductMapper;
import com.hfkj.entity.*;
import com.hfkj.service.BsDeviceService;
import com.hfkj.service.group.BsStoreGroupService;
import com.hfkj.service.meal.*;
import com.hfkj.sysenum.DeviceTypeEnum;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 * @className: BsMealTableOrderChildServiceImpl
 * @author: HuRui
 * @date: 2023/12/5
 **/
@Service("mealTableOrderChildService")
public class BsMealTableOrderChildServiceImpl implements BsMealTableOrderChildService {

    @Resource
    private BsMealTableOrderChildMapper mealTableOrderChildMapper;

    @Resource
    private BsMealTableOrderChildProductMapper mealTableOrderChildProductMapper;

    @Resource
    private BsMealTableOrderService mealTableOrderService;

    @Resource
    private BsMealTableOrderProductService mealTableOrderProductService;

    @Resource
    private BsStoreGroupService storeGroupService;

    @Resource
    private BsMealShopCartService mealShopCartService;

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private MqttProviderService mqttProviderService;

    @Resource
    private BsDeviceService deviceService;

    @Override
    public void editData(BsMealTableOrderChild data) {
        if (data.getId() == null) {
            data.setCreateTime(new Date());
            data.setUpdateTime(new Date());
            mealTableOrderChildMapper.insert(data);
        } else {
            data.setUpdateTime(new Date());
            mealTableOrderChildMapper.updateByPrimaryKey(data);
        }
    }

    @Override
    @Transactional(propagation= Propagation.REQUIRES_NEW)
    public void createChildOrder(String serialNumber, String remark, String userIdentity) {
        // 查询当前开台订单
        BsMealTableOrder tableOrder = mealTableOrderService.getCurrentTableOrder(serialNumber);
        if (tableOrder == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "桌台未开台，订单创建失败！");
        }
        String lockKey = "MEAL_ORDER_" + tableOrder.getOrderNo();
        try {
            Boolean lock = redisTemplate.opsForValue().setIfAbsent(lockKey, null);
            if(lock) {
                // 加锁成功
                BsMealTableOrderChild tableOrderChild = new BsMealTableOrderChild();
                tableOrderChild.setMerId(tableOrder.getMerId());
                tableOrderChild.setMerNo(tableOrder.getMerNo());
                tableOrderChild.setMerName(tableOrder.getMerName());
                tableOrderChild.setMerAbbreviate(tableOrder.getMerAbbreviate());
                tableOrderChild.setStoreId(tableOrder.getStoreId());
                tableOrderChild.setStoreName(tableOrder.getStoreName());
                tableOrderChild.setSerialNumber(tableOrder.getSerialNumber());
                tableOrderChild.setTableNumber(tableOrder.getTableNumber());
                tableOrderChild.setTableName(tableOrder.getTableName());
                tableOrderChild.setOrderNo(tableOrder.getOrderNo());
                tableOrderChild.setChildOrderNo(System.currentTimeMillis()+ GenerateUtil.generateRandomString(1));
                tableOrderChild.setChildOrderAmount(new BigDecimal("0"));
                tableOrderChild.setStatus(1);
                tableOrderChild.setRemark(remark);
                editData(tableOrderChild);

                List<BsMealTableOrderChildProduct> childProductList = new ArrayList<>();
                BsMealTableOrderChildProduct childProduct;

                // 查询购物车
                Map<String,Object> shopCardParam = new HashMap<>();
                shopCardParam.put("serialNumber", serialNumber);
                List<BsMealShopCart> cartProductList = mealShopCartService.getShopCartProductList(shopCardParam);
                if (cartProductList.isEmpty()) {
                    throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "请选择产品");
                }
                for (BsMealShopCart cartProduct : cartProductList) {
                    // 查询交易订单中的产品
                    BsMealTableOrderProduct orderProduct = mealTableOrderProductService.getOrderProduct(tableOrder.getOrderNo(), cartProduct.getProductId());
                    if (orderProduct == null) {
                        orderProduct = new BsMealTableOrderProduct();
                        orderProduct.setOrderId(tableOrder.getId());
                        orderProduct.setOrderNo(tableOrder.getOrderNo());
                        orderProduct.setProductCategoryId(cartProduct.getProductCategoryId());
                        orderProduct.setProductCategoryName(cartProduct.getProductCategoryName());
                        orderProduct.setProductId(cartProduct.getProductId());
                        orderProduct.setProductImg(cartProduct.getProductImg());
                        orderProduct.setProductName(cartProduct.getProductName());
                        orderProduct.setProductSpec(cartProduct.getProductSpec());
                        orderProduct.setProductPrice(cartProduct.getProductPrice());
                        orderProduct.setProductNum(cartProduct.getProductNum());
                        orderProduct.setProductTotalPrice(new BigDecimal(orderProduct.getProductNum().toString()).multiply(orderProduct.getProductPrice()));
                        orderProduct.setStatus(1);
                    } else {
                        orderProduct.setProductNum(orderProduct.getProductNum() + cartProduct.getProductNum());
                        orderProduct.setProductTotalPrice(new BigDecimal(orderProduct.getProductNum().toString()).multiply(orderProduct.getProductPrice()));
                    }
                    mealTableOrderProductService.editData(orderProduct);


                    childProduct = new BsMealTableOrderChildProduct();
                    childProduct.setStoreId(tableOrderChild.getStoreId());
                    childProduct.setStoreName(tableOrderChild.getStoreName());
                    childProduct.setChildOrderId(tableOrderChild.getId());
                    childProduct.setChildOrderNo(tableOrderChild.getChildOrderNo());
                    childProduct.setProductCategoryId(cartProduct.getProductCategoryId());
                    childProduct.setProductCategoryName(cartProduct.getProductCategoryName());
                    childProduct.setProductId(cartProduct.getProductId());
                    childProduct.setProductImg(cartProduct.getProductImg());
                    childProduct.setProductName(cartProduct.getProductName());
                    childProduct.setProductSpec(cartProduct.getProductSpec());
                    childProduct.setProductPrice(cartProduct.getProductPrice());
                    childProduct.setProductNum(cartProduct.getProductNum());
                    childProduct.setProductTotalPrice(new BigDecimal(childProduct.getProductNum().toString()).multiply(childProduct.getProductPrice()));
                    childProduct.setStatus(1);
                    childProduct.setCreateTime(new Date());
                    childProduct.setUpdateTime(new Date());
                    childProductList.add(childProduct);
                    // 计算子订单总金额
                    tableOrderChild.setChildOrderAmount(tableOrderChild.getChildOrderAmount().add(childProduct.getProductTotalPrice()));
                }
                editData(tableOrderChild);

                // 批量插入子订单产品数据
                mealTableOrderChildProductMapper.addPatch(childProductList);

                // 修改交易订单数据
                tableOrder.setOrderAmount(tableOrder.getOrderAmount().add(tableOrderChild.getChildOrderAmount()));
                mealTableOrderService.editData(tableOrder);

                // 清楚购物车数据
                mealShopCartService.clearData(serialNumber);

                // 推送MQTT
                Map<String,Object> pushParam = new HashMap<>();
                pushParam.put("userIdentity", userIdentity);
                pushParam.put("cmdType", CmdTypeEnum.type6.getNumber());
                pushParam.put("productList", new JSONArray());
                mqttProviderService.publish(2, false, "MEAL_TABLE_" + serialNumber, JSONObject.toJSONString(pushParam));

                // TODO 打印小票
                Map<String,Object> deviceParam = new HashMap<>();
                deviceParam.put("storeId", tableOrder.getStoreId());
                deviceParam.put("deviceType", DeviceTypeEnum.type3.getNumber());
                List<BsDevice> deviceList = deviceService.getDeviceList(deviceParam);
                for (BsDevice device : deviceList) {
                    SpPrinterConfig sp = new SpPrinterConfig();
                    sp.print(device.getDeviceNo(), SpPrinterTemplate.mealOrder(tableOrder, tableOrderChild, childProductList), 1);
                }
                redisTemplate.delete(lockKey);

            } else {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.MEAL_TABLE_CREATE_BREAK_OUT_ERROR, "");
            }
        } catch (BaseException baseException) {
            redisTemplate.delete(lockKey);
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, baseException.getErrorMsg());

        } catch (Exception e) {
            redisTemplate.delete(lockKey);
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知错误");
        }
    }
}
