package cn.iocoder.yudao.module.server.controller.admin.policycommunications;

import cn.iocoder.yudao.framework.common.exception.ErrorCode;
import cn.iocoder.yudao.module.server.controller.admin.policycommunications.vo.analysis.*;
import cn.iocoder.yudao.module.server.enums.ErrorCodeConstants;
import cn.iocoder.yudao.module.server.service.policycommunications.TraditionalCaptchaMathService;
import cn.iocoder.yudao.module.server.service.policycommunications.TraditionalCaptchaService;
import cn.iocoder.yudao.module.server.utils.MultiRateLimit;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;

import javax.annotation.security.PermitAll;
import javax.validation.constraints.*;
import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;

import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.error;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;

import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;

import cn.iocoder.yudao.module.server.controller.admin.policycommunications.vo.*;
import cn.iocoder.yudao.module.server.dal.dataobject.policycommunications.PolicyCommunicationsDO;
import cn.iocoder.yudao.module.server.service.policycommunications.PolicyCommunicationsService;

@Tag(name = "管理后台 - 政策沟通交流")
@RestController
@RequestMapping("/server/policy-communications")
@Validated
public class PolicyCommunicationsController {

    @Resource
    private PolicyCommunicationsService policyCommunicationsService;
    @Resource
    private TraditionalCaptchaService traditionalCaptchaService;
    @Resource
    private TraditionalCaptchaMathService traditionalCaptchaMathService;

    @PostMapping("/create")
    @Operation(summary = "创建政策沟通交流")
    @PreAuthorize("@ss.hasPermission('server:policy-communications:create')")
    public CommonResult<Long> createPolicyCommunications(@Valid @RequestBody PolicyCommunicationsSaveReqVO createReqVO) {
        return success(policyCommunicationsService.createPolicyCommunications(createReqVO));
    }

    @PostMapping("/update")
    @Operation(summary = "更新政策沟通交流")
    @PreAuthorize("@ss.hasPermission('server:policy-communications:update')")
    public CommonResult<Boolean> updatePolicyCommunications(@Valid @RequestBody PolicyCommunicationsSaveReqVO updateReqVO) {
        policyCommunicationsService.updatePolicyCommunications(updateReqVO);
        return success(true);
    }

    @PostMapping("/updateStatus")
    @Operation(summary = "更新政策沟通交流")
    @PreAuthorize("@ss.hasPermission('server:policy-communications:update')")
    public CommonResult<Boolean> updateStatusPolicyCommunications(@Valid @RequestBody PolicyCommunicationsSaveReqVO updateReqVO) {
        policyCommunicationsService.updateStatusPolicyCommunications(updateReqVO);
        return success(true);
    }

    @PostMapping("/delete")
    @Operation(summary = "删除政策沟通交流")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('server:policy-communications:delete')")
    public CommonResult<Boolean> deletePolicyCommunications(@RequestParam("id") Long id) {
        policyCommunicationsService.deletePolicyCommunications(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得政策沟通交流")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('server:policy-communications:query')")
    public CommonResult<PolicyCommunicationsRespAdminVO> getPolicyCommunications(@RequestParam("id") Long id) {
        PolicyCommunicationsDO policyCommunications = policyCommunicationsService.getPolicyCommunications(id);
        return success(BeanUtils.toBean(policyCommunications, PolicyCommunicationsRespAdminVO.class));
    }

    @GetMapping("/page")
    @Operation(summary = "获得政策沟通交流分页")
    @PreAuthorize("@ss.hasPermission('server:policy-communications:query')")
    public CommonResult<PageResult<PolicyCommunicationsRespVO>> getPolicyCommunicationsPage(@Valid PolicyCommunicationsPageReqVO pageReqVO) {
        PageResult<PolicyCommunicationsDO> pageResult = policyCommunicationsService.getPolicyCommunicationsPage(pageReqVO);
        return success(BeanUtils.toBean(pageResult, PolicyCommunicationsRespVO.class));
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出政策沟通交流 Excel")
    @PreAuthorize("@ss.hasPermission('server:policy-communications:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportPolicyCommunicationsExcel(@Valid PolicyCommunicationsPageReqVO pageReqVO,
              HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<PolicyCommunicationsDO> list = policyCommunicationsService.getPolicyCommunicationsPage(pageReqVO).getList();
        // 导出 Excel
        ExcelUtils.write(response, "政策沟通交流.xls", "数据", PolicyCommunicationsRespAdminVO.class,
                        BeanUtils.toBean(list, PolicyCommunicationsRespAdminVO.class));
    }

    @PostMapping("/update-sort")
    @Operation(summary = "更新政策沟通交流排序")
    @PreAuthorize("@ss.hasPermission('server:policy-communications:update')")
    public CommonResult<Boolean> updatePolicyCommunicationsSort(@Valid @RequestBody PolicyCommunicationsSortReqVO reqVO) {
        policyCommunicationsService.updatePolicyCommunicationsSort(reqVO);
        return success(true);
    }
    @PostMapping("/batch-update-sort")
    @Operation(summary = "批量更新政策沟通交流排序")
    @PreAuthorize("@ss.hasPermission('server:policy-communications:update')")
    public CommonResult<Boolean> batchUpdateSort(@Valid @RequestBody List<PolicyCommunicationsBatchSortReqVO.SortItem> items) {
        policyCommunicationsService.batchUpdateSort(items);
        return success(true);
    }

    // PolicyCommunicationsController.java

    @GetMapping("/pending/page")
    @Operation(summary = "获得待处理政策沟通交流分页")
    public CommonResult<PageResult<PolicyCommunicationsRespAdminVO>> getPendingPolicyCommunicationsPage(@Valid PolicyCommunicationsPageReqVO pageReqVO) {
        pageReqVO.setDealStatus(0); // 待处理
        PageResult<PolicyCommunicationsDO> pageResult = policyCommunicationsService.getPolicyCommunicationsPage(pageReqVO);
        return success(BeanUtils.toBean(pageResult, PolicyCommunicationsRespAdminVO.class));
    }

    @GetMapping("/replied/page")
    @Operation(summary = "获得已回复政策沟通交流分页")
    public CommonResult<PageResult<PolicyCommunicationsRespAdminVO>> getRepliedPolicyCommunicationsPage(@Valid PolicyCommunicationsPageReqVO pageReqVO) {
        pageReqVO.setDealStatus(1); // 已回复
        PageResult<PolicyCommunicationsDO> pageResult = policyCommunicationsService.getPolicyCommunicationsPage(pageReqVO);
        return success(BeanUtils.toBean(pageResult, PolicyCommunicationsRespAdminVO.class));
    }

    @GetMapping("/published/page")
    @Operation(summary = "获得已公开政策沟通交流分页")
    public CommonResult<PageResult<PolicyCommunicationsRespAdminVO>> getPublishedPolicyCommunicationsPage(@Valid PolicyCommunicationsPageReqVO pageReqVO) {
        pageReqVO.setDealStatus(2); // 已公开
        PageResult<PolicyCommunicationsDO> pageResult = policyCommunicationsService.getPolicyCommunicationsPage(pageReqVO);
        return success(BeanUtils.toBean(pageResult, PolicyCommunicationsRespAdminVO.class));
    }

    @GetMapping("/rejected/page")
    @Operation(summary = "获得不予受理政策沟通交流分页")
    public CommonResult<PageResult<PolicyCommunicationsRespAdminVO>> getRejectedPolicyCommunicationsPage(@Valid PolicyCommunicationsPageReqVO pageReqVO) {
        pageReqVO.setDealStatus(3); // 不予受理
        PageResult<PolicyCommunicationsDO> pageResult = policyCommunicationsService.getPolicyCommunicationsPage(pageReqVO);
        return success(BeanUtils.toBean(pageResult, PolicyCommunicationsRespAdminVO.class));
    }


    @GetMapping("/anonymous/get-image")
    @Operation(summary = "获取传统验证码图片")
    @PermitAll
    public CommonResult<CaptchaImageRespDTO> getCaptchaImage() {
        CaptchaImageRespDTO captchaImage = traditionalCaptchaMathService.generateCaptchaImage();
        return success(captchaImage);
    }

    @GetMapping("/anonymous/refresh")
    @Operation(summary = "刷新验证码图片")
    @PermitAll
    public CommonResult<CaptchaImageRespDTO> refreshCaptchaImage() {
        // 与get-image相同，只是接口名不同，方便前端理解
        return getCaptchaImage();
    }
    @RequestMapping("/create-anonymous")
    @Operation(summary = "匿名创建政策沟通交流")
    @PermitAll  // 允许匿名访问
    @ApiAccessLog(enable = false) // 禁用访问日志，避免记录匿名用户信息
    @MultiRateLimit(
            minuteLimit = 3,   // 1分钟2次
            hourLimit = 30,    // 1小时30次
            dayLimit = 50     // 24小时100次
    )
    public CommonResult<Long> createPolicyCommunicationsAnonymous(@Valid @RequestBody PolicyCommunicationsAnonymousCreateReqVO createReqVO) {
        // 验证传统验证码
        boolean valid = traditionalCaptchaMathService.verifyCaptcha(
                createReqVO.getCaptchaUuid(),
                createReqVO.getCaptchaCode()
        );
        if (!valid) {
            return error(new ErrorCode(10001, "验证码错误"));
        }
        return success(policyCommunicationsService.createPolicyCommunicationsAnonymous(createReqVO));
    }


    @RequestMapping("/anonymous/user/page")
    @Operation(summary = "按用户ID查询列表（包含公开和不公开）")
    @PermitAll
    @ApiAccessLog(enable = false)
    public CommonResult<PageResult<PolicyCommunicationsRespVO>> getPolicyCommunicationsByUser(PolicyCommunicationsAnonymousQueryReqVO queryReqVO) {
        if(queryReqVO.getUserId()==null||"".equals(queryReqVO.getUserId())){
            return error(new ErrorCode(10001,"用户id不能为空"));
        }
        PageResult<PolicyCommunicationsDO> pageResult = policyCommunicationsService
                .getPolicyCommunicationsByUser(queryReqVO);
        return success(BeanUtils.toBean(pageResult, PolicyCommunicationsRespVO.class));
    }

    @RequestMapping("/anonymous/policy/page")
    @Operation(summary = "按政策ID查询列表（只查询公开）")
    @PermitAll
    @ApiAccessLog(enable = false)
    public CommonResult<PageResult<PolicyCommunicationsRespVO>> getPolicyCommunicationsByPolicy(PolicyCommunicationsAnonymousQueryReqVO queryReqVO) {
        if(queryReqVO.getPolicyId()==null||"".equals(queryReqVO.getPolicyId())){
            return error(new ErrorCode(10002,"政策id不能为空"));
        }
        PageResult<PolicyCommunicationsDO> pageResult = policyCommunicationsService
                .getPolicyCommunicationsByPolicy(queryReqVO);
        return success(BeanUtils.toBean(pageResult, PolicyCommunicationsRespVO.class));
    }

    @RequestMapping("/anonymous/policy/detail")
    @Operation(summary = "按ID查询详情")
    @PermitAll
    @ApiAccessLog(enable = false)
    public CommonResult<PolicyCommunicationsRespVO> getPolicyCommunicationsById(@RequestParam Long id) {
        if(id==null){
            return error(new ErrorCode(10002,"id不能为空"));
        }
        PolicyCommunicationsDO policyCommunications = policyCommunicationsService.getPolicyCommunications(id);
        return success(BeanUtils.toBean(policyCommunications, PolicyCommunicationsRespVO.class));
    }

    @RequestMapping("/anonymous/public/page")
    @Operation(summary = "查询所有公开列表")
    @PermitAll
    @ApiAccessLog(enable = false)
    public CommonResult<PageResult<PolicyCommunicationsRespVO>> getPublicPolicyCommunications(PolicyCommunicationsAnonymousQueryReqVO queryReqVO) {
        PageResult<PolicyCommunicationsDO> pageResult = policyCommunicationsService
                .getPublicPolicyCommunications(queryReqVO);
        return success(BeanUtils.toBean(pageResult, PolicyCommunicationsRespVO.class));
    }


    // 统计分析接口
    @GetMapping("/analysis/kpi")
    @Operation(summary = "获取统计分析KPI指标")
    @PreAuthorize("@ss.hasPermission('server:policy-communications:query')")
    public CommonResult<PolicyCommunicationsAnalysisKpiRespVO> getAnalysisKpi(PolicyCommunicationsAnalysisQueryReqVO queryReqVO) {
        return success(policyCommunicationsService.getAnalysisKpi(queryReqVO));
    }

    @GetMapping("/analysis/policy-rank")
    @Operation(summary = "获取政策排行分析")
    @PreAuthorize("@ss.hasPermission('server:policy-communications:query')")
    public CommonResult<PolicyCommunicationsRankRespVO> getPolicyRankAnalysis(
            @Valid PolicyCommunicationsAnalysisQueryReqVO queryReqVO,
            @RequestParam(value = "order", defaultValue = "desc") String order,
            @RequestParam(value = "limit", defaultValue = "10") Integer limit) {
        return success(policyCommunicationsService.getPolicyRankAnalysis(queryReqVO, order, limit));
    }

    @GetMapping("/analysis/trend")
    @Operation(summary = "获取趋势分析")
    @PreAuthorize("@ss.hasPermission('server:policy-communications:query')")
    public CommonResult<PolicyCommunicationsTrendAnalysisRespVO> getTrendAnalysis(PolicyCommunicationsAnalysisQueryReqVO queryReqVO) {
        return success(policyCommunicationsService.getTrendAnalysis(queryReqVO));
    }

    @GetMapping("/analysis/department")
    @Operation(summary = "获取部门处理效能分析")
    @PreAuthorize("@ss.hasPermission('server:policy-communications:query')")
    public CommonResult<PolicyCommunicationsDepartmentAnalysisRespVO> getDepartmentAnalysis(PolicyCommunicationsAnalysisQueryReqVO queryReqVO) {
        return success(policyCommunicationsService.getDepartmentAnalysis(queryReqVO));
    }

    @GetMapping("/analysis/overtime")
    @Operation(summary = "获取超时未回复清单")
    @PreAuthorize("@ss.hasPermission('server:policy-communications:query')")
    public CommonResult<PolicyCommunicationsOverdueListRespVO> getOverdueList(
            @Valid PolicyCommunicationsAnalysisQueryReqVO queryReqVO,
            @RequestParam(value = "overdueDays", defaultValue = "30") Integer overdueDays) {
        return success(policyCommunicationsService.getOverdueList(queryReqVO, overdueDays));
    }

    @GetMapping("/analysis/type-distribution")
    @Operation(summary = "获取沟通类型分布")
    @PreAuthorize("@ss.hasPermission('server:policy-communications:query')")
    public CommonResult<PolicyCommunicationsContentAnalysisRespVO> getContentAnalysis(PolicyCommunicationsAnalysisQueryReqVO queryReqVO) {
        return success(policyCommunicationsService.getContentAnalysis(queryReqVO));
    }

    @GetMapping("/analysis/department-list")
    @Operation(summary = "获取部门列表")
    @PreAuthorize("@ss.hasPermission('server:policy-communications:query')")
    public CommonResult<DepartmentListRespVO> getDepartmentList() {
        return success(policyCommunicationsService.getDepartmentList());
    }

    @GetMapping("/analysis/word-cloud")
    @Operation(summary = "获取高频词云数据")
    @PreAuthorize("@ss.hasPermission('server:policy-communications:query')")
    public CommonResult<List<PolicyCommunicationsContentAnalysisRespVO.WordCloudItem>> getWordCloudData(PolicyCommunicationsAnalysisQueryReqVO queryReqVO) {
        PolicyCommunicationsContentAnalysisRespVO contentAnalysis = policyCommunicationsService.getContentAnalysis(queryReqVO);
        return success(contentAnalysis.getWordCloudData());
    }

    @GetMapping("/analysis/export-overtime")
    @Operation(summary = "导出超时未回复清单")
    @PreAuthorize("@ss.hasPermission('server:policy-communications:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportOverdueList(PolicyCommunicationsAnalysisQueryReqVO queryReqVO,
                                  @RequestParam(value = "overdueDays", defaultValue = "30") Integer overdueDays,
                                  HttpServletResponse response) throws IOException {
        PolicyCommunicationsOverdueListRespVO overdueList = policyCommunicationsService.getOverdueList(queryReqVO, overdueDays);

        // 导出 Excel
        ExcelUtils.write(response, "超时未回复清单.xls", "数据", PolicyCommunicationsOverdueListRespVO.OverdueItem.class,
                overdueList.getOverdueList());
    }

    // 示例接口


}