package com.ruoyi.mall.service.impl;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.ApiResult;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.mall.domain.*;
import com.ruoyi.mall.domain.vo.MallOrderGoodsVO;
import com.ruoyi.mall.service.*;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.stereotype.Service;
import com.ruoyi.mall.mapper.MallOrderOrderMapper;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;

/**
 * 订单Service业务层处理
 *
 * @author chang
 * @date 2021-11-25
 */
@Service
public class MallOrderOrderServiceImpl implements IMallOrderOrderService
{
    @Resource
    private MallOrderOrderMapper mallOrderOrderMapper;

    @Resource
    IMallGoodsGoodsService goodsService;

    @Resource
    IMallGoodsProductService productService;

    @Resource
    IMallGoodsSpecValueService specValueService;

    @Resource
    IMallMemberAddressService addressService;

    @Resource
    IMallMemberUserService memberUserService;

    @Resource
    IMallOrderGoodsService orderGoodsService;

    @Resource
    IMallMemberCartService memberCartService;

    @Resource
    IMallOrderBackService backService;

    @Resource
    private IMallOrderPostService mallOrderPostService;

    @Resource
    private RedisCache redisCache;

    /**
     * 查询订单
     *
     * @param id 订单主键
     * @return 订单
     */
    @Override
    public MallOrderOrder selectMallOrderOrderById(Long id)
    {
        Object test = redisCache.getCacheObject("test");
        System.out.println(test);
        return mallOrderOrderMapper.selectMallOrderOrderById(id);
    }

    /**
     * 查询订单列表
     *
     * @param mallOrderOrder 订单
     * @return 订单
     */
    @Override
    public List<MallOrderOrder> selectMallOrderOrderList(MallOrderOrder mallOrderOrder)
    {
        redisCache.setCacheObject("test", 123);
        return mallOrderOrderMapper.selectMallOrderOrderList(mallOrderOrder);
    }

    /**
     * 新增订单
     *
     * @param mallOrderOrder 订单
     * @return 结果
     */
    @Override
    public int insertMallOrderOrder(MallOrderOrder mallOrderOrder)
    {
        return mallOrderOrderMapper.insertMallOrderOrder(mallOrderOrder);
    }

    /**
     * 修改订单
     *
     * @param mallOrderOrder 订单
     * @return 结果
     */
    @Override
    public int updateMallOrderOrder(MallOrderOrder mallOrderOrder)
    {
        return mallOrderOrderMapper.updateMallOrderOrder(mallOrderOrder);
    }

    /**
     * 批量删除订单
     *
     * @param ids 需要删除的订单主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteMallOrderOrderByIds(Long[] ids)
    {
        for (Long id: ids) {
            List<MallOrderGoodsVO> list  = orderGoodsService.selectMallOrderGoodsByOrderId(id);
            for (MallOrderGoodsVO vo: list) {
                orderGoodsService.deleteMallOrderGoodsById(vo.getId());
            }
        }
        return mallOrderOrderMapper.deleteMallOrderOrderByIds(ids);
    }

    /**
     * 删除订单信息
     *
     * @param id 订单主键
     * @return 结果
     */
    @Override
    public int deleteMallOrderOrderById(Long id)
    {
        return mallOrderOrderMapper.deleteMallOrderOrderById(id);
    }

    /**
     * 生成订单
     *
     */
    @Transactional
    @Override
    public MallOrderOrder creatOrderByGoods(Map<String, Object> params) {
        MallGoodsProduct pro = productService.selectMallGoodsProductById(Long.valueOf(params.get("productId").toString()));

        //创建order Model
        MallOrderOrder order =  new MallOrderOrder();
        order.setUserId(Long.valueOf(params.get("userId").toString()));
        order.setPostFee(BigDecimal.valueOf(0));
        String orderNo = orderIdGenerator();
        order.setOrderNo(orderNo);

        // 购买数量
        BigDecimal count = new BigDecimal(MapUtils.getInteger(params, "count"));

        // 价格
        BigDecimal goodsPrice = pro.getPrice().multiply(count);
        order.setPayment(goodsPrice);
        order.setOrderPrice(goodsPrice);

        String couponId = "";
        if (params.containsKey("couponId")){
            couponId = params.get("couponId").toString();
        }

        // 邮费
        MallOrderPost mallOrderPost = mallOrderPostService.selectMallOrderPostById();
        if (ObjectUtils.isNotEmpty(mallOrderPost)){
            // 满足金额
            BigDecimal price = mallOrderPost.getPrice();
            // 邮费
            BigDecimal postFee = mallOrderPost.getPostFee();
            if (price != null && postFee != null){
                BigDecimal orderPrice = order.getOrderPrice();
                BigDecimal payment = order.getPayment();
                // 满足则不要运费
                if (orderPrice.compareTo(price) < 0){
                    order.setOrderPrice(orderPrice.add(postFee));
                    order.setPayment(payment.add(postFee));
                    order.setPostFee(postFee);
                }
            }
        }


        //如果使用优惠券
        if (!StringUtils.isEmpty(couponId)){
            Map<String, Object> map = memberUserService.checkCouponUsed(couponId,Long.valueOf(params.get("userId").toString()));
            memberUserService.updateCouponUsed(couponId,Long.valueOf(params.get("userId").toString()));
            goodsPrice = pro.getPrice().subtract(new BigDecimal(map.get("price").toString()));
            order.setPayment(goodsPrice.compareTo(new BigDecimal(0)) > 0 ? goodsPrice : new BigDecimal("0.01"));
        }

        order.setOrderPrice(order.getPayment());
        order.setStatus("0");
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        order.setCreateAt(formatter.format(new Date()));
        order.setBuyerMsg(params.get("buyerMsg").toString());

        MallMemberAddress address =  addressService.selectMallMemberAddressById(Long.valueOf(params.get("addressId").toString()));
        order.setReceiverName(address.getName());
        order.setReceiverPhone(address.getPhone());
        order.setReceiverProvince(address.getProvince());
        order.setReceiverCity(address.getCity());
        order.setReceiverArea(address.getArea());
        order.setReceiverAddress(address.getAddress());
        this.insertMallOrderOrder(order);

        if (pro.getStock() >= Integer.valueOf(params.get("count").toString())){
            //库存够，修改库存
            pro.setStock(pro.getStock() - Integer.valueOf(params.get("count").toString()));
            pro.setNumSale(pro.getNumSale() + Integer.valueOf(params.get("count").toString()));
        }else {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return null;
        }
        //修改库存、插入订单
        productService.updateMallGoodsProduct(pro);


        MallGoodsGoods goods = goodsService.selectMallGoodsGoodsById(Long.valueOf(params.get("goodId").toString()));
        //创建订单-商品 model
        MallOrderGoods orderGoods = new MallOrderGoods();
        orderGoods.setGoodsId(Long.valueOf(params.get("goodId").toString()));
        orderGoods.setOrderId(order.getId());
        orderGoods.setProductId(pro.getId());
        orderGoods.setGoodsName(goods.getGoodsName());
        orderGoods.setGoodsImg(goods.getGoodsImg());
        orderGoods.setProductName(pro.getProductName());
        orderGoods.setPrice(pro.getPrice());
        orderGoods.setTotal(Integer.parseInt(params.get("count").toString()));

        orderGoodsService.insertMallOrderGoods(orderGoods);
        return order;
    }

    @Override
    public MallOrderOrder queryByOrderSn(String orderNo) {
        return mallOrderOrderMapper.queryByOrderSn(orderNo);
    }

    /*
    * 购物车生成订单
    * */
    @Transactional
    @Override
    public MallOrderOrder creatOrderByCartIds(Map<String, Object> params) {
        String userId = params.get("userId").toString();
        String cartIds = params.get("cartIds").toString();
        String addressId = params.get("addressId").toString();

        //创建order Model
        MallOrderOrder order =  new MallOrderOrder();
        order.setUserId(Long.parseLong(userId));
        order.setPostFee(BigDecimal.valueOf(0));
        String orderNo = orderIdGenerator();
        order.setOrderNo(orderNo);
        order.setStatus("0");
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        order.setCreateAt(formatter.format(new Date()));
        order.setBuyerMsg(params.get("buyerMsg").toString());

        MallMemberAddress address =  addressService.selectMallMemberAddressById(Long.valueOf(addressId));
        order.setReceiverName(address.getName());
        order.setReceiverPhone(address.getPhone());
        order.setReceiverProvince(address.getProvince());
        order.setReceiverCity(address.getCity());
        order.setReceiverArea(address.getArea());
        order.setReceiverAddress(address.getAddress());
        this.insertMallOrderOrder(order);

        String[] cartIdList = cartIds.split(",");

        BigDecimal totlePrice = new BigDecimal(0);
        BigDecimal totlePriceN = new BigDecimal(0);

        for (String cartId : cartIdList) {
            MallMemberCart memberCart = memberCartService.selectMallMemberCartById(Long.parseLong(cartId));

            MallGoodsProduct pro = productService.selectMallGoodsProductById(memberCart.getProductId());
            if (pro.getStock() >= Integer.valueOf(memberCart.getTotal())){
                //库存够，修改库存
                pro.setStock(pro.getStock() - Integer.valueOf(memberCart.getTotal()));
                pro.setNumSale(pro.getNumSale() + Integer.valueOf(memberCart.getTotal()));
            }else {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return null;
            }
            //修改库存、插入订单
            productService.updateMallGoodsProduct(pro);

            MallGoodsGoods goods = goodsService.selectMallGoodsGoodsById(memberCart.getGoodsId());
            //创建订单-商品 model
            MallOrderGoods orderGoods = new MallOrderGoods();
            orderGoods.setGoodsId(Long.valueOf(memberCart.getGoodsId()));
            orderGoods.setOrderId(order.getId());
            orderGoods.setProductId(pro.getId());
            orderGoods.setGoodsName(goods.getGoodsName());
            orderGoods.setGoodsImg(goods.getGoodsImg());
            orderGoods.setProductName(pro.getProductName());
            orderGoods.setPrice(pro.getPrice());
            orderGoods.setTotal(memberCart.getTotal());

            orderGoodsService.insertMallOrderGoods(orderGoods);

            //下单成功 删除购物车
            memberCartService.deleteMallMemberCartById(Long.parseLong(cartId));

            //总金额计算
            totlePrice = totlePrice.add(pro.getPrice().multiply(new BigDecimal(Integer.valueOf(memberCart.getTotal()))));
            totlePriceN = totlePrice.add(pro.getPriceN().multiply(new BigDecimal(Integer.valueOf(memberCart.getTotal()))));
        }
        order.setOrderPrice(totlePrice);
        order.setPayment(totlePrice);
        String couponId = "";
        if (params.containsKey("couponId")){
            couponId = params.get("couponId").toString();
        }

        //如果使用优惠券
        if (!StringUtils.isEmpty(couponId)){
            Map<String, Object> map = memberUserService.checkCouponUsed(couponId,Long.valueOf(params.get("userId").toString()));
            memberUserService.updateCouponUsed(couponId,Long.valueOf( params.get("userId").toString()));
            BigDecimal payment = totlePrice.subtract(new BigDecimal(map.get("price").toString()));
            order.setPayment(payment.compareTo(new BigDecimal(0)) == 1 ? payment : new BigDecimal(0.01));
        }else {
            order.setPayment(totlePrice);
        }

        // 邮费
        MallOrderPost mallOrderPost = mallOrderPostService.selectMallOrderPostById();
        if (ObjectUtils.isNotEmpty(mallOrderPost)){
            // 满足金额
            BigDecimal price = mallOrderPost.getPrice();
            // 邮费
            BigDecimal postFee = mallOrderPost.getPostFee();
            if (price != null && postFee != null){
                BigDecimal orderPrice = order.getOrderPrice();
                BigDecimal payment = order.getPayment();
                // 满足则不要运费
                if (orderPrice.compareTo(price) < 0){
                    order.setOrderPrice(orderPrice.add(postFee));
                    order.setPayment(payment.add(postFee));
                    order.setPostFee(postFee);
                }
            }
        }
        this.updateMallOrderOrder(order);

        return order;
    }

    public static String orderIdGenerator() {
        String time = DateUtils.dateTimeNow();
        String randomString = RandomStringUtils.randomNumeric(8);
        return  time + randomString;
    }

    //订单状态0=待支付,1=待发货,2=待收货,3=待评论,4=已完成,5=退货中,6=退货成功,7=换货中,8=已取消
    public Boolean orderStatusRoute(int nowStatus, String orderId){

        MallOrderOrder order = this.selectMallOrderOrderById(Long.parseLong(orderId));
        switch (nowStatus) {
            case 1:
                return  "0".equals(order.getStatus()) ? true : false;
            case 2:
                if ("1".equals(order.getStatus()) || "5".equals(order.getStatus())){
                    return true;
                }else {
                    return false;
                }
            case 3:
                if ("2".equals(order.getStatus()) || "5".equals(order.getStatus())){
                    return true;
                }else {
                    return false;
                }
            case 4:
                return  "3".equals(order.getStatus()) ? true : false;
            case 5:
                if ("1".equals(order.getStatus()) || "2".equals(order.getStatus())){
                    return true;
                }else {
                    return false;
                }
            case 6:
                return  "5".equals(order.getStatus()) ? true : false;
            case 8:
                return  "0".equals(order.getStatus()) ? true : false;
            default: return false;
        }
    }

    //状态: 0=退款中,1=退款成功,2=取消退款,3=拒绝退款
    public Boolean refundStatusRoute(int nowStatus, String refundId){
        //订单状态0=待支付,1=待发货,2=待收货,3=待评论,4=已完成,5=退货中,6=退货成功,7=换货中,8=已取消
        MallOrderBack back = backService.selectMallOrderBackById(Long.parseLong(refundId));
        MallOrderOrder order = this.selectMallOrderOrderById(back.getOrderId());

        switch (nowStatus) {
            case 0:
                if ("1".equals(order.getStatus()) || "2".equals(order.getStatus())) {
                    return true;
                }else {
                    return false;
                }
            case 1:
                if ("5".equals(order.getStatus()) && "0".equals(back.getStatus())) {
                    return true;
                }else {
                    return false;
                }
            case 2:
                if ("5".equals(order.getStatus()) && "0".equals(back.getStatus())) {
                    return true;
                }else {
                    return false;
                }
            case 3:
                if ("5".equals(order.getStatus()) && "0".equals(back.getStatus())) {
                    return true;
                }else {
                    return false;
                }
            default: return false;
        }
    }

    @Override
    public PageInfo<MallOrderOrder> selectOrdersByType(String pageNum, String pageSize, String type, String userId) {
        PageHelper.startPage(Integer.parseInt(pageNum),Integer.parseInt(pageSize));
        List<MallOrderOrder> list = new ArrayList<>();
        if ("0".equals(type) || "1".equals(type) || "2".equals(type) || "3".equals(type)){
            String sqlStr = "('"+type+"')";
            list = mallOrderOrderMapper.selectOrdersByStatus(sqlStr,userId);
        }
        if ("-1".equals(type)){
            MallOrderOrder orderOrder = new MallOrderOrder();
            orderOrder.setUserId(Long.parseLong(userId));
            list = mallOrderOrderMapper.selectMallOrderOrderList(orderOrder);
        }

        if ("5".equals(type)){
            list = mallOrderOrderMapper.selectOrdersByStatus("('5','6')",userId);
        }

        for (MallOrderOrder orderOrder: list) {
            List<MallOrderGoodsVO> orderGoodsVOList = orderGoodsService.selectMallOrderGoodsByOrderId(orderOrder.getId());
            orderOrder.setGoodsVOList(orderGoodsVOList);
        }

        PageInfo<MallOrderOrder> page = new PageInfo<>(list);
        return page;
    }

    @Transactional
    @Override
    public void cancelOrder() {
        String compareTime = DateUtils.getBeforeTime(30);

        //订单列表
        List<MallOrderOrder> orderList = mallOrderOrderMapper.selectMallOrderByTime(compareTime);
        if (orderList.size() > 0){
            for (MallOrderOrder order: orderList) {
                //订单-商品列表
                List<MallOrderGoodsVO> goodsList = orderGoodsService.selectMallOrderGoodsByOrderId(order.getId());
                for (MallOrderGoodsVO goodsVO: goodsList) {
                    //商品-规格列表，恢复库存和销量
//                    MallGoodsProduct product = productService.selectMallGoodsProductById(goodsVO.getProductId());
//                    product.setStock(product.getStock() + goodsVO.getTotal());
//                    product.setNumSale(product.getNumSale() - goodsVO.getTotal());
//                    productService.updateMallGoodsProduct(product);

                    productService.updateMallGoodsProductByParams(goodsVO.getProductId(),goodsVO.getTotal());
                }
            }
        }
        mallOrderOrderMapper.taskCancleOrder(compareTime);
    }

    @Transactional
    @Override
    public void updateRefundRestlt(MallOrderBack orderBack, MallOrderOrder orderOrder) {
        backService.updateMallOrderBack(orderBack);
        updateMallOrderOrder(orderOrder);
    }

    @Transactional
    @Override
    public ApiResult updateMallOrderOrderByCancle(MallOrderOrder order) {
        try {
            this.updateMallOrderOrder(order);
            //改库存
            List<MallOrderGoodsVO> list = orderGoodsService.selectMallOrderGoodsByOrderId(order.getId());
            for (MallOrderGoodsVO vo: list) {
                productService.updateMallGoodsProductByParams(vo.getProductId(),vo.getTotal());
            }
            return ApiResult.ok("取消订单成功");
        }catch (Exception e){
            return ApiResult.error("取消订单失败");
        }


    }

    @Override
    public int checkTotleCount() {
        return mallOrderOrderMapper.checkTotleCount();
    }

    @Override
    public BigDecimal checkTotlePrice() {
        return mallOrderOrderMapper.checkTotlePrice();
    }

    @Override
    public BigDecimal checkYearDate(String year) {
        return mallOrderOrderMapper.checkYearDate(year);
    }

    @Override
    public BigDecimal checkYearAndMonth(String year, String month, String day) {
        return mallOrderOrderMapper.checkYearAndMonth(year,month,day);
    }

    @Override
    public int checkCountYearAndMonth(String year, String month, String day) {
        return mallOrderOrderMapper.checkCountYearAndMonth(year,month,day);
    }
}
