package com.seer.teach.mall.app.good.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
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.seer.teach.common.PageListBean;
import com.seer.teach.common.constants.CommonConstant;
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.exception.CommonException;
import com.seer.teach.common.utils.AssertUtils;
import com.seer.teach.common.utils.CommonUtils;
import com.seer.teach.common.utils.PageConverterUtils;
import com.seer.teach.mall.app.good.service.IAppGoodsCommentService;
import com.seer.teach.mall.app.good.service.IAppGoodsSpecificationService;
import com.seer.teach.mall.convert.GoodsCommentConvert;
import com.seer.teach.mall.entity.GoodsCommentEntity;
import com.seer.teach.mall.entity.GoodsEntity;
import com.seer.teach.mall.entity.GoodsSpecificationEntity;
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.mapper.GoodsCommentMapper;
import com.seer.teach.mall.request.GoodsCommentCreateReq;
import com.seer.teach.mall.request.GoodsCommentListCreateReq;
import com.seer.teach.mall.request.GoodsCommentPageReqVO;
import com.seer.teach.mall.response.GoodsCommentResp;
import com.seer.teach.mall.service.IGoodsService;
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.user.api.UserInfoServiceApi;
import com.seer.teach.user.api.dto.UserInfoDTO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

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

/**
 * <p>
 * 商品评论 服务实现类
 * </p>
 *
 * @author Wang
 * @since 2025-07-03 10:22:05
 */
@RequiredArgsConstructor
@Slf4j
@Service
public class AppGoodsCommentServiceImpl extends ServiceImpl<GoodsCommentMapper, GoodsCommentEntity> implements IAppGoodsCommentService {

    private final IOrderService orderService;

    private final IOrderChildService orderChildService;

    private final IOrderGoodsService orderGoodsService;

    private final IAppGoodsSpecificationService goodsSpecificationService;

    private final IGoodsService goodsService;

    private final UserInfoServiceApi userInfoServiceApi;

    @Override
    public boolean createList(GoodsCommentListCreateReq commentCreateReq) {
        Integer userId = StpUtil.getLoginIdAsInt();

        if (CollectionUtils.isEmpty(commentCreateReq.getCommentItems())) {
            return false;
        }
        UserInfoDTO defaultChild = userInfoServiceApi.getByUserId(userId);
        List<GoodsCommentCreateReq> commentItems = commentCreateReq.getCommentItems();

        OrderChildEntity childOrder = orderChildService.checkOrderChild(commentCreateReq.getChildOrderId());

        for (GoodsCommentCreateReq commentItem : commentItems) {

            OrderGoodsEntity orderItem = orderGoodsService.getOneByChildOrderIdAndSkuId(commentCreateReq.getChildOrderId(), commentItem.getSkuId());

            AssertUtils.notNull(orderItem, ResultCodeEnum.ORDER_NOT_FOUND);

            GoodsEntity goodsEntity = goodsService.getById(orderItem.getGoodsId());
            AssertUtils.notNull(goodsEntity, ResultCodeEnum.GOOD_NOT_FOUND);

            Integer orderId = orderItem.getOrderId();
            log.info("用户[{}]查询订单[{}]成功", userId, orderId);
            AssertUtils.isTrue(childOrder.getOrderStatus() == OrderStatusEnum.COMPLETED.getCode(), ResultCodeEnum.ORDER_COMMENT_FAIL_STATUS_NOT_COMPLETED);

            // 判断当前订单的当前商品用户是否评价过
            GoodsCommentEntity comment = getOne(new LambdaQueryWrapper<>(GoodsCommentEntity.class).eq(GoodsCommentEntity::getOrderItemId, commentItem.getOrderItemId()).eq(GoodsCommentEntity::getUserId, userId));
            AssertUtils.isNull(comment, ResultCodeEnum.COMMENT_EXIST);

            // 更新订单子项表的评价状态
            boolean updatedOrderItemResult = orderGoodsService.update(new LambdaUpdateWrapper<>(OrderGoodsEntity.class).eq(OrderGoodsEntity::getId, orderItem.getId())
                    .set(OrderGoodsEntity::getCommentStatus, CommentStatusEnum.COMMENTED.getCode()));
            log.info("用户[{}]更新订单子项评价状态结果：{}", userId, updatedOrderItemResult ? "成功" : "失败");

            List<OrderGoodsEntity> orderItemList = orderGoodsService.list(new LambdaQueryWrapper<>(OrderGoodsEntity.class).eq(OrderGoodsEntity::getChildOrderId, orderItem.getChildOrderId()));
            Optional<OrderGoodsEntity> any = orderItemList.stream().filter(orderGoods -> Objects.equals(orderGoods.getCommentStatus(), CommentStatusEnum.NON_COMMENTED.getCode())).findAny();
            if (!any.isPresent()) {
                // 所有的子订单都评价完成后，更新订单表的评价状态字段
                boolean updatedOrderResult = orderChildService.update(new LambdaUpdateWrapper<>(OrderChildEntity.class)
                        .eq(OrderChildEntity::getId, childOrder.getId())
                        .eq(OrderChildEntity::getUserId, userId)
                        .set(OrderChildEntity::getCommentStatus, CommentStatusEnum.COMMENTED.getCode()));
                log.info("用户[{}]更新订单表评价状态结果：{}", userId, updatedOrderResult ? "成功" : "失败");
            }
            GoodsSpecificationEntity goodsSpecificationEntity = goodsSpecificationService.getById(commentItem.getSkuId());
            GoodsCommentEntity goodsCommentEntity = GoodsCommentConvert.INSTANCE.convertOne(commentItem);
            goodsCommentEntity.setScores(CommonUtils.calcScores(commentItem.getDescriptionScores(), commentItem.getBenefitScores()));
            goodsCommentEntity.setSkuPicUrl(goodsSpecificationEntity.getPicUrl());
            goodsCommentEntity.setOrderId(orderId);
            goodsCommentEntity.setSkuId(orderItem.getSkuId());
            goodsCommentEntity.setMerchantId(childOrder.getMerchantUserId());
            goodsCommentEntity.setOrderItemId(orderItem.getId());
            goodsCommentEntity.setChildOrderId(childOrder.getId());
            goodsCommentEntity.setSpuId(goodsEntity.getId());
            goodsCommentEntity.setSpuName(goodsEntity.getName());
            goodsCommentEntity.setUserId(userId);
            goodsCommentEntity.setCommentTime(LocalDateTime.now());
            if(Objects.nonNull(defaultChild)){
                goodsCommentEntity.setUserAvatar(defaultChild.getAvatar());
                goodsCommentEntity.setUserNickname(defaultChild.getNickName());
            }
            boolean saved = save(goodsCommentEntity);
            log.info("保存商品评论结果：{}", saved);
        }
        return true;
    }

    @Override
    public PageListBean<GoodsCommentResp> getOrderPage(Integer userId, Boolean isVisible, GoodsCommentPageReqVO params) {
        if (Objects.isNull(params.getSpuId()) && Objects.isNull(userId)) {
            throw new CommonException(ResultCodeEnum.COMMENT_LIST_QUERY_PARAM_ERROR);
        }
        IPage<GoodsCommentEntity> pageParams = new Page<>(params.getPageNo(), params.getPageSize());
        IPage<GoodsCommentEntity> iPage = super.page(pageParams, new LambdaQueryWrapper<GoodsCommentEntity>()
                .eq(StringUtils.hasText(params.getSpuId()), GoodsCommentEntity::getSpuId, params.getSpuId())
                .eq(!isVisible, GoodsCommentEntity::getIsVisible, CommonConstant.YES)
                .eq(Objects.nonNull(userId), GoodsCommentEntity::getUserId, userId)
                .eq(Objects.nonNull(params.getOrderId()), GoodsCommentEntity::getOrderId, params.getOrderId())
                .eq(Objects.nonNull(params.getChildOrderId()), GoodsCommentEntity::getChildOrderId, params.getChildOrderId())
                .orderByDesc(GoodsCommentEntity::getId));
        if(CollectionUtils.isEmpty(iPage.getRecords())){
            return new PageListBean<>();
        }
        PageListBean<GoodsCommentResp> goodsCommentRespPageList = PageConverterUtils.convertPageListBean(iPage, GoodsCommentConvert.INSTANCE::convertList);
        List<Integer> skuIdList = iPage.getRecords().stream().map(GoodsCommentEntity::getSkuId).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(skuIdList)){
            log.info("查询商品sku结果为空");
            return goodsCommentRespPageList;
        }
        List<GoodsSpecificationEntity> skuList = goodsSpecificationService.listByIds(skuIdList);
        if(CollectionUtils.isEmpty(skuList)){
            return goodsCommentRespPageList;
        }
        Map<Integer, GoodsSpecificationEntity> skuMap = skuList.stream().collect(Collectors.toMap(GoodsSpecificationEntity::getId, Function.identity(), (old, newOne) -> newOne));
        goodsCommentRespPageList.getList().forEach(goodsCommentResp -> {
            GoodsSpecificationEntity goodsSpecification = skuMap.get(goodsCommentResp.getSkuId());
            goodsCommentResp.setSkuPicUrl(goodsSpecification.getPicUrl());
            if(Objects.nonNull(goodsSpecification)){
                goodsCommentResp.setAttributes(goodsSpecification.getAttributes());
            }else{
                log.info("查询商品[{}]sku[{}]结果为空", goodsCommentResp.getSpuId(), goodsCommentResp.getSkuId());
            }

        });
        log.info("查询商品评论结果：{}", goodsCommentRespPageList.getTotal());
        return goodsCommentRespPageList;
    }
}