package com.platform.service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.JSONArray;
import com.platform.entity.*;
import com.platform.enums.ResultCodeEnum;
import com.platform.exception.CommonBaseException;

import com.platform.utils.RRException;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONObject;
import com.platform.cache.J2CacheUtils;
import com.platform.dao.ApiAddressMapper;
import com.platform.dao.ApiCartMapper;
import com.platform.dao.ApiCouponMapper;
import com.platform.dao.ApiOrderGoodsMapper;
import com.platform.dao.ApiOrderMapper;
import com.platform.util.CommonUtil;
import org.springframework.util.CollectionUtils;


@Service
@Slf4j
public class ApiOrderService {
    @Autowired
    private ApiOrderMapper orderDao;
    @Autowired
    private ApiAddressMapper apiAddressMapper;
    @Autowired
    private ApiCartMapper apiCartMapper;
    @Autowired
    private ApiCouponMapper apiCouponMapper;
    @Autowired
    private ApiOrderMapper apiOrderMapper;
    @Autowired
    private ApiOrderGoodsMapper apiOrderGoodsMapper;
    @Autowired
    private ApiProductService productService;
    @Autowired
    private ApiGoodsService apiGoodsService;
    @Autowired
    private ApiOrderShippingService apiOrderShippingService;

    @Autowired
    private ApiUserCouponService apiUserCouponService;

    @Autowired
    private ApiCouponService apiCouponService;

    //这里添加了selet for update，锁定当前订单
    public OrderVo queryObjectByOrderSn(String orderSn) {
        return orderDao.queryObjectByOrderSn(orderSn);
    }

    public OrderVo queryObject(Integer id) {
        return orderDao.queryObject(id);
    }


    public List<OrderVo> queryList(Map<String, Object> map) {
        return orderDao.queryList(map);
    }

    public long countOrderInfo(long userId , int status){
        return orderDao.countOrderInfo(userId , status);
    }

    public int queryTotal(Map<String, Object> map) {
        return orderDao.queryTotal(map);
    }


    public void save(OrderVo order) {
        orderDao.save(order);
    }


    public int update(OrderVo order) {
        return orderDao.update(order);
    }


    public void delete(Integer id) {
        orderDao.delete(id);
    }


    public void deleteBatch(Integer[] ids) {
        orderDao.deleteBatch(ids);
    }


    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> submit(JSONObject jsonParam, UserVo loginUser) {
        Map<String, Object> resultObj = new HashMap<String, Object>();

        String type = jsonParam.getString("type");
        String postscript = jsonParam.getString("postscript");
//        AddressVo addressVo = jsonParam.getObject("checkedAddress",AddressVo.class);
        AddressVo addressVo = apiAddressMapper.queryObject(jsonParam.getInteger("addressId"));


        // * 获取要购买的商品
        List<CartVo> checkedGoodsList = new ArrayList<>();
        BigDecimal goodsTotalPrice;
        if (type.equals("cart")) {
            Map<String, Object> param = new HashMap<String, Object>();
            param.put("user_id", loginUser.getUserId());
            param.put("session_id", 1);
            param.put("checked", 1);
            checkedGoodsList = apiCartMapper.queryList(param);
            if (null == checkedGoodsList) {
                resultObj.put("errno", 400);
                resultObj.put("errmsg", "请选择商品");
                return resultObj;
            }
            //统计商品总价
            goodsTotalPrice = new BigDecimal(0.00);
            for (CartVo cartItem : checkedGoodsList) {
                goodsTotalPrice = goodsTotalPrice.add(cartItem.getRetail_price().multiply(new BigDecimal(cartItem.getNumber())));
            }
        } else {
            BuyGoodsVo goodsVo = (BuyGoodsVo) J2CacheUtils.get(J2CacheUtils.SHOP_CACHE_NAME, "goods" + loginUser.getUserId());
            if(null == goodsVo){
                log.error("商品不存在");
                throw new RRException("商品不存在");
            }
            if(null == goodsVo.getNumber()){
                log.error("商品的购买数量不能为空");
                throw new RRException("商品的购买数量不能为空");
            }
            ProductVo productInfo = productService.queryObject(goodsVo.getProductId());
            //计算订单的费用
            //商品总价
            goodsTotalPrice = productInfo.getRetail_price().multiply(new BigDecimal(goodsVo.getNumber()));

            CartVo cartVo = new CartVo();
            BeanUtils.copyProperties(productInfo, cartVo);
            cartVo.setNumber(goodsVo.getNumber());
            cartVo.setProduct_id(goodsVo.getProductId());
            cartVo.setGoods_specifition_ids(goodsVo.getGoodsSpecifitionIds());
            checkedGoodsList.add(cartVo);
        }

        BigDecimal couponPrice = BigDecimal.ZERO.setScale(2 , RoundingMode.HALF_DOWN);
        //获取订单使用的优惠券
        JSONArray couponIdListJson = jsonParam.getJSONArray("couponIdList");
        List<Integer> couponIdList = null;
        String couponIdListStr = "";
        if(!CollectionUtils.isEmpty(couponIdListJson)){
            log.info("前面结算检查的时候使用了优惠券:{}",couponIdListJson.toJSONString());
            couponIdList = JSONArray.parseArray(couponIdListJson.toJSONString() , Integer.class);
        }else{
            log.info("前面结算检查的时候未使用优惠券");
        }
        if(!CollectionUtils.isEmpty(couponIdList)){
            for(Integer couponId : couponIdList){
                CouponVo couponVo = apiCouponService.queryObject(couponId);
                if(null == couponVo){
                    log.error("获取优惠券[{}]信息失败，无法减免优惠券金额" , couponId);
                }else{
                    couponPrice = couponPrice.add(couponVo.getTypeMoney());
                }
            }
            couponIdListStr = assembleCouponIdString(couponIdList);
        }
        log.info("微信支付之前，获取到优惠券金额为:{}，使用的优惠券列表为:{}" , couponPrice , couponIdListStr);

        //统计商品总价
        //统计商品的品牌种类和总金额,增加订单物流表
        Map<Integer, BigDecimal> brandMap = new HashMap<Integer, BigDecimal>();
        GoodsVo goodsVo = null;
        for (CartVo goodsItem : checkedGoodsList) {
            goodsVo = apiGoodsService.queryObject(goodsItem.getGoods_id());
            if(null != goodsVo){
                if(brandMap.get(goodsVo.getBrand_id()) == null){
                    brandMap.put(goodsVo.getBrand_id(), goodsItem.getRetail_price().multiply(new BigDecimal(goodsItem.getNumber())));
                }else {
                    brandMap.put(goodsVo.getBrand_id(), brandMap.get(goodsVo.getBrand_id()).add(goodsItem.getRetail_price().multiply(new BigDecimal(goodsItem.getNumber()))));
                }
            }

        }

        //每个品牌不满99元加10元运费
        //根据收货地址计算运费
        Integer freightPrice = 0;
        for (Integer key : brandMap.keySet()) {
            if(brandMap.get(key).doubleValue() < 99){
                //TODO:需要修改回来的
//                freightPrice += 10;
            }
        }

        //订单价格计算
        BigDecimal orderTotalPrice = goodsTotalPrice.add(new BigDecimal(freightPrice)); //订单的总价

        BigDecimal actualPrice = orderTotalPrice.subtract(couponPrice);  //减去其它支付的金额后，要实际支付的金额

        Long currentTime = System.currentTimeMillis() / 1000;

        //
        OrderVo orderInfo = new OrderVo();
        orderInfo.setOrder_sn(CommonUtil.generateOrderNumber());
        orderInfo.setUser_id(loginUser.getUserId());
        //收货地址和运费
        orderInfo.setConsignee(addressVo.getUserName());
        orderInfo.setMobile(addressVo.getTelNumber());
        orderInfo.setCountry(addressVo.getNationalCode());
        orderInfo.setProvince(addressVo.getProvinceName());
        orderInfo.setCity(addressVo.getCityName());
        orderInfo.setDistrict(addressVo.getCountyName());
        orderInfo.setAddress(addressVo.getDetailInfo());
        //物流费用
        orderInfo.setFreight_price(freightPrice);
        //留言
        orderInfo.setPostscript(postscript);
        //使用的优惠券
        orderInfo.setCoupon_id(couponIdListStr);
        orderInfo.setCoupon_price(couponPrice);
//        orderInfo.setAdd_time(new Date());
        orderInfo.setAdd_time(LocalDateTime.now());
        orderInfo.setGoods_price(goodsTotalPrice);
        orderInfo.setOrder_price(orderTotalPrice);
        orderInfo.setActual_price(actualPrice);
        // 待付款
        orderInfo.setOrder_status(0);
        orderInfo.setShipping_status(0);
        orderInfo.setPay_status(0);
        orderInfo.setShipping_id(0);
        orderInfo.setShipping_fee(new BigDecimal(0));
        orderInfo.setIntegral(0);
        orderInfo.setIntegral_money(new BigDecimal(0));
        if (type.equals("cart")) {
            orderInfo.setOrder_type("1");
        } else {
            orderInfo.setOrder_type("4");
        }

        //开启事务，插入订单信息和订单商品
        apiOrderMapper.save(orderInfo);
        if (null == orderInfo.getId()) {
            resultObj.put("errno", 1);
            resultObj.put("errmsg", "订单提交失败");
            return resultObj;
        }

        for (CartVo goodsItem : checkedGoodsList) {
            OrderGoodsVo orderGoodsVo = new OrderGoodsVo();
            orderGoodsVo.setOrder_id(orderInfo.getId());
            orderGoodsVo.setGoods_id(goodsItem.getGoods_id());
            orderGoodsVo.setGoods_sn(goodsItem.getGoods_sn());
            orderGoodsVo.setProduct_id(goodsItem.getProduct_id());
            orderGoodsVo.setGoods_name(goodsItem.getGoods_name());
            orderGoodsVo.setList_pic_url(goodsItem.getList_pic_url());
            orderGoodsVo.setMarket_price(goodsItem.getMarket_price());
            orderGoodsVo.setRetail_price(goodsItem.getRetail_price());
            orderGoodsVo.setNumber(goodsItem.getNumber());
            orderGoodsVo.setGoods_specifition_name_value(goodsItem.getGoods_specifition_name_value());
            orderGoodsVo.setGoods_specifition_ids(goodsItem.getGoods_specifition_ids());
            apiOrderGoodsMapper.save(orderGoodsVo);
        }

        OrderShippingVo shippingVo = new OrderShippingVo();
        for (Integer key : brandMap.keySet()) {
            shippingVo = new OrderShippingVo();
            shippingVo.setOrderId(orderInfo.getId());
            shippingVo.setBrandId(key);
            shippingVo.setTotalPrice(brandMap.get(key));
            if(brandMap.get(key).doubleValue() < 99){
                //TODO:这里的邮费统一写为0
                shippingVo.setFreightPrice(new BigDecimal(0));
                shippingVo.setTotalPrice(brandMap.get(key).add(new BigDecimal(0)));
            }else {
                shippingVo.setFreightPrice(new BigDecimal(0));
            }
            apiOrderShippingService.save(shippingVo);
        }
        //更新优惠券使用记录，写上相应的订单号以及翻转状态
        if(!CollectionUtils.isEmpty(couponIdList)){
            //更新优惠券的状态
            for(Integer couponId : couponIdList){
                UserCouponVo usedUserCoupon = apiUserCouponService.getByUserIdAndCouponId(loginUser.getUserId() , couponId);
                if(null == usedUserCoupon){
                    log.error("更新优惠券的使用状态失败");
                    throw new CommonBaseException(ResultCodeEnum.D101 , "更新优惠券状态失败");
                }
                usedUserCoupon.setUsedTime(new Date());
                usedUserCoupon.setOrderId(orderInfo.getId());
                //状态 1. 可用 2. 已用 3. 过期
                if(null != usedUserCoupon.getCouponStatus() && usedUserCoupon.getCouponStatus().compareTo(1) == 0){
                    usedUserCoupon.setCouponStatus(2);
                    log.info("更新优惠券[{}]为已经使用" , couponId);
                }
                apiUserCouponService.update(usedUserCoupon);

                //更新优惠券的使用量
                CouponVo couponVo = apiCouponService.selectCouponForUpdate(usedUserCoupon.getCouponId());
                if(null == couponVo){
                    log.error("获取使用的优惠券[{}]失败，无法更新此优惠券的使用量");
                    throw new CommonBaseException(ResultCodeEnum.D101 , "无法更新此优惠券的使用量");
                }
                long useNum = (null == couponVo.getUsedNumber() ? 0l : couponVo.getUsedNumber());
                useNum += 1;
                couponVo.setUsedNumber(useNum);
                couponVo.setUpdateTime(LocalDateTime.now());
                apiCouponMapper.update(couponVo);
                log.info("更新优惠券[{}]的使用数量成功" , couponVo.getId());
            }
        }

        //清空已购买的商品
        apiCartMapper.deleteByCart(loginUser.getUserId(), 1, 1);
        resultObj.put("errno", 0);
        resultObj.put("errmsg", "订单提交成功");
        //
        Map<String, OrderVo> orderInfoMap = new HashMap<String, OrderVo>();
        orderInfoMap.put("orderInfo", orderInfo);
        //
        resultObj.put("data", orderInfoMap);

        return resultObj;
    }

    private String assembleCouponIdString(List<Integer> couponIds){
        StringBuilder result = new StringBuilder();
        String totalResult = "";
        if(!CollectionUtils.isEmpty(couponIds)){
            for(Integer id : couponIds){
                result.append(id.toString()).append(",");
            }
            if(result.length() >= 1){
                totalResult = result.substring(0 , result.length() - 1);
            }
        }
        return totalResult;
    }

}
