/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许，不可做商业用途！
 *
 * 版权所有，侵权必究！
 */

package com.yami.shop.api.controller;


import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.bean.app.dto.ProdCommDataDto;
import com.yami.shop.bean.app.dto.ProdCommDto;
import com.yami.shop.bean.app.param.ProdCommParam;
import com.yami.shop.bean.model.ProdComm;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.security.api.util.SecurityUtils;
import com.yami.shop.service.ProdCommService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.Operation;
import lombok.AllArgsConstructor;
import com.yami.shop.common.response.ServerResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.Date;

/**
 * 商品评论相关接口的控制器类
 * 该类提供了多个与商品评论相关的接口，包括获取商品评论数据（如好评率、各评价数量等）、根据不同条件获取评论分页数据（按用户、按商品等）、添加评论以及删除评论等功能，
 * 通过调用服务层的对应方法来实现业务逻辑，并借助`Swagger`注解对接口进行文档化描述，方便接口的查看与使用。
 *
 * @author lanhai
 */
@RestController
@RequestMapping("/prodComm")
@Tag(name = "评论接口")
// 使用 @AllArgsConstructor 注解，由 lombok 自动生成包含所有成员变量的构造函数，用于依赖注入
@AllArgsConstructor
public class ProdCommController {

    // 通过构造函数注入ProdCommService，用于调用业务层方法来处理商品评论相关的业务逻辑
    private final ProdCommService prodCommService;

    /**
     * 获取商品评论数据的接口方法
     * 根据传入的商品ID，调用服务层方法获取该商品对应的评论数据（如好评率、好评数量、中评数、差评数等），并将结果以合适的格式返回给前端。
     *
     * @param prodId 要获取评论数据的商品的唯一标识（ID），该参数从请求中获取。
     * @return 返回一个ServerResponseEntity<ProdCommDataDto>类型的响应，成功时包含对应商品的评论数据对应的DTO对象，若获取数据出现异常则返回相应的错误信息。
     */
    @GetMapping("/prodCommData")
    @Operation(summary = "返回商品评论数据(好评率 好评数量 中评数 差评数)", description = "根据商品id获取")
    public ServerResponseEntity<ProdCommDataDto> getProdCommData(Long prodId) {
        return ServerResponseEntity.success(prodCommService.getProdCommDataByProdId(prodId));
    }

    /**
     * 根据用户获取评论分页数据的接口方法
     * 根据当前登录用户的信息以及传入的分页参数，调用服务层方法获取该用户相关的评论分页数据，并将结果以合适的格式返回给前端。
     *
     * @param page 分页参数对象，包含了分页相关的信息，如页码、每页数量等，用于服务层进行分页查询操作。
     * @return 返回一个ServerResponseEntity<IPage<ProdCommDto>>类型的响应，成功时包含符合分页条件的该用户的评论分页数据对应的DTO分页数据，若获取数据出现异常则返回相应的错误信息。
     */
    @GetMapping("/prodCommPageByUser")
    @Operation(summary = "根据用户返回评论分页数据", description = "传入页码")
    public ServerResponseEntity<IPage<ProdCommDto>> getProdCommPage(PageParam page) {
        return ServerResponseEntity.success(prodCommService.getProdCommDtoPageByUserId(page, SecurityUtils.getUser().getUserId()));
    }

    /**
     * 根据商品获取评论分页数据的接口方法
     * 根据传入的商品ID、评价筛选条件以及分页参数，调用服务层方法获取该商品对应的评论分页数据，并将结果以合适的格式返回给前端。
     * 其中评价筛选条件可用于筛选不同类型的评价（如好评、中评、差评、有图评价等）。
     *
     * @param page 分页参数对象，包含了分页相关的信息，如页码、每页数量等，用于服务层进行分页查询操作。
     * @param prodId 要获取评论分页数据的商品的唯一标识（ID），该参数从请求中获取，是必选参数。
     * @param evaluate 评价筛选条件，取值为 -1 或 null 表示获取全部评价，0 表示好评，1 表示中评，2 表示差评，3 表示有图评价，该参数从请求中获取，是必选参数。
     * @return 返回一个ServerResponseEntity<IPage<ProdCommDto>>类型的响应，成功时包含符合分页条件及评价筛选条件的该商品的评论分页数据对应的DTO分页数据，若获取数据出现异常则返回相应的错误信息。
     */
    @GetMapping("/prodCommPageByProdId")
    @Operation(summary = "根据商品返回评论分页数据", description = "传入商品id和页码")
    @Parameters({
            @Parameter(name = "prodId", description = "商品id", required = true),
            @Parameter(name = "evaluate", description = "-1或null 全部，0好评 1中评 2差评 3有图", required = true),
    })
    public ServerResponseEntity<IPage<ProdCommDto>> getProdCommPageByProdId(PageParam page, Long prodId, Integer evaluate) {
        return ServerResponseEntity.success(prodCommService.getProdCommDtoPageByProdId(page, prodId, evaluate));
    }

    /**
     * 添加评论的接口方法
     * 根据传入的评论参数对象，构建评论实体对象，设置相关属性（如商品ID、用户ID、评论内容、评分等）后，调用服务层方法将评论保存到数据库中，
     * 并返回表示操作成功的响应给前端。
     *
     * @param prodCommParam 包含评论相关信息的参数对象，用于构建要保存的评论实体对象，其属性涵盖了商品ID、订单商品项ID、用户ID、评分、内容、图片、是否匿名、评价类型等信息。
     * @return 返回一个ServerResponseEntity<Void>类型的响应，成功时表示评论添加操作成功，无具体返回数据，若保存过程出现异常则返回相应的错误信息。
     */
    @PostMapping
    @Operation(summary = "添加评论")
    public ServerResponseEntity<Void> saveProdCommPage(ProdCommParam prodCommParam) {
        ProdComm prodComm = new ProdComm();
        prodComm.setProdId(prodCommParam.getProdId());
        prodComm.setOrderItemId(prodCommParam.getOrderItemId());
        prodComm.setUserId(SecurityUtils.getUser().getUserId());
        prodComm.setScore(prodCommParam.getScore());
        prodComm.setContent(prodCommParam.getContent());
        prodComm.setPics(prodCommParam.getPics());
        prodComm.setIsAnonymous(prodCommParam.getIsAnonymous());
        prodComm.setRecTime(new Date());
        prodComm.setStatus(0);
        prodComm.setEvaluate(prodCommParam.getEvaluate());
        prodCommService.save(prodComm);
        return ServerResponseEntity.success();
    }

    /**
     * 删除评论的接口方法
     * 根据传入的评论ID，调用服务层方法从数据库中删除对应的评论记录，并返回表示操作成功的响应给前端。
     *
     * @param prodCommId 要删除的评论的唯一标识（ID），该参数从请求中获取。
     * @return 返回一个ServerResponseEntity<Void>类型的响应，成功时表示评论删除操作成功，无具体返回数据，若删除过程出现异常则返回相应的错误信息。
     */
    @DeleteMapping
    @Operation(summary = "删除评论", description = "根据id删除")
    public ServerResponseEntity<Void> deleteProdComm(Long prodCommId) {
        prodCommService.removeById(prodCommId);
        return ServerResponseEntity.success();
    }
}