package jnpf.cultivate.v2.controller.app.course;

import jnpf.base.ActionResult;
import jnpf.base.UserInfo;
import jnpf.base.vo.PageListVO;
import jnpf.cultivate.service.CultivateCourseMsgService;
import jnpf.cultivate.v2.service.FtbCultivateCourseSettingGlobalService;
import jnpf.cultivate.v2.service.FtbCultivateLabelService;
import jnpf.cultivate.v2.service.V2CultivateCourseAppService;
import jnpf.cultivate.v2.util.CultivateCourseStudyUtil;
import jnpf.model.cultivate.CultivatePage;
import jnpf.model.cultivate.po.FtbCultivateCourseSettingGlobal;
import jnpf.model.cultivate.v2.course.vo.app.*;
import jnpf.model.cultivate.v2.label.vo.FtbCultivateLabelVo;
import jnpf.model.cultivate.v2.position.req.V2CultivateCommonCourseForAppReq;
import jnpf.model.cultivate.v2.position.req.V2MyCultivateCommonCourseForAppReq;
import jnpf.model.cultivate.vo.course.app.FtbCultivateCourseMsgForAppVO;
import jnpf.util.StringUtil;
import jnpf.util.UserProvider;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * app端课程模块
 *
 * @author xgl
 * @date 2026-01-27 14:04:01
 */
@Slf4j
@RestController
@RequestMapping("/v2/app/course")
public class V2CultivateCourseAppController {


    @Autowired
    private V2CultivateCourseAppService v2CultivateCourseAppService;

    @Autowired
    private FtbCultivateCourseSettingGlobalService ftbCultivateCourseSettingGlobalService;

    @Autowired
    private FtbCultivateLabelService ftbCultivateLabelService;


    @Autowired
    private CultivateCourseStudyUtil cultivateCourseStudyUtil;

    @Autowired
    private CultivateCourseMsgService cultivateCourseMsgService;


    @Autowired
    private RedisTemplate redisTemplate;


    /**
     * 我的课程详情（带学习进度）
     *
     * @param dto 请求参数
     * @return {@link ActionResult}<{@link V2CourseDetailsAppVO}>
     */
    @GetMapping("/course-details")
    public ActionResult<V2CourseDetailsAppVO> courseDetails(@Validated V2CourseAppDto dto) {
        V2CourseDetailsAppVO vo = v2CultivateCourseAppService.courseDetails(dto);
        cultivateCourseStudyUtil.checkCourseComplete(dto, vo.getState());
        return ActionResult.success("", vo);
    }

    /**
     * 课程大纲(带学习进度)
     *
     * @param dto 请求参数
     * @return {@link ActionResult}<{@link V2CourseOutlineAppVo}>
     */
    @GetMapping("/course-outline")
    public ActionResult<V2CourseOutlineAppVo> courseOutline(@Validated V2CourseAppDto dto) {
        return ActionResult.success("", v2CultivateCourseAppService.courseOutline(dto.getCourseId(), dto.getUserId()));
    }


    /**
     * App课程学习模块-章节详情
     *
     * @param id 章节id,必填
     */
    @GetMapping("/chapter-details/{id}/{userId}")
    public ActionResult<V2ChapterAppDetails> chapterDetails(@PathVariable("id") String id, @PathVariable("userId") String userId) {
        return ActionResult.success(v2CultivateCourseAppService.chapterDetails(id, userId));
    }


    /**
     * App课程学习模块-完成章节学习
     *
     * @param chapterStudyDTO 章节学习参数
     * @return {@link ActionResult}
     */
    @PostMapping("/chapter-study")
    public ActionResult<Void> chapterStudy(@Validated @RequestBody V2ChapterStudyVo chapterStudyDTO) {
        UserInfo userInfo = UserProvider.getUser();
        String lockKey = "chapterStudy:" + userInfo.getTenantId() + ":" + userInfo.getUserId() + ":" + chapterStudyDTO.getCourseId() + ":" + chapterStudyDTO.getChapterId();
        executeWithLock(lockKey, () -> v2CultivateCourseAppService.chapterStudy(chapterStudyDTO));
        return ActionResult.success();
    }

    /**
     * App课程学习模块-时长记录
     *
     * @param chapterStudyDTO 章节学习参数
     * @return {@link ActionResult}
     */
    @PostMapping("/duration-record")
    public ActionResult<Void> durationRecord(@Validated @RequestBody V2ChapterStudyVo chapterStudyDTO) {
        if (chapterStudyDTO.getDuration() == null || chapterStudyDTO.getDuration() <= 0) {
            return ActionResult.success();
        }
        UserInfo userInfo = UserProvider.getUser();
        String lockKey = "duration-record:" + userInfo.getTenantId() + ":" + userInfo.getUserId() + ":" + chapterStudyDTO.getCourseId() + ":" + chapterStudyDTO.getChapterId();
        executeWithLock(lockKey, () -> v2CultivateCourseAppService.durationRecord(chapterStudyDTO));
        return ActionResult.success();
    }

    /**
     * 使用分布式锁执行操作
     *
     * @param lockKey 锁的key
     * @param action  要执行的操作
     */
    private void executeWithLock(String lockKey, Runnable action) {
        String lockValue = UUID.randomUUID().toString();
        Boolean locked = redisTemplate.opsForValue().setIfAbsent(lockKey, lockValue, 3, TimeUnit.SECONDS);
        if (Boolean.TRUE.equals(locked)) {
            try {
                action.run();
            } catch (Exception e) {
                log.error("执行操作失败，lockKey: {}", lockKey, e);
                throw e;
            } finally {
                // 安全的释放锁：只有当锁的值与当前值匹配时才删除
                Object currentValue = redisTemplate.opsForValue().get(lockKey);
                if (lockValue.equals(currentValue)) {
                    redisTemplate.delete(lockKey);
                }
            }
        } else {
            log.warn("重复提交被拦截，lockKey: {}", lockKey);
            throw new RuntimeException("请不要重复提交");
        }
    }

    /**
     * 获取课程规则全局配置
     *
     * @return {@link ActionResult}<{@link FtbCultivateCourseSettingGlobal}>
     */
    @GetMapping("/global-setting")
    public ActionResult<FtbCultivateCourseSettingGlobal> globalSetting() {
        return ActionResult.success(ftbCultivateCourseSettingGlobalService.getInfo());
    }


    /**
     * App课程学习模块-增加当前课程浏览量
     *
     * @param courseId 课程主键id,必填
     * @return {@link ActionResult}
     */
    @PutMapping("/course-browsing/{id}")
    public ActionResult<Void> courseBrowsing(@PathVariable("id") String courseId) {
        v2CultivateCourseAppService.courseBrowsing(courseId);
        return ActionResult.success();
    }


    /**
     * 我的课程-通用课程标签列表
     */
    @GetMapping("/common-course-label-list")
    public ActionResult<List<FtbCultivateLabelVo>> commonCourseLabelList(V2CultivateCommonCourseForAppReq req) {
        return ActionResult.success("成功", ftbCultivateLabelService.commonCourseLabelList(req));
    }


    /**
     * 我的课程-通用课程列表
     */
    @GetMapping("/common-course-list")
    public ActionResult<PageListVO<AppCommonCourseSimpleVo>> commonCourseList(V2MyCultivateCommonCourseForAppReq dto, CultivatePage page) {
        return ActionResult.success(CultivatePage.coverPageList(v2CultivateCourseAppService.commonCourseList(dto, page)));
    }


    /**
     * 我的课程-通用课程-（总课程/已经完成课程）
     */
    @GetMapping("/common-course-count")
    public ActionResult<CommonCourseCountVo> commonCourseCount(V2MyCultivateCommonCourseForAppReq dto) {
        return ActionResult.success(v2CultivateCourseAppService.commonCourseCount(dto));
    }

    /**
     * 最后一次学习的课程
     */
    @GetMapping("/query-last-study-course")
    public ActionResult<LastStudyCourseVo> queryLastStudyCourse() {
        LastStudyCourseVo vo = v2CultivateCourseAppService.queryLastStudyCourse();
        if (StringUtil.isEmpty(vo.getCourseId())) {
            return ActionResult.success("成功", null);
        }
        if (StringUtil.isNotEmpty(vo.getCourseId())) {
            V2CourseOutlineAppVo courseOutline = v2CultivateCourseAppService.courseOutline(vo.getCourseId(), UserProvider.getUser().getUserId());
            if (courseOutline != null) {
                vo.setChapterTotalNumber(courseOutline.getChapterTotalNumber());
                vo.setChapterFinishedNumber(courseOutline.getChapterFinishedNumber());
                vo.setCoverUrl(courseOutline.getCoverUrl());
                vo.setCourseName(courseOutline.getCourseName());
            }
        }
        return ActionResult.success("成功", vo);
    }

    /**
     * App查询用户未读信息列表
     *
     * @return {@link ActionResult}<{@link List<FtbCultivateCourseMsgForAppVO>}>
     */
    @GetMapping("/queryUserUnreadMsg")
    public ActionResult<List<FtbCultivateCourseMsgForAppVO>> queryUserUnreadMsg(@RequestParam("courseId") String courseId) {
        return ActionResult.success(cultivateCourseMsgService.queryUserUnreadMsgV2(courseId));
    }

    /**
     * App更新用户已读信息
     *
     * @param courseId 课程id
     * @return {@link ActionResult}<{@link Boolean}>
     */
    @PutMapping("/updateInfoByMsgId/{courseId}")
    public ActionResult<Boolean> updateInfoByMsgId(@PathVariable("courseId") String courseId) {
        cultivateCourseMsgService.updateInfoByMsgIdV2(courseId);
        return ActionResult.success("", true);
    }
}
