package com.hotwj.platform.reportStatistics.controller;

import com.hotwj.platform.reportStatistics.domain.vo.OfflineTrainingListVo;
import com.hotwj.platform.reportStatistics.domain.vo.TrainingPlanDetailVo;
import com.hotwj.platform.reportStatistics.service.ISecurityManageFilePrintService;
import com.hotwj.platform.securityManagement.securityMeeting.domain.bo.HotSecurityMeetingBo;
import com.hotwj.platform.securityManagement.securityMeeting.domain.vo.HotSecurityMeetingVo;
import com.hotwj.platform.securityManagement.securityMeeting.service.IHotSecurityMeetingService;
import com.hotwj.platform.securityManagement.training.domain.bo.HotTrainingBo;
import com.hotwj.platform.securityManagement.training.domain.vo.HotTrainingVo;
import com.hotwj.platform.securityManagement.training.service.IHotTrainingService;
import com.hotwj.platform.securityManagement.trainingCourseRecord.domain.bo.HotTrainingCourseRecordBo;
import com.hotwj.platform.securityManagement.trainingCourseRecord.domain.vo.HotTrainingCourseRecordVo;
import com.hotwj.platform.securityManagement.trainingCourseRecord.service.IHotTrainingCourseRecordService;
import com.hotwj.platform.securityManagement.trainingParticipant.domain.bo.HotTrainingParticipantBo;
import com.hotwj.platform.securityManagement.trainingParticipant.domain.vo.HotTrainingParticipantVo;
import com.hotwj.platform.securityManagement.trainingParticipant.service.IHotTrainingParticipantService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.core.utils.file.FileUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.web.core.BaseController;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.*;

/**
 * 学习报表打印模块
 *
 * @author shihongwei
 * @date 2026-02-18
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/reportStatistics/learnPrintReport")
@Tag(name = "学习报表打印", description = "学习报表打印")
public class LearnPrintReportController extends BaseController {

    private final IHotTrainingService hotTrainingService;
    private final IHotTrainingParticipantService trainingParticipantService;
    private final IHotTrainingCourseRecordService trainingCourseRecordService;
    private final ISecurityManageFilePrintService securityManageFilePrintService;
    private final IHotSecurityMeetingService hotSecurityMeetingService;

    //@SaCheckPermission("reportStatistics:preJobTrainingPlan:list")
    @GetMapping("/trainingPlan/list")
    @Operation(summary = "培训计划-分页查询")
    public TableDataInfo<HotTrainingVo> preJobTrainingPlanList(
            @RequestParam Long companyId,
            @RequestParam(required = false) String planName,
            @RequestParam(required = false) String personType,
            @RequestParam(required = false) String trainingType,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date startBeginDate,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date startEndDate,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date endBeginDate,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date endEndDate,
            @RequestParam(required = false) Long isEnabled,
            @RequestParam(required = false) String planOwner,
            PageQuery pageQuery
    ) {
        HotTrainingBo bo = new HotTrainingBo();
        bo.setCompanyId(companyId);
        bo.setPlanName(planName);
        bo.setPersonType(personType);
        bo.setIsEnabled(isEnabled);
        bo.setPlanOwner(planOwner);
        String finalTrainingType = StringUtils.isBlank(trainingType) ? "pre-job" : trainingType;
        bo.setTrainingType(finalTrainingType);
        bo.setIsDeleted(0L);
        if (startBeginDate != null) {
            bo.getParams().put("startBeginDate", startBeginDate);
        }
        if (startEndDate != null) {
            bo.getParams().put("startEndDate", startEndDate);
        }
        if (endBeginDate != null) {
            bo.getParams().put("endBeginDate", endBeginDate);
        }
        if (endEndDate != null) {
            bo.getParams().put("endEndDate", endEndDate);
        }
        return hotTrainingService.queryPageList(bo, pageQuery);
    }

    //@SaCheckPermission("reportStatistics:trainingPlanDetail:list")
    @GetMapping("/trainingPlan/detail")
    @Operation(summary = "培训计划明细-分页查询")
    public TableDataInfo<TrainingPlanDetailVo> trainingPlanDetail(
            @RequestParam Long companyId,
            @RequestParam Long trainingId,
            @RequestParam(required = false) String userName,
            @RequestParam(required = false) String phone,
            @RequestParam(required = false) Long personType,
            @RequestParam(required = false) Long isCompleted,
            PageQuery pageQuery
    ) {
        HotTrainingParticipantBo bo = new HotTrainingParticipantBo();
        bo.setCompanyId(companyId);
        bo.setTrainingId(trainingId);
        bo.setUserName(userName);
        bo.setPhone(phone);
        bo.setPersonType(personType);
        bo.setIsCompleted(isCompleted);
        bo.setIsDeleted(0L);
        TableDataInfo<HotTrainingParticipantVo> participantPage = trainingParticipantService.queryPageList(bo, pageQuery);
        List<HotTrainingParticipantVo> participantRows = participantPage.getRows();
        if (participantRows == null || participantRows.isEmpty()) {
            return new TableDataInfo<>(new ArrayList<>(), 0);
        }
        HotTrainingVo trainingVo = hotTrainingService.queryById(trainingId);
        Long isMakeUp = trainingVo != null ? trainingVo.getIsMakeUp() : null;
        HotTrainingCourseRecordBo recordBo = new HotTrainingCourseRecordBo();
        recordBo.setCompanyId(companyId);
        recordBo.setTrainingId(trainingId);
        recordBo.setIsDeleted(0L);
        List<HotTrainingCourseRecordVo> records = trainingCourseRecordService.queryList(recordBo);
        Map<String, Long> signatureMap = new HashMap<>();
        for (HotTrainingCourseRecordVo record : records) {
            if (record.getSignatureOssId() != null && StringUtils.isNotBlank(record.getUserId())) {
                signatureMap.putIfAbsent(record.getUserId(), record.getSignatureOssId());
            }
        }
        List<TrainingPlanDetailVo> list = new ArrayList<>();
        for (HotTrainingParticipantVo p : participantRows) {
            TrainingPlanDetailVo vo = new TrainingPlanDetailVo();
            vo.setUserId(p.getUserId());
            vo.setUserName(p.getUserName());
            vo.setPhone(p.getPhone());
            vo.setPersonType(p.getPersonType());
            vo.setCompleteTime(p.getCompleteTime());
            vo.setIsCompleted(p.getIsCompleted());
            vo.setIsMakeUp(isMakeUp);
            vo.setSignatureOssId(signatureMap.get(p.getUserId()));
            list.add(vo);
        }
        return new TableDataInfo<>(list, participantPage.getTotal());
    }

    //@SaCheckPermission("reportStatistics:trainingPlanDetail:list")
    @GetMapping("/trainingPlan/monthlyStat/exportPdf")
    @Operation(summary = "培训计划月度统计-PDF导出")
    public void trainingPlanMonthlyStatExportPdf(
            @RequestParam Long companyId,
            @RequestParam Long trainingId,
            @RequestParam(value = "userIds", required = false) List<String> userIds,
            HttpServletResponse response
    ) {
        byte[] bytes = securityManageFilePrintService.generateTrainingPlanMonthlyStatPdf(companyId, trainingId, userIds);
        try {
            FileUtils.setAttachmentResponseHeader(response, "培训计划月度统计表.pdf");
            response.setContentType("application/pdf");
            response.getOutputStream().write(bytes);
        } catch (IOException e) {
            throw new RuntimeException("导出PDF异常", e);
        }
    }

    //@SaCheckPermission("reportStatistics:trainingPlanDetail:list")
    @GetMapping("/trainingPlan/studyRecord/exportPdf")
    @Operation(summary = "学习记录打印-PDF导出")
    public void studyRecordExportPdf(
            @RequestParam Long companyId,
            @RequestParam Long trainingId,
            @RequestParam("userIds") List<String> userIds,
            HttpServletResponse response
    ) {
        byte[] bytes = securityManageFilePrintService.generateStudyRecordPdf(companyId, trainingId, userIds);
        try {
            FileUtils.setAttachmentResponseHeader(response, "学习记录表.pdf");
            response.setContentType("application/pdf");
            response.getOutputStream().write(bytes);
        } catch (IOException e) {
            throw new RuntimeException("导出PDF异常", e);
        }
    }

    //@SaCheckPermission("reportStatistics:trainingPlanDetail:list")
    @GetMapping("/trainingPlan/studyDetail/exportPdf")
    @Operation(summary = "学习明细打印-PDF导出")
    public void studyDetailExportPdf(
            @RequestParam Long companyId,
            @RequestParam Long trainingId,
            @RequestParam("userIds") java.util.List<String> userIds,
            HttpServletResponse response
    ) {
        byte[] bytes = securityManageFilePrintService.generateStudyDetailPdf(companyId, trainingId, userIds);
        try {
            FileUtils.setAttachmentResponseHeader(response, "学习明细表.pdf");
            response.setContentType("application/pdf");
            response.getOutputStream().write(bytes);
        } catch (IOException e) {
            throw new RuntimeException("导出PDF异常", e);
        }
    }

    //@SaCheckPermission("reportStatistics:preJobTrainingPlan:list")
    @GetMapping("/offlineTraining/list")
    @Operation(summary = "线下培训统计-分页查询")
    public TableDataInfo<OfflineTrainingListVo> offlineTrainingList(
            @RequestParam Long companyId,
            @RequestParam(required = false) String type,
            @RequestParam(required = false) String category,
            @RequestParam(required = false) String name,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date beginTime,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date endTime,
            PageQuery pageQuery
    ) {
        HotTrainingBo bo = new HotTrainingBo();
        bo.setCompanyId(companyId);
        bo.setMeetingType(type);
        bo.setTrainingType("offline");
        bo.setMeetingCategory(category);
        bo.setPlanName(name);
        bo.setIsDeleted(0L);
        if (beginTime != null) {
            bo.getParams().put("startBeginDate", beginTime);
        }
        if (endTime != null) {
            bo.getParams().put("startEndDate", endTime);
        }
        TableDataInfo<HotTrainingVo> pageInfo = hotTrainingService.queryPageList(bo, pageQuery);

        // 转换为 OfflineTrainingListVo
        List<OfflineTrainingListVo> list = new ArrayList<>();
        if (pageInfo.getRows() != null) {
            for (HotTrainingVo vo : pageInfo.getRows()) {
                OfflineTrainingListVo item = new OfflineTrainingListVo();
                item.setId(vo.getId());
                item.setMeetingTopic(vo.getPlanName()); // 名称
                item.setMeetingCategory(vo.getMeetingCategory()); // 种类
                item.setOfflineMeetingType(vo.getMeetingType()); // 类型
                item.setEndTime(vo.getEndTime()); // 结束时间
                item.setMeetingStatus(vo.getIsIssued() != null && vo.getIsIssued() == 1 ? "已下发" : "未下发"); // 状态 (根据业务逻辑映射)
                item.setStartTime(vo.getStartTime());
                item.setLocation(vo.getTrainingLocation());
                item.setHostName(vo.getTeacherName());
                item.setRecorderName(vo.getRecorderName());
                list.add(item);
            }
        }

        TableDataInfo<OfflineTrainingListVo> result = new TableDataInfo<>();
        result.setRows(list);
        result.setTotal(pageInfo.getTotal());
        result.setCode(pageInfo.getCode());
        result.setMsg(pageInfo.getMsg());
        return result;
    }

    //@SaCheckPermission("reportStatistics:preJobTrainingPlan:list")
    @GetMapping("/offlineMeeting/list")
    @Operation(summary = "线下会议统计-分页查询")
    public TableDataInfo<OfflineTrainingListVo> offlineMeetingList(
            @RequestParam Long companyId,
            @RequestParam(required = false) String type,
            @RequestParam(required = false) String category,
            @RequestParam(required = false) String name,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date beginTime,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date endTime,
            PageQuery pageQuery
    ) {
        HotSecurityMeetingBo bo = new HotSecurityMeetingBo();
        bo.setCompanyId(companyId);
        bo.setMeetingType("offline"); // 线下会议
        bo.setOfflineMeetingType(type); // 具体的线下会议类型
        bo.setMeetingCategory(category);
        bo.setMeetingTopic(name);
        bo.setIsDeleted(0L);
        Map<String, Object> params = new HashMap<>();
        if (beginTime != null) {
            params.put("beginTime", beginTime);
        }
        if (endTime != null) {
            params.put("endTime", endTime);
        }
        bo.setParams(params);
        TableDataInfo<HotSecurityMeetingVo> pageInfo = hotSecurityMeetingService.queryPageList(bo, pageQuery);

        // 转换为 OfflineTrainingListVo
        List<OfflineTrainingListVo> list = new ArrayList<>();
        if (pageInfo.getRows() != null) {
            for (HotSecurityMeetingVo vo : pageInfo.getRows()) {
                OfflineTrainingListVo item = new OfflineTrainingListVo();
                item.setId(vo.getId());
                item.setMeetingTopic(vo.getMeetingTopic()); // 名称
                item.setMeetingCategory(vo.getMeetingCategory()); // 种类
                item.setOfflineMeetingType(vo.getOfflineMeetingType()); // 类型
                item.setEndTime(vo.getEndTime()); // 结束时间
                item.setMeetingStatus(vo.getMeetingStatus()); // 状态
                item.setStartTime(vo.getStartTime());
                item.setLocation(vo.getLocation());
                item.setHostName(vo.getHostName());
                item.setRecorderName(vo.getRecorderName());
                list.add(item);
            }
        }

        TableDataInfo<OfflineTrainingListVo> result = new TableDataInfo<>();
        result.setRows(list);
        result.setTotal(pageInfo.getTotal());
        result.setCode(pageInfo.getCode());
        result.setMsg(pageInfo.getMsg());
        return result;
    }

    //@SaCheckPermission("reportStatistics:preJobTrainingPlan:list")
    @GetMapping("/offlineTraining/exportPdf")
    @Operation(summary = "线下培训会议照片打印-PDF导出")
    public void offlineTrainingPhotoExportPdf(
            @RequestParam Long companyId,
            @RequestParam("trainingIds") java.util.List<Long> trainingIds,
            @RequestParam(value = "type", required = false, defaultValue = "1") Integer type,
            HttpServletResponse response
    ) {
        byte[] bytes = securityManageFilePrintService.generateOfflineTrainingPhotoPdf(companyId, trainingIds, type);
        try {
            String fileName = type == 2 ? "线下会议记录.pdf" : "线下培训记录.pdf";
            FileUtils.setAttachmentResponseHeader(response, fileName);
            response.setContentType("application/pdf");
            response.getOutputStream().write(bytes);
        } catch (IOException e) {
            throw new RuntimeException("导出PDF异常", e);
        }
    }
}
