package com.hfkj.service.order.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.hfkj.common.utils.StarbucksUtil;
import com.hfkj.dao.BsOrderChildMapper;
import com.hfkj.entity.*;
import com.hfkj.model.order.OrderChildModel;
import com.hfkj.qianzhu.StarbucksService;
import com.hfkj.service.BsProductConfigService;
import com.hfkj.service.goods.*;
import com.hfkj.service.goods.impl.BsOrderStarbucksServiceImpl;
import com.hfkj.service.order.BsOrderChildService;
import com.hfkj.service.order.BsOrderService;
import com.hfkj.sysenum.order.OrderChildProductTypeEnum;
import com.hfkj.sysenum.order.OrderChildStatusEnum;
import com.hfkj.sysenum.order.OrderLogisticsStatusEnum;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

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

/**
 * @className: BsOrderChildServiceImpl
 * @author: HuRui
 * @date: 2024/5/6
 **/
@Service("orderChildService")
public class BsOrderChildServiceImpl implements BsOrderChildService {
    @Resource
    private BsOrderChildMapper orderChildMapper;

    @Resource
    private GoodsUserAddressService goodsUserAddressService;

    @Resource
    private BsOrderGoodsService orderGoodsService;
    @Resource
    private GoodsVpdService goodsVpdService;
    @Resource
    private GoodsJumpService goodsJumpService;
    @Resource
    private BsOrderStarbucksServiceImpl bsOrderStarbucksService;
    @Resource
    private BsProductConfigService bsProductConfigService;

    @Resource
    private BsOrderService orderService;

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

    @Override
    public OrderChildModel getDetail(String childOrderNo) {
        BsOrderChildExample example = new BsOrderChildExample();
        example.createCriteria().andChildOrderNoEqualTo(childOrderNo);
        List<BsOrderChild> list = orderChildMapper.selectByExample(example);
        if (!list.isEmpty()) {
            OrderChildModel childModel = new OrderChildModel();
            BeanUtils.copyProperties(list.get(0), childModel);
            return childModel;
        }
        return null;

    }

    @Override
    public List<OrderChildModel> getOrderChildListByOrderNo(String orderNo) {
        BsOrderChildExample example = new BsOrderChildExample();
        example.createCriteria().andOrderNoEqualTo(orderNo);
        example.setOrderByClause("id");
        List<BsOrderChild> list = orderChildMapper.selectByExample(example);

        List<OrderChildModel> orderChildModelList = new ArrayList<>();

        for (BsOrderChild orderChild : list) {
            OrderChildModel childModel = new OrderChildModel();
            BeanUtils.copyProperties(orderChild, childModel);

            if (childModel.getProductType().equals(OrderChildProductTypeEnum.type1.getCode())) {
                BsOrderGoods orderGoods = orderGoodsService.findGoodsOrder(orderNo);
                if (orderGoods != null) {
                    GoodsUserAddress address;
                    if (orderGoods.getDeliveryAddressId() != null) {
                        address = goodsUserAddressService.queryDetail(orderGoods.getDeliveryAddressId());
                    } else {
                        Map<String , Object> map = new HashMap<>();
                        map.put("userId" , orderGoods.getUserId());
                        address = goodsUserAddressService.queryDetailByMap(map);
                    }
       
                    JSONObject object;
                    if (childModel.getBusiness() == null) {
                        object = new JSONObject();
                    } else {
                        object = new JSONObject((Map<String, Object>) childModel.getBusiness());
                    }

                    // 查询商品虚拟信息
                    GoodsJump goodsJump = goodsJumpService.queryDetailBySpecsId(orderChild.getProductSpecId());

                    object.put("goodsJump", goodsJump);
                    object.put("address", address);
                    object.put("orderGoodsId", orderGoods.getId());
                    childModel.setBusiness(object);

                    if (orderGoods.getLogisticsStatus() != null && orderGoods.getLogisticsStatus().equals(OrderLogisticsStatusEnum.statusSIGN.getCode())) {
                        // 子订单完成
                        orderService.childOrderComplete(orderGoods.getChildOrderNo());
                        orderGoods.setStatus(OrderChildStatusEnum.status3.getCode());
                        orderGoods.setUpdateTime(new Date());
                        orderGoodsService.update(orderGoods);
                        // 删除缓存
                        orderService.cacheDelete(orderGoods.getOrderNo());
                    }

                }
            } else if (childModel.getProductType().equals(OrderChildProductTypeEnum.type2.getCode())) {
                childModel.setBusiness(goodsVpdService.queryDetailBySpecsId(childModel.getProductSpecId()));
            } else if (childModel.getProductType().equals(OrderChildProductTypeEnum.type4.getCode())) {
                BsProductConfig productConfig = bsProductConfigService.queryDetail(OrderChildProductTypeEnum.type4.getCode());
                // 查询星巴克订单列表信息
                Map<String , Object> map = new HashMap<>();
                map.put("orderNo", childModel.getOrderNo());
                List<BsOrderStarbucks> starbucksList = bsOrderStarbucksService.getList(map);
                JSONObject object = new JSONObject();
                object.put("storeName", starbucksList.get(0).getStoreName());
                object.put("storeAddress", starbucksList.get(0).getStoreAddress());
                object.put("status", starbucksList.get(0).getStatus());
                // 查询星巴克订单详情
                Map<String , Object> orderMap = new HashMap<>();
                orderMap.put("orderNo" , orderChild.getChannelOrderNo());
                JSONObject objectOrder = StarbucksService.starbucksOrder(orderMap);
                // 如果查询上游订单数据不为空 则回填上游数据
                JSONObject orderJson;
                List<JSONObject> orderItemList = new ArrayList<>();
                if (objectOrder != null) {
                    // 订单数据
                    JSONObject order = objectOrder.getJSONObject("data");
                    // 修改订单数据
                    bsOrderStarbucksService.updateOrderStatus(orderChild.getOrderNo() , order.getInteger("status"));
                    // 修改订单状态
                    object.put("status", order.getInteger("status"));
                    // 订单业务数据
                    JSONArray orderItems = order.getJSONArray("orderItems");

                    for (Object orderItem : orderItems) {
                        JSONObject orderItemJson = (JSONObject) orderItem;
                        orderJson = new JSONObject();
                        orderJson.put("name" , orderItemJson.getString("productName"));
                        orderJson.put("failReason" , orderItemJson.getString("failReason"));
                        orderJson.put("code" , orderItemJson.getString("code"));
                        orderJson.put("img" , orderItemJson.getString("imgUrl"));
                        orderJson.put("num" , orderItemJson.getInteger("quantity"));
                        orderJson.put("status" , orderItemJson.getInteger("status"));
                        orderJson.put("price" , StarbucksUtil.calculatePrice(productConfig.getDiscount() , orderItemJson.getBigDecimal("unitPrice")));
                        orderJson.put("totalPrice" , orderJson.getBigDecimal("price").multiply(orderJson.getBigDecimal("num")));
                        orderJson.put("speList"  , StarbucksUtil.speString(orderItemJson.getString("cupSize") ,
                                orderItemJson.getString("temperature") , orderItemJson.getString("cream") ,
                                orderItemJson.getString("espresso") , orderItemJson.getString("milk") ,
                                orderItemJson.getString("milkBubble") , "/"));
                        orderJson.put("speDetail"  , StarbucksUtil.speString(orderItemJson.getString("cupSize") ,
                                orderItemJson.getString("temperature") , orderItemJson.getString("cream") ,
                                orderItemJson.getString("espresso") , orderItemJson.getString("milk") ,
                                orderItemJson.getString("milkBubble") , "</br>"));
                        orderItemList.add(orderJson);
                    }


                } else {
                    for (BsOrderStarbucks starbucks : starbucksList) {
                        orderJson = new JSONObject();
                        orderJson.put("name" , starbucks.getName());
                        orderJson.put("img" , starbucks.getImg());
                        orderJson.put("num" , starbucks.getNum());
                        orderJson.put("price" , starbucks.getPrice());
                        orderJson.put("totalPrice" , starbucks.getPrice().multiply(new BigDecimal(starbucks.getNum())));
                        orderJson.put("speList"  , StarbucksUtil.speString(starbucks.getCupSize() , starbucks.getTemperature() ,
                                starbucks.getCream() , starbucks.getEspresso() ,
                                starbucks.getMilk() , starbucks.getMilkBubble() , "/"));
                        orderJson.put("speDetail" , StarbucksUtil.speString(starbucks.getCupSize() ,
                                starbucks.getTemperature() , starbucks.getCream() , starbucks.getEspresso() ,
                                starbucks.getMilk() , starbucks.getMilkBubble() , "</br>"));
                        orderItemList.add(orderJson);
                    }
                }

                object.put("orderItemList", orderItemList);
                childModel.setBusiness(object);

            }
            orderChildModelList.add(childModel);
        }
        return orderChildModelList;
    }

    @Override
    public List<BsOrderChild> getList(Map<String, Object> map) {
        BsOrderChildExample example = new BsOrderChildExample();
        BsOrderChildExample.Criteria criteria = example.createCriteria();

        if (MapUtils.getLong(map, "merId") != null) {
            criteria.andMerIdEqualTo(MapUtils.getLong(map, "merId"));
        }

        if (StringUtils.isNotBlank(MapUtils.getString(map, "orderNo"))) {
            criteria.andOrderNoEqualTo(MapUtils.getString(map, "orderNo"));
        }
        if (StringUtils.isNotBlank(MapUtils.getString(map, "childOrderNo"))) {
            criteria.andChildOrderNoEqualTo(MapUtils.getString(map, "childOrderNo"));
        }

        if (StringUtils.isNotBlank(MapUtils.getString(map, "productSpecName"))) {
            criteria.andProductSpecNameLike(MapUtils.getString(map, "productSpecName"));
        }
        if (MapUtils.getInteger(map, "productType") != null) {
            criteria.andProductTypeEqualTo(MapUtils.getInteger(map, "productType"));
        }

        if (StringUtils.isNotBlank(MapUtils.getString(map, "productName"))) {
            criteria.andProductNameLike("%"+MapUtils.getString(map, "productName")+"%");
        }

        if (MapUtils.getLong(map, "createTimeS") != null) {
            criteria.andCreateTimeGreaterThanOrEqualTo(new Date(MapUtils.getLong(map, "createTimeS")));
        }
        if (MapUtils.getLong(map, "createTimeE") != null) {
            criteria.andCreateTimeLessThan(new Date(MapUtils.getLong(map, "createTimeE")));
        }
        if (MapUtils.getInteger(map, "status") != null) {
            criteria.andStatusEqualTo(MapUtils.getInteger(map, "status"));
        }
        example.setOrderByClause("create_time desc");

        return orderChildMapper.selectByExample(example);
    }

    @Override
    public long getUndoneChildOrder(String orderNo) {
        BsOrderChildExample example = new BsOrderChildExample();
        example.createCriteria().andOrderNoEqualTo(orderNo).andStatusNotEqualTo(OrderChildStatusEnum.status3.getCode());
        return orderChildMapper.countByExample(example);
    }
}
