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

import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.server.controller.admin.harmfulinforeport.vo.HarmfulInfoReportPageReqVO;
import cn.iocoder.yudao.module.server.dal.dataobject.harmfulinforeport.HarmfulInfoReportDO;
import cn.iocoder.yudao.module.server.dal.dataobject.rectifyinforeport.RectifyInfoSummaryExportVO;
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
import cn.iocoder.yudao.module.system.service.dept.DeptService;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.alibaba.fastjson.JSONObject;
import com.mzt.logapi.starter.annotation.LogRecord;
import org.apache.commons.lang3.StringUtils;
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.net.URLEncoder;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Month;
import java.time.YearMonth;
import java.util.*;
import java.io.IOException;
import java.util.stream.Collectors;

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.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 static cn.iocoder.yudao.module.system.enums.LogRecordConstants.*;

import cn.iocoder.yudao.module.server.controller.admin.rectifyinforeport.vo.*;
import cn.iocoder.yudao.module.server.dal.dataobject.rectifyinforeport.RectifyInfoReportDO;
import cn.iocoder.yudao.module.server.service.rectifyinforeport.RectifyInfoReportService;

@Tag(name = "管理后台 - 整改结果")
@RestController
@RequestMapping("/server/rectify-info-report")
@Validated
public class RectifyInfoReportController {

    @Resource
    private RectifyInfoReportService rectifyInfoReportService;
    @Resource
    private DeptService deptService;

    @PostMapping("/create")
    @Operation(summary = "创建整改结果")
    @PreAuthorize("@ss.hasPermission('server:rectify-info-report:create')")
    public CommonResult<Long> createRectifyInfoReport(@Valid @RequestBody RectifyInfoReportSaveReqVO createReqVO) {
        Long deptId = SecurityFrameworkUtils.getLoginUserDeptId();
        if(deptId!=null){
            DeptDO dept = deptService.getDept(deptId);
            createReqVO.setDepartmentName(dept.getName());
            createReqVO.setDepartmentId(deptId);
        }
        createReqVO.setReportTime(LocalDateTime.now());
        createReqVO.setReportStatus("未上报");
        return success(rectifyInfoReportService.createRectifyInfoReport(createReqVO));
    }

    @PostMapping("/update")
    @Operation(summary = "更新整改结果")
    @PreAuthorize("@ss.hasPermission('server:rectify-info-report:update')")
    public CommonResult<Boolean> updateRectifyInfoReport(@Valid @RequestBody RectifyInfoReportSaveReqVO updateReqVO) {
        updateReqVO.setReportTime(LocalDateTime.now());
        rectifyInfoReportService.updateRectifyInfoReport(updateReqVO);
        return success(true);
    }

    @PostMapping("/delete")
    @Operation(summary = "删除整改结果")
    /*@LogRecord(type = SYSTEM_ROLE_TYPE, subType = SYSTEM_ROLE_CREATE_SUB_TYPE, bizNo = "{{#role.id}}",
            success = SYSTEM_ROLE_CREATE_SUCCESS)*/
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('server:rectify-info-report:delete')")
    public CommonResult<Boolean> deleteRectifyInfoReport(@RequestParam("id") Long id) {
        rectifyInfoReportService.deleteRectifyInfoReport(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得整改结果")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('server:rectify-info-report:query')")
    public CommonResult<RectifyInfoReportRespVO> getRectifyInfoReport(@RequestParam("id") Long id) {
        RectifyInfoReportDO rectifyInfoReport = rectifyInfoReportService.getRectifyInfoReport(id);
        return success(BeanUtils.toBean(rectifyInfoReport, RectifyInfoReportRespVO.class));
    }

    @GetMapping("/page")
    @Operation(summary = "获得整改结果分页")
    @PreAuthorize("@ss.hasPermission('server:rectify-info-report:query')")
    public CommonResult<PageResult<RectifyInfoReportRespVO>> getRectifyInfoReportPage(@Valid RectifyInfoReportPageReqVO pageReqVO) {
        PageResult<RectifyInfoReportDO> pageResult = rectifyInfoReportService.getRectifyInfoReportPage(pageReqVO);
        return success(BeanUtils.toBean(pageResult, RectifyInfoReportRespVO.class));
    }

    @Operation(summary = "首页面板")
    @PermitAll
    @RequestMapping("/indexdata")
    public CommonResult<JSONObject> indexdata(@Valid RectifyInfoReportPageReqVO pageReqVO) {
        JSONObject indexData = new JSONObject();

        // 总上报数
        indexData.put("totalCount", countByTimeRange(null, null));

        // 本年上报数
        LocalDateTime startOfYear = LocalDate.now().withDayOfYear(1).atStartOfDay();
        LocalDateTime endOfYear = LocalDate.of(LocalDate.now().getYear(), 12, 31).atTime(23, 59, 59);
        indexData.put("yearCount", countByTimeRange(startOfYear, endOfYear));

        // 本季度上报数
        indexData.put("quarterCount", countByTimeRange(
                getStartOfCurrentQuarter(), getEndOfCurrentQuarter()));

        // 本月上报数
        LocalDateTime startOfMonth = LocalDate.now().withDayOfMonth(1).atStartOfDay();
        LocalDateTime endOfMonth = YearMonth.from(LocalDate.now()).atEndOfMonth().atTime(23, 59, 59);
        indexData.put("monthCount", countByTimeRange(startOfMonth, endOfMonth));

        // 每月上报数（本年1~12月）
        List<Long> monthCountList = new ArrayList<>();
        int currentYear = LocalDate.now().getYear();
        for (int month = 1; month <= 12; month++) {
            LocalDateTime start = LocalDate.of(currentYear, month, 1).atStartOfDay();
            LocalDateTime end = YearMonth.of(currentYear, month).atEndOfMonth().atTime(23, 59, 59);
            monthCountList.add(countByTimeRange(start, end));
        }
        indexData.put("monthCountList", monthCountList);

        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
//        pageReqVO.setReportStatus("已上报"); // 只统计已上报的数据
        List<RectifyInfoReportDO> reports = rectifyInfoReportService.getRectifyInfoReportPage(pageReqVO).getList();
        // 汇总数据
        int interviewCount = reports.stream().mapToInt(r -> r.getInterviewCount() != null ? r.getInterviewCount() : 0).sum();
        int writtenExaminationCount = reports.stream().mapToInt(r -> r.getWrittenExaminationCount() != null ? r.getWrittenExaminationCount() : 0).sum();
        int criticismCount = reports.stream().mapToInt(r -> r.getCriticismCount() != null ? r.getCriticismCount() : 0).sum();
        int warningCount = reports.stream().mapToInt(r -> r.getWarningCount() != null ? r.getWarningCount() : 0).sum();
        int dismissalCount = reports.stream().mapToInt(r -> r.getDismissalCount() != null ? r.getDismissalCount() : 0).sum();
        int otherCount = reports.stream().mapToInt(r -> r.getOtherCount() != null ? r.getOtherCount() : 0).sum();
        // 返回新增字段
        indexData.put("interviewCount", interviewCount);
        indexData.put("writtenExaminationCount", writtenExaminationCount);
        indexData.put("criticismCount", criticismCount);
        indexData.put("warningCount", warningCount);
        indexData.put("dismissalCount", dismissalCount);
        indexData.put("otherCount", otherCount);

        return success(indexData);
    }
    private Long countByTimeRange(LocalDateTime start, LocalDateTime end) {
        RectifyInfoReportPageReqVO pageReqVO = new RectifyInfoReportPageReqVO();
        pageReqVO.setReportStatus("已上报");
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);

        if (start != null && end != null) {
            pageReqVO.setReportTime(new LocalDateTime[]{start, end});
        }
        return rectifyInfoReportService.getRectifyInfoReportPage(pageReqVO).getTotal(); // 使用分页结果的总数
    }
    private LocalDateTime getStartOfCurrentQuarter() {
        Month currentMonth = LocalDate.now().getMonth();
        int startMonth = (currentMonth.firstMonthOfQuarter().getValue());
        return LocalDate.of(LocalDate.now().getYear(), startMonth, 1).atStartOfDay();
    }

    private LocalDateTime getEndOfCurrentQuarter() {
        Month currentMonth = LocalDate.now().getMonth();
        int endMonth = currentMonth.firstMonthOfQuarter().getValue() + 2;
        YearMonth ym = YearMonth.of(LocalDate.now().getYear(), endMonth);
        return ym.atEndOfMonth().atTime(23, 59, 59);
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出整改结果 Excel")
    @PreAuthorize("@ss.hasPermission('server:rectify-info-report:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportRectifyInfoReportExcel(@Valid RectifyInfoReportPageReqVO pageReqVO,
              HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<RectifyInfoReportDO> list = rectifyInfoReportService.getRectifyInfoReportPage(pageReqVO).getList();
        // 导出 Excel
        ExcelUtils.write(response, "整改结果.xls", "数据", RectifyInfoReportRespVO.class,
                        BeanUtils.toBean(list, RectifyInfoReportRespVO.class));
    }

    @PostMapping("/report")
    @Operation(summary = "上报信息上报")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('server:rectify-info-report:report')")
    public CommonResult<Boolean> reportHarmfulInfoReport(@RequestParam("id") Long id) {
        RectifyInfoReportDO rectifyInfoReport = rectifyInfoReportService.getRectifyInfoReport(id);
        rectifyInfoReport.setReportStatus("已上报");
        rectifyInfoReportService.updateRectifyInfoReportObj(rectifyInfoReport);
        return success(true);
    }


    @GetMapping("/export-summary-excel")
    @Operation(summary = "按单位导出整改结果汇总表")
    @PreAuthorize("@ss.hasPermission('server:rectify-info-report:adminexport')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportSummaryByDepartment(@Valid RectifyInfoReportPageReqVO pageReqVO,
                                          HttpServletResponse response) throws IOException {
        // 设置查询条件，只查询已上报的数据
        pageReqVO.setReportStatus("已上报");
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);

        String year = pageReqVO.getYear();
        if (StringUtils.isNotBlank(year)) {
            // 解析选择的年份
            int yearValue = Integer.parseInt(year);
            // 获取该年份的起止时间
            LocalDateTime startOfYear = LocalDate.of(yearValue, 1, 1).atStartOfDay();
            LocalDateTime endOfYear = LocalDate.of(yearValue, 12, 31).atTime(23, 59, 59);
            pageReqVO.setReportTime(new LocalDateTime[]{startOfYear, endOfYear});
        }else {
            // 获取今年的起止时间
            LocalDateTime startOfYear = LocalDate.now().withDayOfYear(1).atStartOfDay();
            LocalDateTime endOfYear = LocalDate.now().withMonth(12).withDayOfMonth(31).atTime(23, 59, 59);
            pageReqVO.setReportTime(new LocalDateTime[]{startOfYear, endOfYear});
        }

        // 获取数据
        List<RectifyInfoReportDO> reports = rectifyInfoReportService.getRectifyInfoReportPage(pageReqVO).getList();

        // 按单位分组并转换为Sheet数据
        List<RectifySummarySheetData> sheetDataList = convertToSheetData(reports);

        // 创建Excel写入器
        ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build();

        // 注册全局样式处理器
        RectifyExcelStyleHandler styleHandler = new RectifyExcelStyleHandler();

        // 写入多个Sheet
        int sheetIndex = 0;
        for (RectifySummarySheetData sheetData : sheetDataList) {
            // 创建Sheet
            WriteSheet writeSheet = EasyExcel.writerSheet(sheetIndex++, sheetData.getDepartmentName())
                    .head(RectifyInfoSummaryExportVO.class)
                    .registerWriteHandler(styleHandler) // 注册样式处理器
                    .registerWriteHandler(RectifyExcelStyleFactory.createStyleStrategy())
                    .build();

            // 写入数据
            excelWriter.write(sheetData.getData(), writeSheet);
        }

        // 设置响应头
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode("整改结果汇总表(按单位)", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");

        excelWriter.finish();
    }

    // 数据转换方法
    private List<RectifySummarySheetData> convertToSheetData(List<RectifyInfoReportDO> reports) {
        // 按单位分组
        Map<String, List<RectifyInfoReportDO>> reportsByDepartment = reports.stream()
                .collect(Collectors.groupingBy(RectifyInfoReportDO::getDepartmentName));

        List<RectifySummarySheetData> result = new ArrayList<>();

        for (Map.Entry<String, List<RectifyInfoReportDO>> entry : reportsByDepartment.entrySet()) {
            RectifySummarySheetData sheetData = new RectifySummarySheetData();
            sheetData.setDepartmentName(entry.getKey());
            sheetData.setData(convertToSummaryFormat(entry.getValue()));
            result.add(sheetData);
        }

        return result;
    }

    // 转换为汇总格式
// 在 convertToSummaryFormat 方法中确保行顺序
    private List<RectifyInfoSummaryExportVO> convertToSummaryFormat(List<RectifyInfoReportDO> reports) {
        List<RectifyInfoSummaryExportVO> result = new ArrayList<>();

        // 确保顺序
        String[] rectifyTypes = {
                "约谈", "书面检查", "通报批评",
                "警告或记过处分", "调离岗位或免职", "其他"
        };

        // 按季度分组
        Map<String, List<RectifyInfoReportDO>> reportsByQuarter = reports.stream()
                .collect(Collectors.groupingBy(RectifyInfoReportDO::getQuarter));

        for (String type : rectifyTypes) {
            result.add(createSummaryRow(type, reportsByQuarter));
        }

        return result;
    }

    // 创建每种整改类型的汇总行
    private RectifyInfoSummaryExportVO createSummaryRow(String rectifyType,
                                                        Map<String, List<RectifyInfoReportDO>> reportsByQuarter) {
        RectifyInfoSummaryExportVO vo = new RectifyInfoSummaryExportVO();
        vo.setRectifyType(rectifyType);

        // 各季度数据
        int firstQuarter = sumByQuarterAndType(reportsByQuarter.get("第一季度"), rectifyType);
        int secondQuarter = sumByQuarterAndType(reportsByQuarter.get("第二季度"), rectifyType);
        int thirdQuarter = sumByQuarterAndType(reportsByQuarter.get("第三季度"), rectifyType);
        int fourthQuarter = sumByQuarterAndType(reportsByQuarter.get("第四季度"), rectifyType);

        vo.setFirstQuarter(firstQuarter);
        vo.setSecondQuarter(secondQuarter);
        vo.setThirdQuarter(thirdQuarter);
        vo.setFourthQuarter(fourthQuarter);

        // 总数
        vo.setTotal(firstQuarter + secondQuarter + thirdQuarter + fourthQuarter);

        return vo;
    }

    // 按整改类型求和
    private int sumByQuarterAndType(List<RectifyInfoReportDO> reports, String rectifyType) {
        if (reports == null) return 0;

        return reports.stream()
                .mapToInt(r -> {
                    switch (rectifyType) {
                        case "约谈": return r.getInterviewCount() != null ? r.getInterviewCount() : 0;
                        case "书面检查": return r.getWrittenExaminationCount() != null ? r.getWrittenExaminationCount() : 0;
                        case "通报批评": return r.getCriticismCount() != null ? r.getCriticismCount() : 0;
                        case "警告或记过处分": return r.getWarningCount() != null ? r.getWarningCount() : 0;
                        case "调离岗位或免职": return r.getDismissalCount() != null ? r.getDismissalCount() : 0;
                        case "其他": return r.getOtherCount() != null ? r.getOtherCount() : 0;
                        default: return 0;
                    }
                })
                .sum();
    }


}