package com.hotwj.platform.securityManagement.trainingCourseConfig.controller;

import com.fasterxml.jackson.core.type.TypeReference;
import com.hotwj.platform.config.courseResource.domain.bo.HotCourseResourceBo;
import com.hotwj.platform.config.courseResource.service.IHotCourseResourceService;
import com.hotwj.platform.securityManagement.training.domain.vo.HotTrainingVo;
import com.hotwj.platform.securityManagement.training.service.IHotTrainingService;
import com.hotwj.platform.securityManagement.trainingCourseConfig.domain.bo.HotTrainingCourseConfigBo;
import com.hotwj.platform.securityManagement.trainingCourseConfig.domain.vo.HotTrainingCourseConfigVo;
import com.hotwj.platform.securityManagement.trainingCourseConfig.domain.vo.TrainingUserCourseStudyDetailVo;
import com.hotwj.platform.securityManagement.trainingCourseConfig.service.IHotTrainingCourseConfigService;
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 com.hotwj.platform.securityManagement.training.support.StudyForbidPeriodSupport;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.json.utils.JsonUtils;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.log.enums.BusinessType;
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.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.*;

/**
 * 企业课程配置
 *
 * @author shihongwei
 * @date 2026-01-24
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/securityManagement/trainingCourseConfig")
@Tag(name = "企业课程配置", description = "企业课程配置管理")
public class HotTrainingCourseConfigController extends BaseController {

    private final IHotTrainingCourseConfigService hotTrainingCourseConfigService;
    private final IHotTrainingCourseRecordService hotTrainingCourseRecordService;
    private final IHotCourseResourceService hotCourseResourceService;
    private final IHotTrainingParticipantService hotTrainingParticipantService;
    private final IHotTrainingService hotTrainingService;
    private final StudyForbidPeriodSupport studyForbidPeriodSupport;

    /**
     * 查询企业课程配置列表
     */
    //@SaCheckPermission("securityManagement:trainingCourseConfig:list")
    @GetMapping("/list")
    @Operation(summary = "分页查询企业课程配置列表")
    public TableDataInfo<HotTrainingCourseConfigVo> list(HotTrainingCourseConfigBo bo, PageQuery pageQuery) {
        if (!Boolean.TRUE.equals(bo.getSkipIntercept()) && bo.getTrainingId() != null && StringUtils.isNotBlank(bo.getUserId())
                && !isDriverTrainingAccessible(bo.getCompanyId(), bo.getTrainingId(), bo.getUserId())) {
            TableDataInfo<HotTrainingCourseConfigVo> result = TableDataInfo.build(Collections.emptyList());
            result.setMsg("当前学习计划已关闭或已过期");
            return result;
        }
        TableDataInfo<HotTrainingCourseConfigVo> tableDataInfo = hotTrainingCourseConfigService.queryPageList(bo, pageQuery);
        List<HotTrainingCourseConfigVo> rows = tableDataInfo.getRows();
        if (rows == null || rows.isEmpty()) {
            return tableDataInfo;
        }
        for (HotTrainingCourseConfigVo vo : rows) {
            HotCourseResourceBo courseResourceBo = new HotCourseResourceBo();
            courseResourceBo.setCourseId(vo.getCourseId());
            courseResourceBo.setResourceType(3L);
            boolean hasLessonQuiz = !hotCourseResourceService.queryList(courseResourceBo).isEmpty();
            vo.setHasLessonQuiz(hasLessonQuiz);
            if (!hasLessonQuiz) {
                vo.setLessonQuizCompleted(null);
            }
            if (bo.getUserId() != null && !bo.getUserId().isEmpty()) {
                HotTrainingCourseRecordBo recordBo = new HotTrainingCourseRecordBo();
                recordBo.setCompanyId(vo.getCompanyId());
                recordBo.setTrainingId(vo.getTrainingId());
                recordBo.setTrainingCourseId(vo.getId());
                recordBo.setUserId(bo.getUserId());
                HotTrainingCourseRecordVo latest = hotTrainingCourseRecordService.queryLatestByUserAndCourse(recordBo);
                if (latest != null) {
                    if (latest.getLearnDurationMin() != null) {
                        vo.setLearnDurationMin(latest.getLearnDurationMin().intValue());
                    }
                    vo.setProgressRate(latest.getProgressRate());
                    vo.setCompleted(latest.getCheckStatus() != null && latest.getCheckStatus() == 1L);
                    vo.setCompleteTime(latest.getCompleteTime());
                    vo.setLessonQuizCompleted(latest.getCheckStatus() != null && latest.getCheckStatus() == 1L);
                }
            }

            if (bo.getUserId() != null && !bo.getUserId().isEmpty()) {
                HotTrainingParticipantBo pbo = new HotTrainingParticipantBo();
                pbo.setCompanyId(vo.getCompanyId());
                pbo.setTrainingId(vo.getTrainingId());
                pbo.setUserId(bo.getUserId());
                pbo.setIsDeleted(0L);
                List<HotTrainingParticipantVo> participants = hotTrainingParticipantService.queryList(pbo);
                if (participants != null && !participants.isEmpty()) {
                    String json = participants.get(0).getStudyPhotoOssId();
                    if (json != null && !json.isEmpty()) {
                        try {
                            Map<Long, Long> map = JsonUtils.parseObject(json, new TypeReference<>() {
                            });
                            if (map != null) {
                                Long ossId = map.get(vo.getId());
                                if (ossId != null) {
                                    vo.setStudyPhotoOssId(ossId);
                                }
                            }
                        } catch (Exception ignored) {
                        }
                    }
                }
            }
        }
        return tableDataInfo;
    }

    @GetMapping("/trainingStudyDetail")
    @Operation(summary = "培训学习明细聚合（含培训信息与课程明细）")
    public R<Map<String, Object>> trainingStudyDetail(
            @RequestParam Long companyId,
            @RequestParam Long trainingId,
            @RequestParam String userId,
            @RequestParam(required = false, defaultValue = "false") Boolean forceView,
            @RequestParam(required = false, defaultValue = "false") Boolean checkForbidStudy
    ) {
        if (Boolean.TRUE.equals(checkForbidStudy)) {
            String forbidMessage = studyForbidPeriodSupport.getForbidStudyMessage(companyId);
            if (StringUtils.isNotBlank(forbidMessage)) {
                return R.fail(forbidMessage);
            }
        }
        if (!Boolean.TRUE.equals(forceView) && !isDriverTrainingAccessible(companyId, trainingId, userId)) {
            return R.fail("当前学习计划已关闭或已过期");
        }
        HotTrainingVo training = hotTrainingService.queryById(trainingId);
        Long isMakeUp = training == null ? null : training.getIsMakeUp();

        Map<Long, Long> photoMap = Collections.emptyMap();

        HotTrainingParticipantBo participantBo = new HotTrainingParticipantBo();
        participantBo.setCompanyId(companyId);
        participantBo.setTrainingId(trainingId);
        participantBo.setUserId(userId);
        participantBo.setIsDeleted(0L);
        List<HotTrainingParticipantVo> participants = hotTrainingParticipantService.queryList(participantBo);
        Long isCompleted = null;
        Long isPass = null;
        if (participants != null && !participants.isEmpty()) {
            isCompleted = participants.get(0).getIsCompleted();
            isPass = participants.get(0).getIsPass();
            String json = participants.get(0).getStudyPhotoOssId();
            if (json != null && !json.isEmpty()) {
                try {
                    Map<Long, Long> parsed = JsonUtils.parseObject(json, new TypeReference<>() {
                    });
                    if (parsed != null) {
                        photoMap = parsed;
                    }
                } catch (Exception ignored) {
                }
            }
        }

        List<TrainingUserCourseStudyDetailVo> rows = hotTrainingCourseConfigService.queryTrainingUserCourseStudyDetail(companyId, trainingId, userId);
        if (rows == null) {
            rows = List.of();
        }

        List<Map<String, Object>> courseDetailList = new ArrayList<>();
        for (TrainingUserCourseStudyDetailVo row : rows) {
            if (row == null) {
                continue;
            }

            Long trainingCourseId = row.getTrainingCourseId();
            String courseName = row.getCourseName();
            BigDecimal progressRate = row.getProgressRate() == null ? BigDecimal.ZERO : row.getProgressRate();
            java.util.Date completeTime = row.getCompleteTime();
            Long studyPhotoOssId = trainingCourseId == null ? null : photoMap.get(trainingCourseId);

            Map<String, Object> item = new HashMap<>();
            item.put("courseName", courseName);
            item.put("progressRate", progressRate);
            item.put("completeTime", completeTime);
            item.put("isMakeUp", isMakeUp);
            item.put("studyPhotoOssId", studyPhotoOssId);
            courseDetailList.add(item);
        }

        Map<String, Object> resp = new HashMap<>();
        resp.put("traing", training);
        resp.put("isCompleted", isCompleted);
        resp.put("isPass", isPass);
        resp.put("courseDetailList", courseDetailList);
        return R.ok(resp);
    }

    private boolean isDriverTrainingAccessible(Long companyId, Long trainingId, String userId) {
        if (companyId == null || trainingId == null || StringUtils.isBlank(userId)) {
            return false;
        }
        HotTrainingVo training = hotTrainingService.queryById(trainingId);
        if (training == null || !Objects.equals(training.getCompanyId(), companyId)) {
            return false;
        }
        if (!Objects.equals(training.getIsEnabled(), 1L)) {
            return false;
        }
        HotTrainingParticipantBo participantBo = new HotTrainingParticipantBo();
        participantBo.setCompanyId(companyId);
        participantBo.setTrainingId(trainingId);
        participantBo.setUserId(userId);
        participantBo.setIsDeleted(0L);
        List<HotTrainingParticipantVo> participants = hotTrainingParticipantService.queryList(participantBo);
        if (participants == null || participants.isEmpty()) {
            return false;
        }
        if (Objects.equals(training.getIsMakeUp(), 1L)) {
            return true;
        }
        Date now = new Date();
        return training.getStartTime() != null
                && training.getEndTime() != null
                && training.getStartTime().compareTo(now) <= 0
                && training.getEndTime().compareTo(now) >= 0;
    }

    /**
     * 导出企业课程配置列表
     */
    //@SaCheckPermission("securityManagement:trainingCourseConfig:export")
    @Log(title = "企业课程配置", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    @Operation(summary = "导出企业课程配置列表")
    public void export(HotTrainingCourseConfigBo bo, HttpServletResponse response) {
        List<HotTrainingCourseConfigVo> list = hotTrainingCourseConfigService.queryList(bo);
        ExcelUtil.exportExcel(list, "企业课程配置", HotTrainingCourseConfigVo.class, response);
    }

    /**
     * 获取企业课程配置详细信息
     *
     * @param id 主键
     */
    //@SaCheckPermission("securityManagement:trainingCourseConfig:query")
    @GetMapping("/{id}")
    @Operation(summary = "获取企业课程配置详细信息")
    public R<HotTrainingCourseConfigVo> getInfo(@NotNull(message = "主键不能为空")
                                                @Parameter(name = "id", description = "主键", required = true, example = "1")
                                                @PathVariable Long id) {
        return R.ok(hotTrainingCourseConfigService.queryById(id));
    }

    /**
     * 新增企业课程配置
     */
    //@SaCheckPermission("securityManagement:trainingCourseConfig:add")
    @Log(title = "企业课程配置", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping()
    @Operation(summary = "新增企业课程配置")
    public R<Void> add(@Validated(AddGroup.class) @RequestBody HotTrainingCourseConfigBo bo) {
        return toAjax(hotTrainingCourseConfigService.insertByBo(bo));
    }

    /**
     * 修改企业课程配置
     */
    //@SaCheckPermission("securityManagement:trainingCourseConfig:edit")
    @Log(title = "企业课程配置", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping()
    @Operation(summary = "修改企业课程配置")
    public R<Void> edit(@Validated(EditGroup.class) @RequestBody HotTrainingCourseConfigBo bo) {
        return toAjax(hotTrainingCourseConfigService.updateByBo(bo));
    }

    //@SaCheckPermission("securityManagement:trainingCourseConfig:edit")
    @Log(title = "企业课程配置", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping("/updateStudyPhotoOssId")
    @Operation(summary = "修改企业课程配置学习照片")
    public R<Void> updateStudyPhotoOssId(
            @RequestParam Long participantId,
            @RequestParam Long trainingCourseId,
            @RequestParam Long studyPhotoOssId
    ) {
        return toAjax(hotTrainingParticipantService.updateStudyPhotoOssId(participantId, trainingCourseId, studyPhotoOssId));
    }

    /**
     * 删除企业课程配置
     *
     * @param ids 主键串
     */
    //@SaCheckPermission("securityManagement:trainingCourseConfig:remove")
    @Log(title = "企业课程配置", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    @Operation(summary = "删除企业课程配置")
    public R<Void> remove(@NotEmpty(message = "主键不能为空")
                          @Parameter(name = "ids", description = "主键串", required = true, example = "1,2,3")
                          @PathVariable Long[] ids) {
        return toAjax(hotTrainingCourseConfigService.deleteWithValidByIds(List.of(ids), true));
    }
}
