package com.xy.xyaicpzs.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xy.xyaicpzs.common.ErrorCode;
import com.xy.xyaicpzs.common.ResultUtils;
import com.xy.xyaicpzs.common.requset.AnnouncementAddRequest;
import com.xy.xyaicpzs.common.requset.AnnouncementQueryRequest;
import com.xy.xyaicpzs.common.requset.AnnouncementUpdateRequest;
import com.xy.xyaicpzs.common.response.ApiResponse;
import com.xy.xyaicpzs.domain.entity.Announcement;
import com.xy.xyaicpzs.domain.entity.User;
import com.xy.xyaicpzs.domain.vo.AnnouncementVO;
import com.xy.xyaicpzs.exception.BusinessException;
import com.xy.xyaicpzs.service.AnnouncementService;
import com.xy.xyaicpzs.service.OperationHistoryService;
import com.xy.xyaicpzs.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 公告管理接口
 */
@Slf4j
@RestController
@RequestMapping("/announcement")
@Tag(name = "公告管理", description = "公告管理相关接口")
public class AnnouncementController {

    @Autowired
    private AnnouncementService announcementService;

    @Autowired
    private UserService userService;

    @Autowired
    private OperationHistoryService operationHistoryService;

    /**
     * 添加公告
     *
     * @param request 公告添加请求
     * @param httpServletRequest Http请求
     * @return 添加成功的公告ID
     */
    @PostMapping("/add")
    @Operation(summary = "添加公告", description = "管理员添加新公告")
    public ApiResponse<Long> addAnnouncement(@RequestBody AnnouncementAddRequest request,
                                             HttpServletRequest httpServletRequest) {
        // 权限校验
        User loginUser = userService.getLoginUser(httpServletRequest);
        if (!userService.isAdmin(loginUser)) {
            return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "无权限");
        }

        Long userId = loginUser.getId();
        String userName = loginUser.getUserName();

        // 参数校验
        if (request == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数不能为空");
        }
        if (StringUtils.isBlank(request.getTitle())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "公告标题不能为空");
        }
        if (StringUtils.isBlank(request.getContent())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "公告内容不能为空");
        }
        if (request.getTitle().length() > 200) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "公告标题不能超过200个字符");
        }

        try {
            Announcement announcement = new Announcement();
            BeanUtils.copyProperties(request, announcement);
            announcement.setPublisherId(userId);
            announcement.setPublisherName(userName);
            announcement.setViewCount(0);

            boolean result = announcementService.save(announcement);
            if (!result) {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "添加公告失败");
            }

            // 记录操作历史 - 成功
            String resultMessage = String.format("%s成功添加公告：%s", userName, request.getTitle());
            operationHistoryService.recordOperation(userId, "添加公告", 1, "成功", resultMessage);

            log.info("管理员{}添加公告成功，公告ID：{}", userName, announcement.getId());
            return ResultUtils.success(announcement.getId());

        } catch (Exception e) {
            log.error("添加公告失败：{}", e.getMessage(), e);

            // 记录操作历史 - 失败
            String resultMessage = String.format("%s添加公告失败：%s，公告标题：%s", 
                                                userName, e.getMessage(), request.getTitle());
            operationHistoryService.recordOperation(userId, "添加公告", 1, "失败", resultMessage);

            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "添加公告失败：" + e.getMessage());
        }
    }

    /**
     * 更新公告
     *
     * @param request 公告更新请求
     * @param httpServletRequest Http请求
     * @return 更新结果
     */
    @PostMapping("/update")
    @Operation(summary = "更新公告", description = "管理员更新公告信息")
    public ApiResponse<Boolean> updateAnnouncement(@RequestBody AnnouncementUpdateRequest request,
                                                   HttpServletRequest httpServletRequest) {
        // 权限校验
        User loginUser = userService.getLoginUser(httpServletRequest);
        if (!userService.isAdmin(loginUser)) {
            return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "无权限");
        }

        Long userId = loginUser.getId();
        String userName = loginUser.getUserName();

        // 参数校验
        if (request == null || request.getId() == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数不能为空");
        }
        if (request.getTitle() != null && request.getTitle().length() > 200) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "公告标题不能超过200个字符");
        }

        try {
            // 检查公告是否存在
            Announcement existingAnnouncement = announcementService.getById(request.getId());
            if (existingAnnouncement == null) {
                throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "公告不存在");
            }

            Announcement announcement = new Announcement();
            BeanUtils.copyProperties(request, announcement);
            boolean result = announcementService.updateById(announcement);

            if (!result) {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "更新公告失败");
            }

            // 记录操作历史 - 成功
            String resultMessage = String.format("%s成功更新公告：%s（ID：%d）", 
                                                userName, existingAnnouncement.getTitle(), request.getId());
            operationHistoryService.recordOperation(userId, "更新公告", 1, "成功", resultMessage);

            log.info("管理员{}更新公告成功，公告ID：{}", userName, request.getId());
            return ResultUtils.success(true);

        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("更新公告失败：{}", e.getMessage(), e);

            // 记录操作历史 - 失败
            String resultMessage = String.format("%s更新公告失败：%s，公告ID：%d", 
                                                userName, e.getMessage(), request.getId());
            operationHistoryService.recordOperation(userId, "更新公告", 1, "失败", resultMessage);

            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "更新公告失败：" + e.getMessage());
        }
    }

    /**
     * 删除公告（逻辑删除）
     *
     * @param id 公告ID
     * @param httpServletRequest Http请求
     * @return 删除结果
     */
    @DeleteMapping("/delete/{id}")
    @Operation(summary = "删除公告", description = "管理员删除公告（逻辑删除）")
    public ApiResponse<Boolean> deleteAnnouncement(@Parameter(description = "公告ID", required = true)
                                                   @PathVariable Long id,
                                                   HttpServletRequest httpServletRequest) {
        // 权限校验
        User loginUser = userService.getLoginUser(httpServletRequest);
        if (!userService.isAdmin(loginUser)) {
            return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "无权限");
        }

        Long userId = loginUser.getId();
        String userName = loginUser.getUserName();

        if (id == null || id <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "公告ID无效");
        }

        try {
            // 检查公告是否存在
            Announcement announcement = announcementService.getById(id);
            if (announcement == null) {
                throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "公告不存在");
            }

            // 逻辑删除
            UpdateWrapper<Announcement> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("id", id);
            updateWrapper.set("isDelete", 1);
            boolean result = announcementService.update(updateWrapper);

            if (!result) {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "删除公告失败");
            }

            // 记录操作历史 - 成功
            String resultMessage = String.format("%s成功删除公告：%s（ID：%d）", 
                                                userName, announcement.getTitle(), id);
            operationHistoryService.recordOperation(userId, "删除公告", 1, "成功", resultMessage);

            log.info("管理员{}删除公告成功，公告ID：{}", userName, id);
            return ResultUtils.success(true);

        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("删除公告失败：{}", e.getMessage(), e);

            // 记录操作历史 - 失败
            String resultMessage = String.format("%s删除公告失败：%s，公告ID：%d", 
                                                userName, e.getMessage(), id);
            operationHistoryService.recordOperation(userId, "删除公告", 1, "失败", resultMessage);

            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "删除公告失败：" + e.getMessage());
        }
    }

    /**
     * 分页获取公告列表
     *
     * @param queryRequest 查询请求
     * @param httpServletRequest Http请求
     * @return 分页公告列表
     */
    @GetMapping("/list/page")
    @Operation(summary = "分页获取公告列表", description = "分页获取公告列表，支持多条件查询")
    public ApiResponse<Page<AnnouncementVO>> listAnnouncementsByPage(AnnouncementQueryRequest queryRequest,
                                                                     HttpServletRequest httpServletRequest) {
        // 权限校验
        User loginUser = userService.getLoginUser(httpServletRequest);
        if (!userService.isAdmin(loginUser)) {
            return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "无权限");
        }

        if (queryRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数不能为空");
        }

        long current = queryRequest.getCurrent();
        long pageSize = queryRequest.getPageSize();

        // 构建查询条件
        QueryWrapper<Announcement> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("isDelete", 0); // 只查询未删除的

        // 标题模糊查询
        if (StringUtils.isNotBlank(queryRequest.getTitle())) {
            queryWrapper.like("title", queryRequest.getTitle());
        }

        // 状态筛选
        if (queryRequest.getStatus() != null) {
            queryWrapper.eq("status", queryRequest.getStatus());
        }

        // 优先级筛选
        if (queryRequest.getPriority() != null) {
            queryWrapper.eq("priority", queryRequest.getPriority());
        }

        // 发布人ID筛选
        if (queryRequest.getPublisherId() != null) {
            queryWrapper.eq("publisherId", queryRequest.getPublisherId());
        }

        // 发布人名称模糊查询
        if (StringUtils.isNotBlank(queryRequest.getPublisherName())) {
            queryWrapper.like("publisherName", queryRequest.getPublisherName());
        }

        // 排序：优先级降序，然后创建时间降序
        queryWrapper.orderByDesc("priority", "createTime");

        // 执行分页查询
        Page<Announcement> announcementPage = announcementService.page(new Page<>(current, pageSize), queryWrapper);

        // 转换为VO对象
        List<AnnouncementVO> announcementVOList = announcementPage.getRecords().stream().map(announcement -> {
            AnnouncementVO announcementVO = new AnnouncementVO();
            BeanUtils.copyProperties(announcement, announcementVO);
            return announcementVO;
        }).collect(Collectors.toList());

        // 创建VO分页对象
        Page<AnnouncementVO> announcementVOPage = new Page<>(announcementPage.getCurrent(), 
                                                              announcementPage.getSize(), 
                                                              announcementPage.getTotal());
        announcementVOPage.setRecords(announcementVOList);
        announcementVOPage.setPages(announcementPage.getPages());

        return ResultUtils.success(announcementVOPage);
    }

    /**
     * 获取单个公告详情
     *
     * @param id 公告ID
     * @param httpServletRequest Http请求
     * @return 公告详情
     */
    @GetMapping("/get/{id}")
    @Operation(summary = "获取公告详情", description = "根据ID获取公告详情")
    public ApiResponse<AnnouncementVO> getAnnouncement(@Parameter(description = "公告ID", required = true)
                                                       @PathVariable Long id,
                                                       HttpServletRequest httpServletRequest) {
        if (id == null || id <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "公告ID无效");
        }

        try {
            Announcement announcement = announcementService.getById(id);
            if (announcement == null || announcement.getIsDelete() == 1) {
                throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "公告不存在");
            }

            AnnouncementVO announcementVO = new AnnouncementVO();
            BeanUtils.copyProperties(announcement, announcementVO);

            return ResultUtils.success(announcementVO);

        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("获取公告详情失败：{}", e.getMessage(), e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "获取公告详情失败：" + e.getMessage());
        }
    }

    /**
     * 更新公告状态
     *
     * @param id 公告ID
     * @param status 状态：0-草稿，1-已发布，2-已下架
     * @param httpServletRequest Http请求
     * @return 更新结果
     */
    @PutMapping("/status/{id}")
    @Operation(summary = "更新公告状态", description = "管理员更新公告状态（发布/下架）")
    public ApiResponse<Boolean> updateAnnouncementStatus(
            @Parameter(description = "公告ID", required = true) @PathVariable Long id,
            @Parameter(description = "状态：0-草稿，1-已发布，2-已下架", required = true) @RequestParam Integer status,
            HttpServletRequest httpServletRequest) {
        // 权限校验
        User loginUser = userService.getLoginUser(httpServletRequest);
        if (!userService.isAdmin(loginUser)) {
            return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "无权限");
        }

        Long userId = loginUser.getId();
        String userName = loginUser.getUserName();

        if (id == null || id <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "公告ID无效");
        }
        if (status == null || status < 0 || status > 2) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "状态值无效");
        }

        try {
            // 检查公告是否存在
            Announcement announcement = announcementService.getById(id);
            if (announcement == null || announcement.getIsDelete() == 1) {
                throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "公告不存在");
            }

            // 更新状态
            UpdateWrapper<Announcement> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("id", id);
            updateWrapper.set("status", status);
            boolean result = announcementService.update(updateWrapper);

            if (!result) {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "更新公告状态失败");
            }

            // 记录操作历史 - 成功
            String statusText = status == 0 ? "草稿" : (status == 1 ? "已发布" : "已下架");
            String resultMessage = String.format("%s成功将公告状态更新为%s：%s（ID：%d）", 
                                                userName, statusText, announcement.getTitle(), id);
            operationHistoryService.recordOperation(userId, "更新公告状态", 1, "成功", resultMessage);

            log.info("管理员{}更新公告状态成功，公告ID：{}，新状态：{}", userName, id, statusText);
            return ResultUtils.success(true);

        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("更新公告状态失败：{}", e.getMessage(), e);

            // 记录操作历史 - 失败
            String resultMessage = String.format("%s更新公告状态失败：%s，公告ID：%d", 
                                                userName, e.getMessage(), id);
            operationHistoryService.recordOperation(userId, "更新公告状态", 1, "失败", resultMessage);

            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "更新公告状态失败：" + e.getMessage());
        }
    }

    /**
     * 增加公告浏览次数
     *
     * @param id 公告ID
     * @return 更新结果
     */
    @PutMapping("/view/{id}")
    @Operation(summary = "增加浏览次数", description = "用户查看公告时增加浏览次数")
    public ApiResponse<Boolean> increaseViewCount(@Parameter(description = "公告ID", required = true)
                                                  @PathVariable Long id) {
        if (id == null || id <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "公告ID无效");
        }

        try {
            Announcement announcement = announcementService.getById(id);
            if (announcement == null || announcement.getIsDelete() == 1) {
                throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "公告不存在");
            }

            // 增加浏览次数
            UpdateWrapper<Announcement> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("id", id);
            updateWrapper.setSql("viewCount = viewCount + 1");
            boolean result = announcementService.update(updateWrapper);

            return ResultUtils.success(result);

        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("增加浏览次数失败：{}", e.getMessage(), e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "增加浏览次数失败：" + e.getMessage());
        }
    }

    /**
     * 获取公告统计数据
     *
     * @param httpServletRequest Http请求
     * @return 公告统计数据
     */
    @GetMapping("/statistics")
    @Operation(summary = "获取公告统计数据", description = "获取公告总数、已发布、草稿和已下架的数量")
    public ApiResponse<Map<String, Long>> getAnnouncementStatistics(HttpServletRequest httpServletRequest) {
        // 权限校验
        User loginUser = userService.getLoginUser(httpServletRequest);
        if (!userService.isAdmin(loginUser)) {
            return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "无权限");
        }

        try {
            // 总数（未删除的）
            QueryWrapper<Announcement> totalWrapper = new QueryWrapper<>();
            totalWrapper.eq("isDelete", 0);
            long totalCount = announcementService.count(totalWrapper);

            // 已发布的
            QueryWrapper<Announcement> publishedWrapper = new QueryWrapper<>();
            publishedWrapper.eq("isDelete", 0).eq("status", 1);
            long publishedCount = announcementService.count(publishedWrapper);

            // 草稿
            QueryWrapper<Announcement> draftWrapper = new QueryWrapper<>();
            draftWrapper.eq("isDelete", 0).eq("status", 0);
            long draftCount = announcementService.count(draftWrapper);

            // 已下架的
            QueryWrapper<Announcement> offlineWrapper = new QueryWrapper<>();
            offlineWrapper.eq("isDelete", 0).eq("status", 2);
            long offlineCount = announcementService.count(offlineWrapper);

            // 构造返回结果
            Map<String, Long> statistics = new HashMap<>();
            statistics.put("totalCount", totalCount);
            statistics.put("publishedCount", publishedCount);
            statistics.put("draftCount", draftCount);
            statistics.put("offlineCount", offlineCount);

            return ResultUtils.success(statistics);

        } catch (Exception e) {
            log.error("获取公告统计数据失败：{}", e.getMessage(), e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "获取公告统计数据失败：" + e.getMessage());
        }
    }

    /**
     * 获取最新的公告列表（用于首页展示）
     *
     * @param limit 限制数量，默认5条
     * @return 最新公告列表
     */
    @GetMapping("/latest")
    @Operation(summary = "获取最新公告", description = "获取最新的已发布公告列表，用于首页展示")
    public ApiResponse<List<AnnouncementVO>> getLatestAnnouncements(
            @Parameter(description = "限制数量，默认5条") @RequestParam(defaultValue = "5") Integer limit) {
        if (limit == null || limit <= 0) {
            limit = 5;
        }
        if (limit > 20) {
            limit = 20; // 最多返回20条
        }

        try {
            // 查询已发布的公告，按优先级和创建时间排序
            QueryWrapper<Announcement> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("isDelete", 0)
                       .eq("status", 1) // 只查已发布的
                       .orderByDesc("priority", "createTime")
                       .last("LIMIT " + limit);

            List<Announcement> announcements = announcementService.list(queryWrapper);

            // 转换为VO
            List<AnnouncementVO> announcementVOList = announcements.stream().map(announcement -> {
                AnnouncementVO announcementVO = new AnnouncementVO();
                BeanUtils.copyProperties(announcement, announcementVO);
                return announcementVO;
            }).collect(Collectors.toList());

            return ResultUtils.success(announcementVOList);

        } catch (Exception e) {
            log.error("获取最新公告失败：{}", e.getMessage(), e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "获取最新公告失败：" + e.getMessage());
        }
    }

    /**
     * 获取置顶公告列表
     *
     * @param limit 限制数量，默认10条
     * @return 置顶公告列表
     */
    @GetMapping("/top")
    @Operation(summary = "获取置顶公告", description = "获取所有置顶的已发布公告列表")
    public ApiResponse<List<AnnouncementVO>> getTopAnnouncements(
            @Parameter(description = "限制数量，默认10条") @RequestParam(defaultValue = "10") Integer limit) {
        if (limit == null || limit <= 0) {
            limit = 10;
        }
        if (limit > 50) {
            limit = 50; // 最多返回50条
        }

        try {
            // 查询置顶且已发布的公告，按创建时间降序排序
            QueryWrapper<Announcement> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("isDelete", 0)
                       .eq("status", 1) // 只查已发布的
                       .eq("priority", 1) // 只查置顶的
                       .orderByDesc("createTime")
                       .last("LIMIT " + limit);

            List<Announcement> announcements = announcementService.list(queryWrapper);

            // 转换为VO
            List<AnnouncementVO> announcementVOList = announcements.stream().map(announcement -> {
                AnnouncementVO announcementVO = new AnnouncementVO();
                BeanUtils.copyProperties(announcement, announcementVO);
                return announcementVO;
            }).collect(Collectors.toList());

            return ResultUtils.success(announcementVOList);

        } catch (Exception e) {
            log.error("获取置顶公告失败：{}", e.getMessage(), e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "获取置顶公告失败：" + e.getMessage());
        }
    }

    /**
     * 用户端获取所有已发布公告（置顶优先）
     *
     * @return 已发布公告列表，置顶优先
     */
    @GetMapping("/published")
    @Operation(summary = "获取所有已发布公告", description = "用户端获取所有已发布的公告，置顶优先，按创建时间降序排序")
    public ApiResponse<List<AnnouncementVO>> getPublishedAnnouncements() {
        try {
            // 查询所有已发布的公告，置顶优先，然后按创建时间降序
            QueryWrapper<Announcement> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("isDelete", 0)
                       .eq("status", 1) // 只查已发布的
                       .orderByDesc("priority", "createTime");

            List<Announcement> announcements = announcementService.list(queryWrapper);

            // 转换为VO
            List<AnnouncementVO> announcementVOList = announcements.stream().map(announcement -> {
                AnnouncementVO announcementVO = new AnnouncementVO();
                BeanUtils.copyProperties(announcement, announcementVO);
                return announcementVO;
            }).collect(Collectors.toList());

            return ResultUtils.success(announcementVOList);

        } catch (Exception e) {
            log.error("获取已发布公告失败：{}", e.getMessage(), e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "获取已发布公告失败：" + e.getMessage());
        }
    }
}
