package jnpf.cultivate.v2.controller.web.promotion;

import io.swagger.v3.oas.annotations.Operation;
import jnpf.base.ActionResult;
import jnpf.base.vo.PageListVO;
import jnpf.cultivate.v2.service.V2CultivatePromotionService;
import jnpf.model.cultivate.CultivatePage;
import jnpf.model.cultivate.v2.promotion.req.FtbCultivatePromotionReq;
import jnpf.model.cultivate.v2.promotion.req.V2CultivatePositionExcludeReq;
import jnpf.model.cultivate.v2.promotion.req.V2CultivatePromotionCreateReq;
import jnpf.model.cultivate.v2.promotion.req.V2WebCultivateStudyMemberListReq;
import jnpf.model.cultivate.v2.promotion.vo.V2CultivatePositionVo;
import jnpf.model.cultivate.v2.promotion.vo.V2CultivatePromotionVo;
import jnpf.model.cultivate.v2.promotion.vo.V2WebCultivateStudyMemberListVo;
import jnpf.model.cultivate.v2.promotion.vo.WebCultivatePromotionListVo;
import jnpf.model.cultivate.v2.promotion.vo.UserPromotionDetailVo;
import jnpf.util.UserProvider;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
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;


/**
 * web学习地图模块
 *
 * @author xgl
 */
@Slf4j
@RestController
@RequestMapping("/v2/web/promotion")
public class V2CultivatePromotionWebController {
    /**
     * 服务对象
     */
    @Autowired
    private V2CultivatePromotionService promotionService;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * web获取学习地图列表
     *
     * @param dto  查询条件参数
     * @param page 分页参数
     * @return 返回分页后的学习地图列表
     */
    @GetMapping("/list")
    public ActionResult<PageListVO<WebCultivatePromotionListVo>> webList(FtbCultivatePromotionReq dto, CultivatePage page) {
        return ActionResult.success(promotionService.webList(page, dto));
    }

    /**
     * 新增学习地图
     *
     * @param req 学习地图创建请求参数，包含学习地图的基本信息
     * @return 返回操作结果，包含新增的学习地图ID
     */
    @PostMapping("/add")
    public ActionResult<String> add(@Validated @RequestBody V2CultivatePromotionCreateReq req) {
        String id = promotionService.add(req);
        if (StringUtils.isNotEmpty(id)) {
            promotionService.addMemberToPromotion(id, req);
        }
        return ActionResult.success("新增成功", id);
    }

    /**
     * 修改学习地图
     *
     * @param req 学习地图更新请求参数，包含学习地图的更新信息
     * @return 返回操作结果，包含更新的学习地图ID
     */
    @PutMapping("/update")
    public ActionResult<String> update(@Validated @RequestBody V2CultivatePromotionCreateReq req) {
        String tenantId = UserProvider.getUser().getTenantId();
        String lockKey = "PromotionCreate:" + tenantId + ":" + req.getId();
        executeWithLock(lockKey, () -> {
            String id = promotionService.update(req);
            if (StringUtils.isNotEmpty(id)) {
                promotionService.addMemberToPromotion(id, req);
            }
        });
        return ActionResult.success("修改成功", req.getId());
    }

    /**
     * 使用分布式锁执行操作
     *
     * @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("请不要重复提交");
        }
    }

    /**
     * 获取学习地图详情
     *
     * @param id 学习地图的唯一标识符
     * @return 返回指定学习地图的详细信息
     */
    @GetMapping("/{id}")
    public ActionResult<V2CultivatePromotionVo> get(@PathVariable("id") String id) {
        return ActionResult.success("成功", promotionService.get(id));
    }

    /**
     * 删除学习地图
     *
     * @param id 学习地图的唯一标识符
     * @return 返回操作结果，表示是否删除成功
     */
    @Operation(summary = "删除学习地图")
    @DeleteMapping("/{id}")
    public ActionResult<Boolean> delete(@PathVariable("id") String id) {
        promotionService.delete(id);
        return ActionResult.success();
    }

    /**
     * 根据地图主键ID获取地图成员信息
     *
     * @param req  查询条件参数
     * @param page 分页参数
     * @return 返回指定学习地图的成员列表
     */
    @GetMapping("/query-promotion-member")
    public ActionResult<V2WebCultivateStudyMemberListVo> queryPromotionUserList(V2WebCultivateStudyMemberListReq req, CultivatePage page) {
        return ActionResult.success("成功", promotionService.queryPromotionUserList(req, page));
    }

    /**
     * 查询在岗位学习中完成的配置的岗位&职级
     *
     * @param req 查询条件参数
     * @return 返回符合条件的岗位&职级列表
     */
    @GetMapping("/query-cultivate-position")
    public ActionResult<List<V2CultivatePositionVo>> queryCultivatePosition(V2CultivatePositionExcludeReq req) {
        return ActionResult.success("成功", promotionService.queryCultivatePosition(req));
    }

    /**
     * 根据用户ID和学习地图ID查询指定学习地图及分阶段岗位信息
     *
     * @param userId      用户ID
     * @param promotionId 学习地图ID
     * @return 用户学习地图详情，包含该学习地图的各阶段岗位信息
     */
    @GetMapping("/user-promotion-detail")
    public ActionResult<UserPromotionDetailVo> getUserPromotionDetail(@RequestParam("userId") String userId,
                                                                       @RequestParam("promotionId") String promotionId) {
        return ActionResult.success("成功", promotionService.getUserPromotionDetail(userId, promotionId));
    }

}
