package com.seer.teach.mall.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.ResultCodeEnum;
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.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.good.service.IAdminGoodsCommentService;
import com.seer.teach.mall.mapper.GoodsCommentMapper;
import com.seer.teach.mall.request.CommentUpdateVisibleReq;
import com.seer.teach.mall.request.GoodsCommentCreateReq;
import com.seer.teach.mall.request.GoodsCommentPageReqVO;
import com.seer.teach.mall.request.GoodsCommentUpdateReq;
import com.seer.teach.mall.response.GoodsCommentResp;
import com.seer.teach.mall.service.IGoodsService;
import com.seer.teach.mall.service.IGoodsSpecificationService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.Objects;

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

    private final IGoodsService goodsService;

    private final IGoodsSpecificationService goodsSpecificationService;

    @Override
    public boolean create(GoodsCommentCreateReq reqVO) {
        GoodsCommentEntity goodsCommentEntity = GoodsCommentConvert.INSTANCE.convertOne(reqVO);

        GoodsSpecificationEntity specificationEntity = goodsSpecificationService.getById(reqVO.getSkuId());
        AssertUtils.notNull(specificationEntity, ResultCodeEnum.GOOD_SPECIFICATIONS_NOT_EXIST);

        goodsCommentEntity.setSkuId(specificationEntity.getId());
        goodsCommentEntity.setSkuPicUrl(specificationEntity.getPicUrl());

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

        goodsCommentEntity.setSpuName(goodsEntity.getName());

        goodsCommentEntity.setReplyUserId(StpUtil.getLoginIdAsInt());
        goodsCommentEntity.setUserId(0);
        goodsCommentEntity.setIsReal(CommonConstant.YES);
        goodsCommentEntity.setIsAnonymous(CommonConstant.NO);
        goodsCommentEntity.setCommentTime(LocalDateTime.now());
        goodsCommentEntity.setIsVisible(CommonConstant.YES);
        goodsCommentEntity.setScores(CommonUtils.calcScores(reqVO.getDescriptionScores(), reqVO.getBenefitScores()));
        boolean saved = save(goodsCommentEntity);
        log.info("保存商品评论结果：{}", saved);
        return saved;
    }

    @Override
    public PageListBean<GoodsCommentResp> getOrderPage(GoodsCommentPageReqVO params) {
        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(Objects.nonNull(params.getMerchantId()), GoodsCommentEntity::getMerchantId, params.getMerchantId())
                .likeRight(StringUtils.hasText(params.getContent()),GoodsCommentEntity::getContent, params.getContent())
                .likeRight(StringUtils.hasText(params.getSpuName()),GoodsCommentEntity::getSpuName, params.getSpuName())
                .orderByDesc(GoodsCommentEntity::getId));

        PageListBean<GoodsCommentResp> goodsCommentRespPageList = PageConverterUtils.convertPageListBean(iPage, GoodsCommentConvert.INSTANCE::convertList);
        log.info("查询商品评论结果：{}", goodsCommentRespPageList.getTotal());
        return goodsCommentRespPageList;
    }

    @Override
    public boolean replyComment(GoodsCommentUpdateReq updateReq) {
        int userId = StpUtil.getLoginIdAsInt();
        log.info("用户{}回复商品评论", userId);
        GoodsCommentEntity commentEntity = getById(updateReq.getCommentId());
        AssertUtils.notNull(commentEntity, ResultCodeEnum.COMMENT_NOT_FOUND);

        boolean updated = update(new LambdaUpdateWrapper<>(GoodsCommentEntity.class)
                .set(GoodsCommentEntity::getReplyContent, updateReq.getReplyContent())
                .set(GoodsCommentEntity::getOrderId, commentEntity.getOrderId())
                .set(GoodsCommentEntity::getReplyUserId, userId)
                .set(GoodsCommentEntity::getReplyTime, LocalDateTime.now())
                .eq(GoodsCommentEntity::getOrderId, commentEntity.getOrderId()));
        log.info("用户[{}]回复商品评论[{}]结果：{}", userId, updateReq.getCommentId(), updated);
        return updated;
    }

    @Override
    public boolean updateCommentVisible(CommentUpdateVisibleReq commentUpdateVisibleReq) {
        int userId = StpUtil.getLoginIdAsInt();
        log.info("用户{}修改商品评论可见性", userId);
        GoodsCommentEntity commentEntity = getById(commentUpdateVisibleReq.getId());
        AssertUtils.notNull(commentEntity, ResultCodeEnum.COMMENT_NOT_FOUND);
        boolean updatedResult = update(new LambdaUpdateWrapper<>(GoodsCommentEntity.class).set(GoodsCommentEntity::getIsVisible, commentUpdateVisibleReq.getIsVisible())
                .eq(GoodsCommentEntity::getId, commentUpdateVisibleReq.getId()));
        log.info("用户[{}]修改商品评论[{}]可见性结果：{}", userId, commentUpdateVisibleReq.getId(), updatedResult);
        return updatedResult;
    }
}