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

import cn.iocoder.yudao.framework.security.core.LoginUser;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
import cn.iocoder.yudao.module.system.service.dept.DeptService;
import cn.iocoder.yudao.module.system.service.permission.PermissionService;
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.core.io.ClassPathResource;
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.*;
import javax.servlet.http.*;
import java.io.InputStream;
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.harmfulinforeport.vo.*;
import cn.iocoder.yudao.module.server.dal.dataobject.harmfulinforeport.HarmfulInfoReportDO;
import cn.iocoder.yudao.module.server.service.harmfulinforeport.HarmfulInfoReportService;
import org.springframework.web.multipart.MultipartFile;

@Tag(name = "管理后台 - 信息上报")
@RestController
@RequestMapping("/server/harmful-info-report")
@Validated
public class HarmfulInfoReportController {

    @Resource
    private HarmfulInfoReportService harmfulInfoReportService;

    @Resource
    private DeptService deptService;
    @Resource
    private PermissionService permissionService;


    @PostMapping("/create")
    @Operation(summary = "创建信息上报")
    @PreAuthorize("@ss.hasPermission('server:harmful-info-report:create')")
    public CommonResult<Long> createHarmfulInfoReport(@Valid @RequestBody HarmfulInfoReportSaveReqVO createReqVO) {
        Long deptId = SecurityFrameworkUtils.getLoginUserDeptId();
        if(deptId!=null){
            DeptDO dept = deptService.getDept(deptId);
            createReqVO.setDepartmentName(dept.getName());
            createReqVO.setDepartmentId(deptId);
            boolean idAdmin = permissionService.hasAnyRoles(SecurityFrameworkUtils.getLoginUser().getId(), "super_admin");
            if(!idAdmin){//待优化字典
                if(dept.getParentId()==100){
                    createReqVO.setReportStatus("自治区政府部门");
                }else if(dept.getParentId()==111){
                    createReqVO.setReportStatus("盟市");
                }
            }
        }
        createReqVO.setReportTime(LocalDateTime.now());
        createReqVO.setReportStatus("未上报");
        return success(harmfulInfoReportService.createHarmfulInfoReport(createReqVO));
    }

    @PostMapping("/update")
    @Operation(summary = "更新信息上报")
    @PreAuthorize("@ss.hasPermission('server:harmful-info-report:update')")
    public CommonResult<Boolean> updateHarmfulInfoReport(@Valid @RequestBody HarmfulInfoReportSaveReqVO updateReqVO) {
        updateReqVO.setReportTime(LocalDateTime.now());
        harmfulInfoReportService.updateHarmfulInfoReport(updateReqVO);
        return success(true);
    }

    @PostMapping("/delete")
    @Operation(summary = "删除信息上报")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('server:harmful-info-report:delete')")
    public CommonResult<Boolean> deleteHarmfulInfoReport(@RequestParam("id") Long id) {
        harmfulInfoReportService.deleteHarmfulInfoReport(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得信息上报")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('server:harmful-info-report:query')")
    public CommonResult<HarmfulInfoReportRespVO> getHarmfulInfoReport(@RequestParam("id") Long id) {
        HarmfulInfoReportDO harmfulInfoReport = harmfulInfoReportService.getHarmfulInfoReport(id);
        return success(BeanUtils.toBean(harmfulInfoReport, HarmfulInfoReportRespVO.class));
    }

    @GetMapping("/page")
    @Operation(summary = "获得信息上报分页")
    @PreAuthorize("@ss.hasPermission('server:harmful-info-report:query')")
    public CommonResult<PageResult<HarmfulInfoReportRespVO>> getHarmfulInfoReportPage(@Valid HarmfulInfoReportPageReqVO pageReqVO) {
        PageResult<HarmfulInfoReportDO> pageResult = harmfulInfoReportService.getHarmfulInfoReportPage(pageReqVO);
        return success(BeanUtils.toBean(pageResult, HarmfulInfoReportRespVO.class));
    }

    @Operation(summary = "首页面板")
    @PermitAll
    @RequestMapping("/indexdata")
    public CommonResult<JSONObject> indexdata(@Valid HarmfulInfoReportPageReqVO 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<HarmfulInfoReportDO> reports = harmfulInfoReportService.getHarmfulInfoReportPage(pageReqVO).getList();
        // 汇总数据
        int websiteCount = reports.stream().mapToInt(r -> r.getWebsite() != null ? r.getWebsite() : 0).sum();
        int newMediaCount = reports.stream().mapToInt(r -> r.getNewMedia() != null ? r.getNewMedia() : 0).sum();
        int totalCount = reports.stream().mapToInt(r -> r.getTotalCount() != null ? r.getTotalCount() : 0).sum();
        // 返回新增字段
        indexData.put("websiteCount", websiteCount);
        indexData.put("newMediaCount", newMediaCount);
        indexData.put("totalAllCount", totalCount);

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

        if (start != null && end != null) {
            pageReqVO.setReportTime(new LocalDateTime[]{start, end});
        }
        return harmfulInfoReportService.getHarmfulInfoReportPage(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:harmful-info-report:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportHarmfulInfoReportExcel(@Valid HarmfulInfoReportPageReqVO pageReqVO,
              HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<HarmfulInfoReportDO> list = harmfulInfoReportService.getHarmfulInfoReportPage(pageReqVO).getList();
        // 导出 Excel
        ExcelUtils.write(response, "信息上报.xls", "数据", HarmfulInfoReportRespVO.class,
                        BeanUtils.toBean(list, HarmfulInfoReportRespVO.class));
    }

    @PostMapping("/report")
    @Operation(summary = "上报信息上报")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('server:harmful-info-report:report')")
    public CommonResult<Boolean> reportHarmfulInfoReport(@RequestParam("id") Long id) {
        HarmfulInfoReportDO harmfulInfoReport = harmfulInfoReportService.getHarmfulInfoReport(id);
        harmfulInfoReport.setReportStatus("已上报");
        harmfulInfoReportService.updateHarmfulInfoReportObj(harmfulInfoReport);
        return success(true);
    }


    // 创建精确表头(完全匹配图片)
    @GetMapping("/export-summary-excel")
    @Operation(summary = "导出信息上报汇总（完全还原模板样式）")
    @PreAuthorize("@ss.hasPermission('server:harmful-info-report:adminexport')")
    public void exportExactFormatExcel(@Valid HarmfulInfoReportPageReqVO 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<HarmfulInfoReportDO> reports = harmfulInfoReportService.getHarmfulInfoReportPage(pageReqVO).getList();

        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");

        // 构建完整表格数据（表头 + 数据）
        List<List<String>> fullData = new ArrayList<>();
        fullData.addAll(createExactHeader());
        fullData.addAll(createQuarterData(reports));

        EasyExcel.write(response.getOutputStream())
                .head((Class<?>) null) // 明确无 JavaBean
                .registerWriteHandler(new SummaryExcelCellStyleHandler())
                .registerWriteHandler(new SummaryExcelMergeHandler())
                .sheet("信息上报汇总")
                .doWrite(fullData);
    }


    private List<List<String>> createExactHeader() {
        List<List<String>> header = new ArrayList<>();

        // 第一行：A1-D1="盟市"、E1-H1="部门"
//        header.add(Arrays.asList("盟市", "", "", "", "部门", "", "", ""));
        header.add(Arrays.asList("", "盟市", "", "", "", "部门", "", ""));
        // 第二行：列标题
        header.add(Arrays.asList("", "网站", "新媒体", "共计",
                                 "", "网站", "新媒体", "共计"));

        return header;
    }
    private List<List<String>> createQuarterData(List<HarmfulInfoReportDO> reports) {
        List<List<String>> data = new ArrayList<>();
        Map<String, List<HarmfulInfoReportDO>> grouped = reports.stream()
                .collect(Collectors.groupingBy(HarmfulInfoReportDO::getQuarter));

        String[] quarters = {"第一季度", "第二季度", "第三季度", "第四季度"};

        int ctiyWCount = 0;
        int ctiyNCount = 0;
        int ctiyTotal = 0;
        int deptWCount = 0;
        int deptNCount = 0;
        int deptTotal = 0;

        for (String quarter : quarters) {
            List<HarmfulInfoReportDO> quarterReports = grouped.getOrDefault(quarter, new ArrayList<>());
            List<HarmfulInfoReportDO> cityList = new ArrayList<>();
            List<HarmfulInfoReportDO> deptList = new ArrayList<>();

            List<HarmfulInfoReportDO> totalList = new ArrayList<>();

            for (HarmfulInfoReportDO r : quarterReports) {
                if ("盟市".equals(r.getReporterType())) {
                    cityList.add(r);
                } else if ("部门".equals(r.getReporterType())) {
                    deptList.add(r);
                }
            }

            int cityW = cityList.stream().mapToInt(r -> r.getWebsite() == null ? 0 : r.getWebsite()).sum();
            int cityN = cityList.stream().mapToInt(r -> r.getNewMedia() == null ? 0 : r.getNewMedia()).sum();
            int deptW = deptList.stream().mapToInt(r -> r.getWebsite() == null ? 0 : r.getWebsite()).sum();
            int deptN = deptList.stream().mapToInt(r -> r.getNewMedia() == null ? 0 : r.getNewMedia()).sum();

            int totalW = cityList.stream().mapToInt(r -> r.getTotalCount() == null ? 0 : r.getTotalCount()).sum();
            int totalN = deptList.stream().mapToInt(r -> r.getTotalCount() == null ? 0 : r.getTotalCount()).sum();

            ctiyWCount += cityW;
            ctiyNCount += cityN;
            ctiyTotal += totalW;
            deptWCount += deptW;
            deptNCount += deptN;
            deptTotal += totalN;

            data.add(Arrays.asList(
                    quarter,
                    String.valueOf(cityW),
                    String.valueOf(cityN),
                    String.valueOf(totalW),
                    "",
                    String.valueOf(deptW),
                    String.valueOf(deptN),
                    String.valueOf(totalN)
            ));
        }

        data.add(Arrays.asList(
                "全年共计",
                String.valueOf(ctiyWCount),
                String.valueOf(ctiyNCount),
                String.valueOf(ctiyTotal),
                "",
                String.valueOf(deptWCount),
                String.valueOf(deptNCount),
                String.valueOf(deptTotal)
        ));

        return data;
    }


    /**
     * 简单下载模板 - 从resources/template目录读取
     */
    @Operation(summary = "下载报送模板")
    @PermitAll
    @GetMapping("/download-template")
    public void downloadTemplate(HttpServletResponse response) {
        InputStream inputStream = null;
        try {
            // 从classpath读取文件
            ClassPathResource resource = new ClassPathResource("有害信息报送模板.docx");
            inputStream = resource.getInputStream();

            // 设置响应头
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition",
                    "attachment; filename=\"" + URLEncoder.encode("有害信息报送模板.docx", "UTF-8") + "\"");

            // 流式传输
            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                response.getOutputStream().write(buffer, 0, bytesRead);
            }
            response.getOutputStream().flush();

        } catch (Exception e) {
            e.printStackTrace();
            response.setStatus(500);
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

}