package org.springblade.modules.api.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springblade.common.base.BaseEntity;
import org.springblade.common.constant.CommonConstant;
import org.springblade.common.enums.YesOrNoEnum;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.modules.api.request.AddCommentRequest;
import org.springblade.modules.api.response.CommentStatisResponse;
import org.springblade.modules.finance.entity.Order;
import org.springblade.modules.finance.entity.OrderGoods;
import org.springblade.modules.finance.service.IOrderGoodsService;
import org.springblade.modules.finance.service.IOrderService;
import org.springblade.modules.mall.entity.Comment;
import org.springblade.modules.mall.entity.CommentLike;
import org.springblade.modules.mall.entity.CommentMedia;
import org.springblade.modules.mall.service.ICommentLikeService;
import org.springblade.modules.mall.service.ICommentMediaService;
import org.springblade.modules.mall.service.ICommentService;
import org.springblade.modules.mall.vo.CommentVO;
import org.springblade.modules.mall.wrapper.CommentWrapper;
import org.springblade.modules.system.entity.User;
import org.springblade.modules.system.service.IUserService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * Author pangqijun
 * Date 2023/6/13
 * Description
 */
@RestController
@RequestMapping(CommonConstant.API_URL + "/comment")
@Api(value = "评论相关接口", tags = "14.评论相关接口")
public class ApiCommentController {

    @Resource
    private ICommentService commentService;
    @Resource
    private ICommentMediaService commentMediaService;
    @Resource
    private IUserService userService;
    @Resource
    private IOrderGoodsService orderGoodsService;
    @Resource
    private IOrderService orderService;
    @Resource
    private ICommentLikeService commentLikeService;

    @Transactional(rollbackFor = Exception.class)
    @PostMapping("/submit")
    @ApiOperationSupport(order = 1)
    @ApiOperation(value = "提交评论", notes = "传入commt")
    public R save(@Valid @RequestBody AddCommentRequest request) {
        User user = userService.getById(AuthUtil.getUserId());
        Comment comment = new Comment();
        comment.setContent(request.getContent());
        comment.setUserName(user.getName());
        comment.setAvatar(user.getAvatar());
        comment.setOrderId(request.getOrderId());
        comment.setScore(request.getScore());

        Order order = orderService.getById(request.getOrderId());
        Assert.notNull(order, "订单数据不存在");

        OrderGoods orderGoods = orderGoodsService.getByOrderNo(order.getOrderNo());
        Assert.notNull(orderGoods, "订单商品数据不存在");
        comment.setGoodsId(orderGoods.getGoodsId());
        comment.setStyle(orderGoods.getGoodsSpecNames());
        if (CollUtil.isNotEmpty(request.getMediaUrl())) {
            comment.setIsHavePicture(YesOrNoEnum.YES.getValue());
        }
        commentService.save(comment);

        List<CommentMedia> list = new ArrayList<>();
        if (CollUtil.isNotEmpty(request.getMediaUrl())) {
            for (String s : request.getMediaUrl()) {
                CommentMedia commentMedia = new CommentMedia();
                commentMedia.setCommentId(comment.getId());
                commentMedia.setMediaUrl(s);
                list.add(commentMedia);
            }
            commentMediaService.saveBatch(list);
        }
        return R.status(true);
    }

    @GetMapping("/statis")
    @ApiOperationSupport(order = 2)
    @ApiOperation(value = "获取商品评论统计")
    public R<List<CommentStatisResponse>> statis(@ApiParam("商品ID") @RequestParam("goodsId") Long goodId) {
        List<CommentStatisResponse> result = new ArrayList<>();
        List<Comment> list = commentService.lambdaQuery().eq(Comment::getGoodsId, goodId)
                .select(Comment::getIsHavePicture, Comment::getIsAdditionalReview, Comment::getScore).list();
        CommentStatisResponse r1 = new CommentStatisResponse("全部", list.size(), 0);
        result.add(r1);
        if (CollUtil.isNotEmpty(list)) {
            long count = list.stream().filter(e -> YesOrNoEnum.YES.getValue().equals(e.getIsHavePicture())).count();
            CommentStatisResponse r2 = new CommentStatisResponse("有图评价", (int) count, 2);
            long count1 = list.stream().filter(e -> YesOrNoEnum.YES.getValue().equals(e.getIsAdditionalReview())).count();
            CommentStatisResponse r3 = new CommentStatisResponse("追评", (int) count1, 1);
            result.add(r3);
            result.add(r2);
        } else {
            CommentStatisResponse r2 = new CommentStatisResponse("有图评价", 0, 2);
            CommentStatisResponse r3 = new CommentStatisResponse("追评", 0, 1);
            result.add(r3);
            result.add(r2);
        }
        return R.data(result);
    }

    @GetMapping("/list")
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "获取商品评论列表")
    public R<List<CommentVO>> list(@ApiParam("商品ID") @RequestParam("goodsId") Long goodId,
                                   @ApiParam("查询类型0-全部 1-追评 2-有图评价") @RequestParam("queryType") Integer queryType, Query query) {
        LambdaQueryWrapper<Comment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Comment::getGoodsId, goodId);
        if (queryType == 1) {
            wrapper.eq(Comment::getIsAdditionalReview, YesOrNoEnum.YES.getValue());
        } else if (queryType == 2) {
            wrapper.eq(Comment::getIsHavePicture, YesOrNoEnum.YES.getValue());
        }
        IPage<Comment> pages = commentService.page(Condition.getPage(query), wrapper);
        List<CommentVO> commentVOS = CommentWrapper.build().listVO(pages.getRecords());

        Long userId = AuthUtil.getUserId();
        if (CollUtil.isNotEmpty(pages.getRecords())) {
            List<Long> collect = pages.getRecords().stream().map(Comment::getId).collect(Collectors.toList());
            List<CommentLike> likeList = commentLikeService.lambdaQuery().in(CommentLike::getCommentId, collect).list();
            Map<Long, List<CommentLike>> listMap = likeList.stream().collect(Collectors.groupingBy(CommentLike::getCommentId));
            List<CommentMedia> list = commentMediaService.lambdaQuery().in(CommentMedia::getCommentId, collect).list();
            if (CollUtil.isNotEmpty(list)) {
                Map<Long, List<CommentMedia>> map = list.stream().collect(Collectors.groupingBy(CommentMedia::getCommentId));
                for (CommentVO commentVO : commentVOS) {
                    List<CommentMedia> commentMedia = map.get(commentVO.getId());
                    if (CollUtil.isNotEmpty(commentMedia)) {
                        List<String> list1 = commentMedia.stream().map(CommentMedia::getMediaUrl).collect(Collectors.toList());
                        commentVO.setMediaUrl(list1);
                    }
                    List<CommentLike> commentLikes = listMap.get(commentVO.getId());
                    if (CollUtil.isNotEmpty(commentLikes)) {
                        Map<Long, CommentLike> map1 = commentLikes.stream().collect(Collectors.toMap(CommentLike::getUserId, Function.identity()));
                        commentVO.setLike(!Objects.isNull(map1.get(userId)));
                    } else {
                        commentVO.setLike(false);
                    }
                }
            }
        }
        return R.data(commentVOS);
    }

    @Transactional(rollbackFor = Exception.class)
    @PostMapping("/like")
    @ApiOperationSupport(order = 4)
    @ApiOperation(value = "评论点赞")
    public R like(@ApiParam("评论ID") @RequestParam Long commentId, @ApiParam("类型 1-点赞 2-取消点赞") @RequestParam Integer type) {
        Comment comment = commentService.getById(commentId);
        Assert.notNull(comment, "未查询到评论信息");
        Long userId = AuthUtil.getUserId();
        if (type == 1) {
            Integer count = commentLikeService.lambdaQuery().eq(CommentLike::getCommentId, commentId).eq(CommentLike::getUserId, userId).count();
            if (count > 0) {
                return R.fail("您已点赞过");
            }
            CommentLike commentLike = new CommentLike();
            commentLike.setCommentId(commentId);
            commentLike.setUserId(userId);
            commentLikeService.save(commentLike);
            comment.setLikeTotal(comment.getLikeTotal() + 1);
        } else {
            commentLikeService.lambdaUpdate().set(BaseEntity::getIsDelete, YesOrNoEnum.YES.getValue()).eq(CommentLike::getCommentId, commentId)
                    .eq(CommentLike::getUserId, userId).update();
            comment.setLikeTotal(comment.getLikeTotal() - 1);
        }
        commentService.updateById(comment);
        return R.success("ok");
    }

    @Transactional(rollbackFor = Exception.class)
    @PostMapping("/reply")
    @ApiOperationSupport(order = 5)
    @ApiOperation(value = "评论回复")
    public R reply(@ApiParam("评论ID") @RequestParam Long commentId, @ApiParam("回复内容") @RequestParam String content) {
        if (StrUtil.isBlank(content)) {
            return R.fail("请输入评论内容");
        }
        Comment comment = commentService.getById(commentId);
        Assert.notNull(comment, "未查询到评论信息");

        Long userId = AuthUtil.getUserId();
        User user = userService.getById(userId);
        Assert.notNull(user, "未查询到用户信息");

        Comment child = new Comment();
        child.setParentId(commentId);
        child.setContent(content);
        child.setAvatar(user.getAvatar());
        child.setUserName(user.getName());
        commentService.save(child);

        comment.setRecoverTotal(comment.getRecoverTotal() + 1);
        commentService.updateById(comment);

        return R.success("ok");
    }

    @GetMapping("/child-list")
    @ApiOperationSupport(order = 6)
    @ApiOperation(value = "获取子评论列表")
    public R<List<Comment>> list(@ApiParam("评论ID") @RequestParam Long commentId) {
        List<Comment> list = commentService.lambdaQuery().eq(Comment::getParentId, commentId).list();
        return R.data(list);
    }

}
