/*
 * Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
 *
 * https://www.gz-yami.com/
 *
 */

package com.yami.shop.groupbuy.comment.service.impl;


import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Snowflake;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.bean.dto.OrderRefundDto;
import com.yami.shop.bean.enums.*;
import com.yami.shop.bean.model.Order;
import com.yami.shop.bean.model.OrderRefund;
import com.yami.shop.bean.model.Product;
import com.yami.shop.groupbuy.comment.api.dto.ApiGroupTeamDto;
import com.yami.shop.groupbuy.comment.api.dto.ApiJoinGroupTeamDto;
import com.yami.shop.groupbuy.comment.dao.GroupActivityMapper;
import com.yami.shop.groupbuy.comment.dao.GroupOrderMapper;
import com.yami.shop.groupbuy.comment.dao.GroupTeamMapper;
import com.yami.shop.groupbuy.comment.dto.GroupRefundOrder;
import com.yami.shop.groupbuy.comment.dto.GroupTeamDto;
import com.yami.shop.groupbuy.comment.enums.GroupOrderStatusEnum;
import com.yami.shop.groupbuy.comment.enums.TeamStatusEnum;
import com.yami.shop.groupbuy.comment.model.GroupOrder;
import com.yami.shop.groupbuy.comment.model.GroupProd;
import com.yami.shop.groupbuy.comment.model.GroupTeam;
import com.yami.shop.groupbuy.comment.service.GroupOrderService;
import com.yami.shop.groupbuy.comment.service.GroupProdService;
import com.yami.shop.groupbuy.comment.service.GroupTeamService;
import com.yami.shop.service.OrderRefundService;
import com.yami.shop.service.OrderService;
import com.yami.shop.service.ProductService;
import lombok.AllArgsConstructor;
import ma.glasnost.orika.MapperFacade;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 拼团团队表
 *
 * @author LGH
 * @date 2019-08-27 17:55:57
 */
@Service
@AllArgsConstructor
public class GroupTeamServiceImpl extends ServiceImpl<GroupTeamMapper, GroupTeam> implements GroupTeamService {

    private final GroupTeamMapper groupTeamMapper;
    private final GroupActivityMapper groupActivityMapper;
    private final GroupOrderMapper groupOrderMapper;
    private final GroupProdService groupProdService;
    private final GroupOrderService groupOrderService;
    private final ProductService productService;
    private final OrderRefundService orderRefundService;
    private final OrderService orderService;
    private final Snowflake snowflake;
    private final MapperFacade mapperFacade;

    /**
     * 获取分页列表
     */
    @Override
    public IPage<GroupTeamDto> getPage(Page page, GroupTeamDto groupTeamDto) {
        return groupTeamMapper.getPage(page, groupTeamDto);
    }

    /**
     * 可加入的团列表
     *
     * @param groupActivityId 拼团活动ID
     * @param prodId          商品ID
     * @return 团列表（最近n个）
     */
    @Override
    public List<ApiGroupTeamDto> listJoinGroup(Long groupActivityId, Long prodId, Integer showSize) {
        return groupTeamMapper.listByJoinGroupAndNowDate(groupActivityId, prodId, new Date(), showSize);
    }

    /**
     * 获取拼团单（拼团团队）信息
     *
     * @param groupTeamId 团单ID
     * @return ApiGroupTeamDto对象
     */
    @Override
    public ApiGroupTeamDto getApiGroupTeamDto(Long groupTeamId) {
        return groupTeamMapper.getApiGroupTeamDtoByTeamId(groupTeamId);
    }

    /**
     * 获取参加的拼团团队信息
     *
     * @param groupActivityId 活动ID
     * @param prodId          商品ID
     * @return 拼团团队ID
     */
    @Override
    public ApiJoinGroupTeamDto getJoinGroupTeamHasMaxNum(Long groupActivityId, Long prodId) {
        return groupTeamMapper.getJoinGroupTeamHasMaxNum(groupActivityId, prodId);
    }

    /**
     * 获取活动结束或团单结束未成团的拼团团队
     *
     * @return ApiGroupTeamDto对象
     */
    @Override
    public List<GroupTeam> getNotGroupTeam() {
        return groupTeamMapper.getNotGroupTeamByNowDate(new Date());
    }

    /**
     * 处理活动结束或团单结束未成团的拼团团队
     *
     * @param groupTeam 未成团的拼团团队
     * @return 退款单列表
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateNotGroupTeam(GroupTeam groupTeam) {
        Date nowDate = new Date();
        // 机器人列表
        List<GroupOrder> robot = new ArrayList<>();
        // 拼团成功的活动商品列表（机器人）
        List<GroupProd> groupProdList = new ArrayList<>();

        // 修改订单状态(拼团中的状态定时任务修改不了及防止待成团订单重新进行支付)
        List<Order> changeStatusOrderList = new ArrayList<>();

        // 需要还原库存的订单
        List<Order> returnStockOrders = new ArrayList<>();

        // 未支付的拼团，不需要进行退款的操作
        if (groupTeam.getStatus().equals(TeamStatusEnum.WAITING_GROUP.value())) {
            groupTeam.setStatus(TeamStatusEnum.FAIL.value());
            // 获取拼团失败要取消的订单
            List<Order> teamOrderList = groupTeamMapper.getOrders(groupTeam.getGroupTeamId(),null);
//            System.out.println(teamOrderList+"------------");
            if(CollectionUtils.isNotEmpty(teamOrderList)){
                // 需要还原库存的订单
                returnStockOrders.addAll(teamOrderList);
                for (Order order : teamOrderList) {
                    order.setHbOrderStatus(OrderStatus.CLOSE.value());
                    order.setCancelTime(nowDate);
                    order.setUpdateTime(nowDate);
                    changeStatusOrderList.add(order);
                }
            }
        }

        // 如果未成团，有机器人可以成团，不需要进行退款的操作
        if (groupTeam.getStatus().equals(TeamStatusEnum.IN_GROUP.value()) && groupTeam.getHasRobot() == 1) {
            // 更新活动物品成团订单数/已成团人数
            GroupProd groupProd = groupProdService.getById(groupTeam.getGroupProdId());
            groupProd.setGroupOrderCount(groupProd.getGroupNumberCount() + groupTeam.getJoinNum());
            groupProd.setGroupNumberCount(groupOrderMapper.getHadGroupNumberCount(groupProd.getGroupActivityId(), groupProd.getGroupProdId()));
            groupProdList.add(groupProd);

            // 模拟参团操作（添加机器人）
            for (int i = 0; i < groupTeam.getGroupNumber() - groupTeam.getJoinNum(); i++) {

                GroupOrder groupOrder = new GroupOrder();
                groupOrder.setShopId(groupTeam.getShopId());
                groupOrder.setGroupTeamId(groupTeam.getGroupTeamId());
                groupOrder.setUserId("0");
                groupOrder.setIdentityType(0);
                groupOrder.setStatus(1);
                groupOrder.setCreateTime(nowDate);
                robot.add(groupOrder);
            }
            // 更新拼团团队订单
            groupTeam.setJoinNum(groupTeam.getGroupNumber());
            groupTeam.setStatus(TeamStatusEnum.SUCCESS.value());

            // 更新所有的已支付订单状态
            List<Order> teamOrderList = groupTeamMapper.getOrders(groupTeam.getGroupTeamId(),1);
            for (Order order : teamOrderList) {
                order.setHbOrderStatus(OrderStatus.PADYED.value());
                changeStatusOrderList.add(order);
            }
            // 获取未支付要取消的订单
            List<Order> unPayOrderList = groupTeamMapper.getOrders(groupTeam.getGroupTeamId(),0);
//            System.out.println(teamOrderList+"------------");
            if(CollectionUtils.isNotEmpty(unPayOrderList)){
                // 需要还原库存的订单
                returnStockOrders.addAll(unPayOrderList);
                for (Order order : unPayOrderList) {
                    order.setHbOrderStatus(OrderStatus.CLOSE.value());
                    order.setUpdateTime(nowDate);
                    order.setCancelTime(nowDate);
                    changeStatusOrderList.add(order);
                }
            }
        }

        // 如果在拼团中订单且没有模拟成团则需要退款
        if (groupTeam.getStatus().equals(TeamStatusEnum.IN_GROUP.value()) && groupTeam.getHasRobot() == 0) {
            // 更新拼团团队订单
            groupTeam.setStatus(TeamStatusEnum.FAIL.value());

            // 查询未成团的订单列表
            List<GroupRefundOrder> groupRefundOrders = groupTeamMapper.getJoinNotGroupTeamOrder(groupTeam.getGroupTeamId());
            // 需要退款订单
            List<GroupRefundOrder> needRefundOrder = new ArrayList<>();
            // 无需退款订单
            List<GroupOrder> noNeedGroupOrder = new ArrayList<>();

            for (GroupRefundOrder groupRefundOrder : groupRefundOrders) {
                if (groupRefundOrder.getPayStatus() == 1) {
                    needRefundOrder.add(groupRefundOrder);
                } else {
                    GroupOrder groupOrder = new GroupOrder();
                    groupOrder.setGroupOrderId(groupRefundOrder.getGroupOrderId());
                    groupOrder.setStatus(GroupOrderStatusEnum.FAIL.value());
                    noNeedGroupOrder.add(groupOrder);
                }

                // 修改订单退款状态
                Order order = new Order();
                order.setOrderId(groupRefundOrder.getOrderId());
                order.setHbOrderStatus(OrderStatus.CLOSE.value());
                order.setCancelTime(new Date());
                order.setUpdateTime(new Date());
                order.setRefundStatus(RefundStatusEnum.SUCCEED.value());
                changeStatusOrderList.add(order);
            }

            // 将订单变为失效状态
            if (CollectionUtil.isNotEmpty(noNeedGroupOrder)) {
                groupOrderService.updateBatchById(noNeedGroupOrder);
            }


            List<OrderRefundDto> orderRefundDtos = saveRefundOrderAndGetOrderRefundDtoByGroupTeamId(needRefundOrder);
            // 真正的退款操作
            orderRefundService.systemAutoRefundBatch(orderRefundDtos);
        }

        // 更新拼团团队信息
        groupTeam.setUpdateTime(nowDate);
        updateById(groupTeam);

        // 取消订单，还原库存
        if (CollectionUtils.isNotEmpty(returnStockOrders)) {
            orderService.cancelOrders(returnStockOrders,"用户主动取消");
        }
        // 批量保存机器人
        if (robot.size() > 0) {
            groupOrderService.saveBatch(robot);
        }
        // 批量更新拼团成功的活动商品列表
        if (groupProdList.size() > 0) {
            groupProdService.saveOrUpdateBatch(groupProdList);
        }

        // 更新订单状态
        if (changeStatusOrderList.size() > 0) {
            orderService.saveOrUpdateBatch(changeStatusOrderList);
        }

        // 批量清除商品拼团活动ID
        List<Product> products = groupActivityMapper.getActivityFinishProduct(nowDate);
        for (Product product : products) {
//            product.setGroupActivityId(0L);
            product.setActivityId(0L);
            product.setProdType(ProdType.PROD_TYPE_NORMAL.value());
        }
        if (products.size() > 0) {
            productService.saveOrUpdateBatch(products);
        }
    }

    @Override
    public List<GroupTeam> getNotGroupTeamsByActivityIdAndGroupProdId(Long groupActivityId, Long groupProdId) {
        return groupTeamMapper.getNotGroupTeamsByActivityIdAndGroupProdId(groupActivityId, groupProdId);
    }

    @Override
    public List<GroupTeam> getNotGroupTeamsByActivityId(Long groupActivityId) {
        return groupTeamMapper.getNotGroupTeamsByActivityId(groupActivityId);
    }

    @Override
    public List<GroupTeam> getNotGroupTeamByProdId(Long prodId) {
        return groupTeamMapper.getNotGroupTeamByProdId(prodId);
    }

    /**
     * 并生成退款单并保存到数据库，且获组装退款dto
     */
    private List<OrderRefundDto> saveRefundOrderAndGetOrderRefundDtoByGroupTeamId(List<GroupRefundOrder> groupRefundOrder) {
        // 退款单列表
        List<OrderRefund> orderRefundList = new ArrayList<>();
        // 退款数据列表
        List<OrderRefundDto> orderRefundDtoList = new ArrayList<>();

        for (GroupRefundOrder refundOrder : groupRefundOrder) {
            // 生成退款单信息
            OrderRefund orderRefund = new OrderRefund();
            orderRefund.setRefundSn(String.valueOf(snowflake.nextId()));
            orderRefund.setShopId(refundOrder.getShopId());
            orderRefund.setUserId(refundOrder.getUserId());
            orderRefund.setOrderId(refundOrder.getOrderId());
            orderRefund.setRefundType(RefundType.ALL.value());
            orderRefund.setRefundAmount(refundOrder.getActualTotal());
            orderRefund.setApplyType(1);
            orderRefund.setIsReceiver(false);
            orderRefund.setBuyerReason("拼团失败：系统自动退款");
            orderRefund.setBuyerDesc("拼团失败：系统自动退款");
            orderRefund.setReturnMoneySts(ReturnMoneyStsType.SUCCESS.value());
            orderRefund.setSellerMsg("拼团失败：系统自动退款");
            orderRefund.setApplyTime(new Date());
            orderRefund.setHandelTime(new Date());
            orderRefund.setUpdateTime(new Date());
            orderRefundList.add(orderRefund);

            // 生成退款数据
            OrderRefundDto orderRefundDto = mapperFacade.map(orderRefund, OrderRefundDto.class);
            orderRefundDto.setOrderNumber(refundOrder.getOrderNumber());
            orderRefundDto.setOrderAmount(refundOrder.getActualTotal());
            orderRefundDto.setSettlementId(refundOrder.getSettlementId());
            orderRefundDto.setOrderPayNo(refundOrder.getOrderPayNo());
            orderRefundDto.setDistributionTotalAmount(0.0);
            orderRefundDtoList.add(orderRefundDto);
        }

        if (orderRefundList.size() > 0) {
            orderRefundService.saveBatch(orderRefundList);
        }
        return orderRefundDtoList;
    }
}
