package org.dromara.main.controller;

import jakarta.servlet.http.HttpServletResponse;
import cn.dev33.satoken.annotation.SaCheckPermission;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.domain.R;
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.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.dromara.demo.domain.dto.KaoshixingAnswerListRequest;
import org.dromara.demo.domain.dto.KaoshixingAutoLoginRequest;
import org.dromara.demo.domain.dto.KaoshixingExamListRequest;
import org.dromara.demo.domain.dto.KaoshixingRequest;
import org.dromara.demo.domain.dto.KaoshixingScoreListRequest;
import org.dromara.demo.domain.dto.KaoshixingUserExamListRequest;
import org.dromara.demo.service.impl.KaoshixingService;
import org.dromara.main.domain.bo.MainExamEvaluationBo;
import org.dromara.main.domain.bo.MainExamEvaluationSyncBo;
import org.dromara.main.domain.vo.MainExamApplyListVo;
import org.dromara.main.domain.vo.MainExamSyncEmployeeOptionVo;
import org.dromara.main.domain.vo.MainExamEvaluationVo;
import org.dromara.main.service.IMainExamEvaluationService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;

@Slf4j
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/main/examEvaluation")
public class MainExamEvaluationController extends BaseController {

    private final IMainExamEvaluationService examEvaluationService;
    private final KaoshixingService kaoshixingService;

    /**
     * 查询测评列表
     */
//    @SaCheckPermission("main:examEvaluation:list")
    @GetMapping("/list")
    public TableDataInfo<MainExamEvaluationVo> list(MainExamEvaluationBo bo, PageQuery pageQuery) {
        return examEvaluationService.queryPageList(bo, pageQuery);
    }

    @Log(title = "测评管理", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(MainExamEvaluationBo bo, HttpServletResponse response) {
        List<MainExamEvaluationVo> list = examEvaluationService.queryList(bo);
        ExcelUtil.exportExcel(list, "测评数据", MainExamEvaluationVo.class, response);
    }

//    @SaCheckPermission("main:examEvaluation:list")
    @GetMapping("/stats/participant")
    public R<Map<Long, Map<String, Long>>> participantStats(@RequestParam("ids") Collection<Long> ids) {
        return R.ok(examEvaluationService.getParticipantStats(ids));
    }

//    @SaCheckPermission("main:examEvaluation:list")
    @GetMapping("/sync/employeeOptions")
    public R<List<MainExamSyncEmployeeOptionVo>> syncEmployeeOptions() {
        return R.ok(examEvaluationService.getSyncEmployeeOptions());
    }

//    @SaCheckPermission("main:examEvaluation:sync")
    @Log(title = "同步至员工", businessType = BusinessType.UPDATE)
    @PostMapping("/sync/employees")
    public R<Void> syncToEmployees(@Validated @RequestBody MainExamEvaluationSyncBo bo) {
        return toAjax(examEvaluationService.syncToEmployees(bo));
    }

//    @SaCheckPermission("main:examEvaluation:list")
    @GetMapping("/applyList")
    public TableDataInfo<MainExamApplyListVo> applyList(@RequestParam("evaluationId") Long evaluationId,
                                                        @RequestParam(value = "keyword", required = false) String keyword,
                                                        PageQuery pageQuery) {
        return examEvaluationService.getApplyList(evaluationId, keyword, pageQuery);
    }

    @Log(title = "测评报名列表", businessType = BusinessType.EXPORT)
    @PostMapping("/applyList/export")
    public void exportApplyList(@RequestParam("evaluationId") Long evaluationId,
                                @RequestParam(value = "keyword", required = false) String keyword,
                                HttpServletResponse response) {
        List<MainExamApplyListVo> list = examEvaluationService.queryApplyList(evaluationId, keyword);
        ExcelUtil.exportExcel(list, "测评报名列表", MainExamApplyListVo.class, response);
    }

//    @SaCheckPermission("main:examEvaluation:edit")
    @Log(title = "移除测评报名", businessType = BusinessType.DELETE)
    @DeleteMapping("/apply/{applyId}")
    public R<Void> removeApply(@PathVariable("applyId") Long applyId) {
        return toAjax(examEvaluationService.removeApply(applyId));
    }

    /**
     * 获取测评详细信息
     */
//    @SaCheckPermission("main:examEvaluation:query")
    @GetMapping("/{id}")
    public R<MainExamEvaluationVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) {
        return R.ok(examEvaluationService.queryById(id));
    }

    /**
     * 新增测评
     */
//    @SaCheckPermission("main:examEvaluation:add")
    @Log(title = "测评管理", businessType = BusinessType.INSERT)
    @PostMapping()
    public R<Void> add(@Validated(AddGroup.class) @RequestBody MainExamEvaluationBo bo) {
        return toAjax(examEvaluationService.insertByBo(bo));
    }

    /**
     * 修改测评
     */
//    @SaCheckPermission("main:examEvaluation:edit")
    @Log(title = "测评管理", businessType = BusinessType.UPDATE)
    @PutMapping()
    public R<Void> edit(@Validated(EditGroup.class) @RequestBody MainExamEvaluationBo bo) {
        return toAjax(examEvaluationService.updateByBo(bo));
    }

    /**
     * 删除测评
     */
//    @SaCheckPermission("main:examEvaluation:remove")
    @Log(title = "测评管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public R<Void> remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] ids) {
        return toAjax(examEvaluationService.deleteWithValidByIds(Arrays.asList(ids), true));
    }

    /**
     * 批量更新状态
     */
//    @SaCheckPermission("main:examEvaluation:edit")
    @Log(title = "测评管理", businessType = BusinessType.UPDATE)
    @PutMapping("/updateStatus")
    public R<Void> updateStatus(@RequestBody List<Long> ids, @RequestParam String status) {
        return toAjax(examEvaluationService.updateStatus(ids, status));
    }

    /**
     * 单个更新状态
     */
//    @SaCheckPermission("main:examEvaluation:edit")
    @Log(title = "测评管理", businessType = BusinessType.UPDATE)
    @PutMapping("/status/{id}/{status}")
    public R<Void> updateSingleStatus(@NotNull(message = "主键不能为空") @PathVariable Long id,
                                      @PathVariable String status) {
        return toAjax(examEvaluationService.updateStatus(id, status));
    }

    /**
     * 同步第三方数据
     */
//    @SaCheckPermission("main:examEvaluation:sync")
    @Log(title = "测评管理", businessType = BusinessType.OTHER)
    @PostMapping("/sync")
    public R<Void> syncThirdPartyData() {
        return toAjax(examEvaluationService.syncThirdPartyData());
    }



//    @SaCheckPermission("main:evaluation:list")
    @ResponseBody
    @PostMapping("/exam-list")
    @Log(title = "获取第三方考试列表", businessType = BusinessType.OTHER)
    public R<String> getExamList(@RequestBody Map<String, Object> params) {
        // 写死的第三方凭证
        String appId = "631088";  // TODO: 后续改为配置
        String appKey = "605f5f51895f423195850957bb903a43"; // TODO: 后续改为配置

        // 构建请求参数
        KaoshixingExamListRequest request = new KaoshixingExamListRequest();
        request.setAppId(appId);
        request.setAppKey(appKey);
        request.setPage((Integer) params.getOrDefault("page", 1));

        // 转换日期格式：2026-01-01 -> 2026-01-01 00:00:00
        String examStartTime = (String) params.get("examStartTime");
        if (examStartTime != null && !examStartTime.isEmpty()) {
            request.setExamStartTime(examStartTime + " 00:00:00");
        }

        String examEndTime = (String) params.get("examEndTime");
        if (examEndTime != null && !examEndTime.isEmpty()) {
            request.setExamEndTime(examEndTime + " 23:59:59");
        }

        request.setExamIds((String) params.get("examIds"));
        request.setExpSeconds((Integer) params.getOrDefault("expSeconds", 300));

        // 调用第三方接口
        String result = kaoshixingService.fetchExamList(request);
        return R.ok(result);
    }


//    @SaCheckPermission("main:evaluation:list")
    @PostMapping("/score-list")
    @Log(title = "获取考生分数列表", businessType = BusinessType.OTHER)
    public R<String> getScoreList(@RequestBody Map<String, Object> params) {
        KaoshixingScoreListRequest request = new KaoshixingScoreListRequest();
        Object examInfoIdObj = params.get("examInfoId");
        if (examInfoIdObj == null) {
            return R.fail("examInfoId不能为空");
        }
        request.setExamInfoId(Long.valueOf(examInfoIdObj.toString()));
        request.setPage((Integer) params.getOrDefault("page", 1));
        return R.ok(kaoshixingService.fetchScoreList(request));
    }

    /**
     * 获取试卷试题列表 (603)
     */
//    @SaCheckPermission("main:evaluation:list")
    @PostMapping("/paper-questions")
    public R<String> getPaperQuestions(@RequestBody Map<String, Object> params) {
        KaoshixingRequest request = new KaoshixingRequest();
        request.setExamInfoId(Long.valueOf(params.get("examInfoId").toString()));
        return R.ok(kaoshixingService.fetchExamPaperQuestions(request));
    }

    /**
     * 获取考生答案列表 (604)
     */
//    @SaCheckPermission("main:evaluation:list")
    @PostMapping("/answer-list")
    public R<String> getAnswerList(@RequestBody Map<String, Object> params) {
        KaoshixingAnswerListRequest request = new KaoshixingAnswerListRequest();
        request.setExamInfoId(Long.valueOf(params.get("examInfoId").toString()));
        return R.ok(kaoshixingService.fetchAnswerList(request));
    }

    /**
     * 获取在线学习内容列表 (605)
     */
//    @SaCheckPermission("main:evaluation:list")
    @PostMapping("/learning-contents")
    public R<String> getLearningContents(@RequestBody Map<String, Object> params) {
        KaoshixingExamListRequest request = new KaoshixingExamListRequest();
        request.setPage((Integer) params.getOrDefault("page", 1));
        return R.ok(kaoshixingService.fetchLearningContents(request));
    }

    /**
     * 获取考生可见考试和考试结果整合列表 (702)
     */
//    @SaCheckPermission("main:evaluation:list")
    @PostMapping("/user-exam-list")
    public R<String> getUserExamList(@RequestBody Map<String, Object> params) {
        Object userIdObj = params.get("user_id");
        if (userIdObj == null || userIdObj.toString().isBlank()) {
            return R.fail("user_id不能为空");
        }

        KaoshixingUserExamListRequest request = new KaoshixingUserExamListRequest();
        request.setUserId(userIdObj.toString());
        request.setPage((Integer) params.getOrDefault("page", 1));
        return R.ok(kaoshixingService.fetchUserExamList(request));
    }

    /**
     * 小程序专用：考生静默登录（action_id=203）
     * 流程：先尝试203静默登录；若用户不存在，自动以201注册并登录。
     * 成功后返回考试星跳转url，前端用web-view打开即可完成登录进入考试。
     *
     * @param params user_id      考生唯一标识（必填，通常用 studentId）
     *               user_name    考生姓名（首次注册时必填）
     *               department   部门（首次注册时必填，缺省传 "学员"）
     *               custom_url   登录后跳转地址（可选，*.kaoshixing.com 域名）
     */
    @PostMapping("/silent-login")
    @Log(title = "考试星静默登录", businessType = BusinessType.OTHER)
    public R<Map<String, Object>> silentLogin(@RequestBody Map<String, Object> params) {
        String userId = (String) params.get("user_id");
        if (userId == null || userId.isBlank()) {
            return R.fail("user_id不能为空");
        }
        String userName  = (String) params.getOrDefault("user_name",  "学员");
        String department = (String) params.getOrDefault("department", "学员");
        String customUrl  = (String) params.get("custom_url");

        KaoshixingAutoLoginRequest req = new KaoshixingAutoLoginRequest();
        req.setUserId(userId);
        req.setUserName(userName);
        req.setDepartment(department);
        req.setCustomUrl(customUrl);

        try {
            String resp = kaoshixingService.fetchAutoLogin(req);
            // 解析考试星返回的url字段
            com.fasterxml.jackson.databind.ObjectMapper mapper =
                new com.fasterxml.jackson.databind.ObjectMapper();
            com.fasterxml.jackson.databind.JsonNode root = mapper.readTree(resp);

            int code = root.path("code").asInt(0);
            if (code != 10000) {
                String msg = root.path("msg").asText("登录失败");
                return R.fail(msg);
            }

            String url = root.path("url").asText(null);
            if (url == null || url.isBlank()) {
                return R.fail("考试星未返回跳转链接");
            }

            Map<String, Object> data = new java.util.HashMap<>();
            data.put("url", url);
            return R.ok(data);
        } catch (Exception e) {
            log.error("考试星静默登录失败", e);
            return R.fail("登录失败：" + e.getMessage());
        }
    }
}

