package com.hotwj.platform.securityManagement.trainingOutline.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hotwj.platform.common.utils.PdfWatermarkUtil;
import com.hotwj.platform.reportStatistics.integration.GotenbergClient;
import com.hotwj.platform.reportStatistics.template.VelocityTemplateRenderer;
import com.hotwj.platform.securityManagement.trainingOutline.domain.HotTrainingOutline;
import com.hotwj.platform.securityManagement.trainingOutline.domain.bo.HotTrainingOutlineBo;
import com.hotwj.platform.securityManagement.trainingOutline.domain.vo.HotTrainingOutlineVo;
import com.hotwj.platform.securityManagement.trainingOutline.mapper.HotTrainingOutlineMapper;
import com.hotwj.platform.securityManagement.trainingOutline.service.IHotTrainingOutlinePrintService;
import com.hotwj.platform.securityManagement.trainingOutlineCourse.domain.HotTrainingOutlineCourse;
import com.hotwj.platform.securityManagement.trainingOutlineCourse.domain.vo.HotTrainingOutlineCourseVo;
import com.hotwj.platform.securityManagement.trainingOutlineCourse.mapper.HotTrainingOutlineCourseMapper;
import com.hotwj.platform.securityManagement.trainingOutlineMonth.domain.HotTrainingOutlineMonth;
import com.hotwj.platform.securityManagement.trainingOutlineMonth.domain.vo.HotTrainingOutlineMonthVo;
import com.hotwj.platform.securityManagement.trainingOutlineMonth.mapper.HotTrainingOutlineMonthMapper;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.velocity.VelocityContext;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.core.utils.file.FileUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
@RequiredArgsConstructor
public class HotTrainingOutlinePrintServiceImpl implements IHotTrainingOutlinePrintService {

    private final HotTrainingOutlineMapper outlineMapper;
    private final HotTrainingOutlineMonthMapper outlineMonthMapper;
    private final HotTrainingOutlineCourseMapper outlineCourseMapper;
    private final VelocityTemplateRenderer velocityTemplateRenderer;
    private final GotenbergClient gotenbergClient;

    @Value("${dromara.app.name:HOT交通安全管理清单平台}")
    private String appName;

    @Override
    public void exportPdf(HotTrainingOutlineBo bo, HttpServletResponse response) {
        // 1. 查询大纲列表
        LambdaQueryWrapper<HotTrainingOutline> lqw = Wrappers.lambdaQuery();
        lqw.orderByAsc(HotTrainingOutline::getId);
        lqw.eq(bo.getOutlineYear() != null, HotTrainingOutline::getOutlineYear, bo.getOutlineYear());
        lqw.eq(StringUtils.isNotBlank(bo.getOutlineTypes()), HotTrainingOutline::getOutlineTypes, bo.getOutlineTypes());
        lqw.eq(bo.getIsEnabled() != null, HotTrainingOutline::getIsEnabled, bo.getIsEnabled());
        lqw.eq(StringUtils.isNotBlank(bo.getMonthPlanIds()), HotTrainingOutline::getMonthPlanIds, bo.getMonthPlanIds());
        lqw.eq(bo.getIsDeleted() != null, HotTrainingOutline::getIsDeleted, bo.getIsDeleted());

        List<HotTrainingOutlineVo> outlineList = outlineMapper.selectVoList(lqw);
        if (CollUtil.isEmpty(outlineList)) {
            throw new ServiceException("未查询到培训大纲数据");
        }

        // 假设只打印第一个匹配的大纲，或者需要循环打印。通常"导出PDF"如果是列表查询，可能导出列表。
        // 但根据前端逻辑，它似乎是在查看详情时打印，或者是针对特定年份的打印。
        // 如果是列表导出，我们可能需要一个包含多个大纲的 PDF。
        // 这里假设按照 vehicleThreeInspect 的逻辑，它导出的是一个列表。

        // 但前端传参是 queryParams，可能包含 id。
        // 如果 bo.getId() 不为空，则只导出一个。

        List<Map<String, Object>> printDataList = new ArrayList<>();

        for (HotTrainingOutlineVo outline : outlineList) {
            Map<String, Object> outlineData = new HashMap<>();
            outlineData.put("outlineYear", outline.getOutlineYear());

            // 查询月度计划
            List<HotTrainingOutlineMonth> months = outlineMonthMapper.selectList(
                    Wrappers.<HotTrainingOutlineMonth>lambdaQuery()
                            .eq(HotTrainingOutlineMonth::getOutlineId, outline.getId())
                            .eq(HotTrainingOutlineMonth::getIsDeleted, 0)
                            .orderByAsc(HotTrainingOutlineMonth::getSortNo) // 假设有排序
            );
            List<HotTrainingOutlineMonthVo> monthVos = MapstructUtils.convert(months, HotTrainingOutlineMonthVo.class);

            List<Map<String, Object>> flatRows = new ArrayList<>();

            if (CollUtil.isNotEmpty(monthVos)) {
                for (HotTrainingOutlineMonthVo month : monthVos) {
                    // 查询课程
                    List<HotTrainingOutlineCourse> courses = outlineCourseMapper.selectList(
                            Wrappers.<HotTrainingOutlineCourse>lambdaQuery()
                                    .eq(HotTrainingOutlineCourse::getMonthOutlineId, month.getId())
                                    .eq(HotTrainingOutlineCourse::getIsDeleted, 0)
                                    .orderByAsc(HotTrainingOutlineCourse::getSortNo)
                    );
                    List<HotTrainingOutlineCourseVo> courseVos = MapstructUtils.convert(courses, HotTrainingOutlineCourseVo.class);

                    if (CollUtil.isNotEmpty(courseVos)) {
                        for (int i = 0; i < courseVos.size(); i++) {
                            HotTrainingOutlineCourseVo course = courseVos.get(i);
                            Map<String, Object> row = new HashMap<>();
                            row.put("planMonth", month.getPlanMonth());
                            row.put("topic", month.getTopic());
                            row.put("courseName", course.getCourseName());
                            row.put("durationMinute", course.getDurationMinute());
                            row.put("courseDesc", course.getCourseDesc());

                            // 设置 rowSpan
                            if (i == 0) {
                                row.put("monthRowSpan", courseVos.size());
                            } else {
                                row.put("monthRowSpan", 0);
                            }
                            flatRows.add(row);
                        }
                    } else {
                        // 如果没有课程，也显示月度信息
                        Map<String, Object> row = new HashMap<>();
                        row.put("planMonth", month.getPlanMonth());
                        row.put("topic", month.getTopic());
                        row.put("courseName", "");
                        row.put("durationMinute", "");
                        row.put("courseDesc", "");
                        row.put("monthRowSpan", 1);
                        flatRows.add(row);
                    }
                }
            }
            outlineData.put("rows", flatRows);
            printDataList.add(outlineData);
        }

        // 渲染 HTML
        VelocityContext context = new VelocityContext();
        context.put("printTime", DateUtil.now());
        context.put("list", printDataList);
        context.put("appName", appName);

        String bodyHtml = velocityTemplateRenderer.render("templates/securityManage/trainingOutline.html.vm", context);

        VelocityContext layoutContext = new VelocityContext();
        layoutContext.put("title", "年度培训计划大纲");
        List<String> bodies = new ArrayList<>();
        bodies.add(bodyHtml);
        layoutContext.put("bodies", bodies);

        String finalHtml = velocityTemplateRenderer.render("templates/layout/printLayout.html.vm", layoutContext);

        try {
            byte[] pdfBytes = convertAndWatermark(finalHtml);
            response.setContentType("application/pdf");
            String fileName = "年度培训计划大纲.pdf";
            FileUtils.setAttachmentResponseHeader(response, fileName);
            response.getOutputStream().write(pdfBytes);
        } catch (Exception e) {
            log.error("Export PDF failed", e);
            throw new ServiceException("导出PDF失败");
        }
    }

    private byte[] convertAndWatermark(String htmlContent) throws Exception {
        File temp = Files.createTempFile("training-outline-print-", ".html").toFile();
        try {
            try (FileWriter fw = new FileWriter(temp, StandardCharsets.UTF_8)) {
                fw.write(htmlContent);
            }
            String footer = """
                    <div style="font-size:10px;color:#000;width:100%;padding:0 1cm;">
                        <span style="float:left;color:#888;">平台信息依实为准，信息使用自判</span>
                        <span style="float:right;">第 <span class='pageNumber'></span> / <span class='totalPages'></span> 页</span>
                    </div>
                    """;
            byte[] pdf = gotenbergClient.convertHtmlToPdf(temp, footer);
            return PdfWatermarkUtil.addWatermark(pdf, appName);
        } finally {
            if (temp.exists()) {
                if (!temp.delete()) {
                    log.warn("Failed to delete temp file: {}", temp.getAbsolutePath());
                }
            }
        }
    }
}
