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

package com.yami.shop.admin.controller;

import java.util.Arrays;
import java.util.List;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import com.yami.shop.common.response.ServerResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.yami.shop.common.util.PageParam;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.bean.enums.MessageStatus;
import com.yami.shop.bean.model.Message;
import com.yami.shop.service.MessageService;

import cn.hutool.core.util.StrUtil;

/**
 * MessageController类，作为Spring RESTful风格的控制器，用于处理后台管理系统中与消息（Message）相关的各种操作接口。
 * 包含消息的分页查询、获取单个消息详情、保存消息、修改消息、公开留言、取消公开留言以及批量删除消息等功能。
 * @author lgh on 2018/10/15.
 */
@RestController
@RequestMapping("/admin/message")
public class MessageController {

    // 通过Spring的依赖注入机制，自动注入MessageService的实例，以便调用其提供的业务方法来处理消息相关逻辑。
    @Autowired
    private MessageService messageService;

    /**
     * 分页获取消息的接口方法。
     * 根据传入的Message对象（可能包含用户名等查询条件）以及PageParam对象（用于分页参数设置），
     * 使用MessageService的page方法结合LambdaQueryWrapper进行分页查询。
     * 如果消息的用户名不为空，则按照用户名进行模糊查询；如果消息状态不为空，则精确匹配消息状态进行查询。
     * 最后将查询到的分页消息结果封装在ServerResponseEntity中返回，用于统一的接口响应格式处理。
     * @param message 可能包含查询条件的消息对象，比如按用户名模糊查询、按消息状态精确查询等。
     * @param page 分页参数对象，包含页码、每页数量等信息。
     * @return 返回包含分页消息信息的ServerResponseEntity，成功时其数据部分为IPage<Message>类型。
     */
    @GetMapping("/page")
    @PreAuthorize("@pms.hasPermission('admin:message:page')")
    public ServerResponseEntity<IPage<Message>> page(Message message, PageParam<Message> page) {
        IPage<Message> messages = messageService.page(page, new LambdaQueryWrapper<Message>()
              .like(StrUtil.isNotBlank(message.getUserName()), Message::getUserName, message.getUserName())
              .eq(message.getStatus()!= null, Message::getStatus, message.getStatus()));
        return ServerResponseEntity.success(messages);
    }

    /**
     * 获取指定ID消息详细信息的接口方法。
     * 通过路径变量获取消息的ID，调用MessageService的getById方法获取对应的消息对象，
     * 然后将获取到的消息对象封装在ServerResponseEntity中返回，用于统一的接口响应格式处理。
     * @param id 要获取信息的消息的ID。
     * @return 返回包含指定消息详细信息的ServerResponseEntity，成功时其数据部分为Message类型。
     */
    @GetMapping("/info/{id}")
    @PreAuthorize("@pms.hasPermission('admin:message:info')")
    public ServerResponseEntity<Message> info(@PathVariable("id") Long id) {
        Message message = messageService.getById(id);
        return ServerResponseEntity.success(message);
    }

    /**
     * 保存消息的接口方法。
     * 接收通过请求体传入的Message对象（包含要保存的消息相关信息），调用MessageService的save方法将消息保存到数据库中，
     * 最后返回表示保存成功的ServerResponseEntity对象，用于统一的接口响应格式处理，其无具体数据内容（Void类型）。
     * @param message 要保存的消息对象，通过请求体传入，包含消息的各项属性信息。
     * @return 返回表示保存成功的ServerResponseEntity，无数据内容（Void类型）。
     */
    @PostMapping
    @PreAuthorize("@pms.hasPermission('admin:message:save')")
    public ServerResponseEntity<Void> save(@RequestBody Message message) {
        messageService.save(message);
        return ServerResponseEntity.success();
    }

    /**
     * 修改消息的接口方法。
     * 接收通过请求体传入的Message对象（包含要修改的消息相关信息），调用MessageService的updateById方法根据消息的ID更新数据库中的对应消息记录，
     * 最后返回表示修改成功的ServerResponseEntity对象，用于统一的接口响应格式处理，其无具体数据内容（Void类型）。
     * @param message 要修改的消息对象，通过请求体传入，包含消息的各项属性信息。
     * @return 返回表示修改成功的ServerResponseEntity，无数据内容（Void类型）。
     */
    @PutMapping
    @PreAuthorize("@pms.hasPermission('admin:message:update')")
    public ServerResponseEntity<Void> update(@RequestBody Message message) {
        messageService.updateById(message);
        return ServerResponseEntity.success();
    }

    /**
     * 公开留言的接口方法。
     * 根据路径变量获取要操作的消息的ID，创建一个新的Message对象，设置其ID为传入的消息ID，并将消息状态设置为公开状态（通过MessageStatus.RELEASE.value()获取对应值），
     * 然后调用MessageService的updateById方法更新数据库中对应消息的状态为公开，最后返回表示操作成功的ServerResponseEntity对象，用于统一的接口响应格式处理，其无具体数据内容（Void类型）。
     * @param id 要设置为公开状态的消息的ID。
     * @return 返回表示操作成功的ServerResponseEntity，无数据内容（Void类型）。
     */
    @PutMapping("/release/{id}")
    @PreAuthorize("@pms.hasPermission('admin:message:release')")
    public ServerResponseEntity<Void> release(@PathVariable("id") Long id) {
        Message message = new Message();
        message.setId(id);
        message.setStatus(MessageStatus.RELEASE.value());
        messageService.updateById(message);
        return ServerResponseEntity.success();
    }

    /**
     * 取消公开留言的接口方法。
     * 根据路径变量获取要操作的消息的ID，创建一个新的Message对象，设置其ID为传入的消息ID，并将消息状态设置为取消公开状态（通过MessageStatus.CANCEL.value()获取对应值），
     * 然后调用MessageService的updateById方法更新数据库中对应消息的状态为取消公开，最后返回表示操作成功的ServerResponseEntity对象，用于统一的接口响应格式处理，其无具体数据内容（Void类型）。
     * @param id 要设置为取消公开状态的消息的ID。
     * @return 返回表示操作成功的ServerResponseEntity，无数据内容（Void类型）。
     */
    @PutMapping("/cancel/{id}")
    @PreAuthorize("@pms.hasPermission('admin:message:cancel')")
    public ServerResponseEntity<Void> cancel(@PathVariable("id") Long id) {
        Message message = new Message();
        message.setId(id);
        message.setStatus(MessageStatus.CANCEL.value());
        messageService.updateById(message);
        return ServerResponseEntity.success();
    }

    /**
     * 删除消息的接口方法（支持批量删除）。
     * 通过路径变量获取要删除的消息的ID数组，将其转换为List集合后，调用MessageService的removeByIds方法，
     * 根据传入的消息ID集合批量删除数据库中的对应消息记录，最后返回表示删除成功的ServerResponseEntity对象，用于统一的接口响应格式处理，其无具体数据内容（Void类型）。
     * @param ids 要删除的消息的ID数组，通过路径变量传入。
     * @return 返回表示删除成功的ServerResponseEntity，无数据内容（Void类型）。
     */
    @DeleteMapping("/{ids}")
    @PreAuthorize("@pms.hasPermission('admin:message:delete')")
    public ServerResponseEntity<Void> delete(@PathVariable Long[] ids) {
        messageService.removeByIds(Arrays.asList(ids));
        return ServerResponseEntity.success();
    }
}