package com.zsc.edu.gateway.modules.notice.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zsc.edu.gateway.framework.security.UserDetailsImpl;
import com.zsc.edu.gateway.modules.notice.dto.UserMessageDto;
import com.zsc.edu.gateway.modules.notice.entity.MessagePayload;
import com.zsc.edu.gateway.modules.notice.entity.MessageSetting;
import com.zsc.edu.gateway.modules.notice.query.UserMessageQuery;
import com.zsc.edu.gateway.modules.notice.service.UserMessageService;
import com.zsc.edu.gateway.modules.notice.vo.UserMessageVo;
import com.zsc.edu.gateway.modules.system.entity.User;
import lombok.AllArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Set;

/**
 * 用户消息Controller
 *
 * @author harry_yao
 */
@AllArgsConstructor
@RestController
@RequestMapping("api/rest/message")
public class UserMessageController {

    private final UserMessageService service;

    /**
     * 普通用户查看消息详情
     *
     * @param userDetails 操作用户
     * @param messageId   消息ID
     * @return 用户消息详情
     */
    @GetMapping("/self/{messageId}")
    public UserMessageVo selfDetail(@AuthenticationPrincipal UserDetailsImpl userDetails, @PathVariable("messageId") Long messageId) {
        return service.detail(messageId, userDetails.getId());
    }

    /**
     * 普通用户分页查询消息，不能设置查询参数userId和username
     *
     * @param userDetails 操作用户
     * @param query       查询参数
     * @return 分页数据
     */
    @GetMapping("/self")
    public IPage<UserMessageVo> selfPage(@AuthenticationPrincipal UserDetailsImpl userDetails, UserMessageQuery query) {
        query.userId = userDetails.id;
        query.name = null;
        Page<UserMessageVo> page = new Page<>(query.getPageNum(), query.getPageSize());
        return service.page(page, query);
    }

    /**
     * 普通用户统计自己未读消息数量
     *
     * @param userDetails 操作用户
     * @return 数据
     */
    @GetMapping("/countUnread")
    public int countUnread(@AuthenticationPrincipal UserDetailsImpl userDetails) {
        return service.countUnread(userDetails);
    }

    /**
     * 普通用户确认消息已读，如果提交的已读消息ID集合为空，则将所有未读消息设为已读
     *
     * @param userDetails 操作用户
     * @param messageIds  已读消息ID集合
     * @return 确认已读数量
     */
    @PatchMapping("/read")
    public int acknowledge(@AuthenticationPrincipal UserDetailsImpl userDetails, @RequestBody List<Long> messageIds) {
        return service.markAsRead(userDetails, messageIds);
    }

    /**
     * 管理查询消息详情
     *
     * @param userId    用户ID
     * @param messageId 消息ID
     * @return 用户消息详情
     */
    @GetMapping("/{userId}/{messageId}")
    @PreAuthorize("hasAuthority('MESSAGE_QUERY')")
    public UserMessageVo detail(@PathVariable("userId") Long userId, @PathVariable("messageId") Long messageId) {
        return service.detail(messageId, userId);
    }

    /**
     * 管理员分页查询消息
     *
     * @param query 查询参数
     * @return 分页数据
     */
    @GetMapping
    @PreAuthorize("hasAuthority('MESSAGE_QUERY')")
    public IPage<UserMessageVo> page(UserMessageQuery query) {
        Page<UserMessageVo> page = new Page<>(query.getPageNum(), query.getPageSize());
        return service.page(page, query);
    }

    /**
     * 管理员手动创建消息
     *
     * @param dto 表单数据
     * @return 消息列表
     */
    @PostMapping
    @PreAuthorize("hasAuthority('MESSAGE_CREATE')")
    public Boolean create(@RequestBody UserMessageDto dto) {
        return service.createByAdmin(dto);
    }

    /**
     * 管理员为消息添加附件
     *
     * @param messageId     消息ID
     * @param attachmentIds 附件ID集合
     * @return 消息列表
     */
    @PostMapping("/attachment/{messageId}")
    @PreAuthorize("hasAuthority('MESSAGE_CREATE')")
    public Boolean insertInto(@PathVariable("messageId") Long messageId, @RequestBody List<String> attachmentIds) {
        return service.insertInto(messageId, attachmentIds);
    }

    /**
     * 获取消息推送方式
     *
     * @return 消息推送方式列表
     */
    @GetMapping("/setting")
    @PreAuthorize("hasAuthority('MESSAGE_SETTING')")
    public List<MessageSetting> getSetting() {
        return service.getSetting();
    }

    /**
     * 设置消息推送方式
     *
     * @param settings 表单数据
     * @return 消息设置
     */
    @PatchMapping("/setting")
    @PreAuthorize("hasAuthority('MESSAGE_SETTING')")
    public List<MessageSetting> saveSetting(@RequestBody List<MessageSetting> settings) {
        return service.saveSetting(settings);
    }

}
