package com.seer.teach.mall.order.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.seer.teach.common.PageListBean;
import com.seer.teach.common.enums.CommentStatusEnum;
import com.seer.teach.common.enums.OrderStatusEnum;
import com.seer.teach.common.enums.ResultCodeEnum;
import com.seer.teach.common.enums.ShippingStatusEnum;
import com.seer.teach.common.exception.CommonException;
import com.seer.teach.common.utils.AssertUtils;
import com.seer.teach.common.utils.PageConverterUtils;
import com.seer.teach.mall.convert.OrderConverter;
import com.seer.teach.mall.convert.OrderGoodsConverter;
import com.seer.teach.mall.entity.OrderChildEntity;
import com.seer.teach.mall.entity.OrderEntity;
import com.seer.teach.mall.entity.OrderGoodsEntity;
import com.seer.teach.mall.order.controller.req.OrderChildDeliveryReq;
import com.seer.teach.mall.order.service.IAdminOrderChildService;
import com.seer.teach.mall.request.OrderPageListReq;
import com.seer.teach.mall.response.OrderChildResp;
import com.seer.teach.mall.service.IOrderChildService;
import com.seer.teach.mall.service.IOrderGoodsService;
import com.seer.teach.mall.service.IOrderService;
import com.seer.teach.mall.util.OrderLogUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class AdminOrderChildServiceImpl implements IAdminOrderChildService {

    private final IOrderChildService orderChildService;

    private final IOrderGoodsService orderGoodsService;

    private final IOrderService orderService;

    @Override
    public PageListBean<OrderChildResp> getChildOrderPage(OrderPageListReq params) {
        Integer userId = StpUtil.getLoginIdAsInt();
        Page<OrderChildEntity> page = orderChildService.page(new Page<>(params.getPage(), params.getLimits()), new LambdaQueryWrapper<OrderChildEntity>()
                .eq(Objects.nonNull(params.getOrderSn()), OrderChildEntity::getChildOrderSn, params.getOrderSn())
                .eq(Objects.nonNull(params.getOrderStatus()), OrderChildEntity::getOrderStatus, params.getOrderStatus())
                .eq(OrderChildEntity::getMerchantUserId, userId));
        if(CollectionUtil.isEmpty(page.getRecords())){
            return new PageListBean<>();
        }

        PageListBean<OrderChildResp> orderChildRespPage = PageConverterUtils.convertPageListBean(page, OrderConverter.INSTANCE::convertOrderChildren);

        List<OrderChildEntity> orderChildEntities = page.getRecords();
        Set<Integer> parentOrderIds = orderChildEntities.stream().map(OrderChildEntity::getParentOrderId).collect(Collectors.toSet());
        List<OrderEntity> orderEntities = orderService.getListByOrderIds(parentOrderIds);
        Map<Integer, OrderEntity> map = orderEntities.stream().collect(Collectors.toMap(OrderEntity::getId, Function.identity(), (old, newItem) -> newItem));
        orderChildRespPage.getList().forEach(orderChildResp -> {
            OrderEntity orderEntity = map.get(orderChildResp.getParentOrderId());
            if(Objects.nonNull(orderEntity)){
                orderChildResp.setAddressId(orderEntity.getAddressId());
                orderChildResp.setCity(orderEntity.getCity());
                orderChildResp.setProvince(orderEntity.getProvince());
                orderChildResp.setDistrict(orderEntity.getDistrict());
                orderChildResp.setMobile(orderEntity.getMobile());
                orderChildResp.setPostscript(orderEntity.getPostscript());
                orderChildResp.setConsignee(orderEntity.getConsignee());
                orderChildResp.setAddress(orderEntity.getAddress());
            }
        });
        return orderChildRespPage;
    }

    @Override
    public OrderChildResp getOrderChildDetail(Integer orderId) {
        int userId = StpUtil.getLoginIdAsInt();
        log.info("用户[{}]开始查询订单详情，订单ID: {}", userId, orderId);

        LambdaQueryWrapper<OrderChildEntity> orderQueryWrapper = new LambdaQueryWrapper<OrderChildEntity>()
                .eq(OrderChildEntity::getId, orderId);

        OrderChildEntity queryOrder = orderChildService.getOne(orderQueryWrapper);

        if (Objects.isNull(queryOrder)) {
            log.warn("未找到订单，订单ID: {}", orderId);
            throw new CommonException(ResultCodeEnum.ORDER_NOT_FOUND);
        }

        log.debug("找到订单信息: {}", queryOrder);

        OrderChildResp orderChildResp = OrderConverter.INSTANCE.convertOrderChild2Resp(queryOrder);

        LambdaQueryWrapper<OrderGoodsEntity> goodsQueryWrapper = new LambdaQueryWrapper<OrderGoodsEntity>()
                .eq(OrderGoodsEntity::getChildOrderId, orderId);

        List<OrderGoodsEntity> goodsList = orderGoodsService.list(goodsQueryWrapper);
        log.debug("订单[{}]关联的商品数量为: {}", orderId, goodsList.size());

        orderChildResp.setOrderItems(OrderGoodsConverter.INSTANCE.list(goodsList));
        log.info("成功返回订单详情，订单ID: {}", orderId);
        return orderChildResp;
    }


    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED, timeout = 120)
    @Override
    public boolean deliveryOrder(Integer orderChildId, OrderChildDeliveryReq orderChildDeliveryReq) {
        Integer userId = StpUtil.getLoginIdAsInt();
        OrderChildEntity orderChildEntity = orderChildService.checkOrderChild(orderChildId);
        log.info("子订单信息：{}", orderChildEntity);
        AssertUtils.isTrue(OrderStatusEnum.PAID.getCode() == orderChildEntity.getOrderStatus(), ResultCodeEnum.ORDER_NOT_WAIT_SHIP);

        List<OrderChildEntity> childEntities = orderChildService.getListByParentIds(CollUtil.newHashSet(orderChildEntity.getParentOrderId()));

        Set<OrderChildEntity> otherUserOrders = childEntities.stream().filter(orderChild -> !Objects.equals(orderChild.getId(), orderChildId)).collect(Collectors.toSet());

        log.info("用户[{}]开始发货，订单ID: {}", userId, orderChildId);
        // 更新订单的状态和物流单号
        boolean updateOrderStatusResult = orderChildService.deliveryOrder(orderChildId, orderChildDeliveryReq.getLogisticsCode(), orderChildDeliveryReq.getShippingNo(), userId);
        log.info("更新订单状态结果：{}", updateOrderStatusResult);

        if (CollectionUtil.isEmpty(otherUserOrders)) {
            orderService.deliveryOrder(orderChildEntity.getParentOrderId(), orderChildDeliveryReq.getLogisticsCode(), orderChildDeliveryReq.getShippingNo(),userId);
            OrderLogUtils.setDeliveryOrderInfo(orderChildEntity.getParentOrderId(), orderChildEntity.getId(), userId, ShippingStatusEnum.SHIPPED, CommentStatusEnum.NON_COMMENTED);
            return updateOrderStatusResult;
        }
        // 判断是否有未发货的订单
        Optional<OrderChildEntity> any = otherUserOrders.stream().filter(orderChild -> {
            if (Objects.isNull(orderChild.getOrderStatus())) {
                return true;
            }
            return orderChild.getOrderStatus() != OrderStatusEnum.SHIPPED.getCode() && orderChild.getOrderStatus() != OrderStatusEnum.PART_ORDER_SHIPPED.getCode();
        }).findAny();
        if (!any.isPresent()) {
            orderService.deliveryOrder(orderChildEntity.getParentOrderId(), orderChildDeliveryReq.getLogisticsCode(), orderChildDeliveryReq.getShippingNo(),userId);
        } else {
            orderService.deliveryPartOrder(orderChildEntity.getParentOrderId());
        }
        OrderLogUtils.setDeliveryOrderInfo(orderChildEntity.getParentOrderId(), orderChildEntity.getId(), userId, ShippingStatusEnum.SHIPPED, CommentStatusEnum.NON_COMMENTED);
        return updateOrderStatusResult;
    }

}