package com.ycwl.basic.service.mobile;

import com.ycwl.basic.biz.OrderBiz;
import com.ycwl.basic.integration.common.manager.ScenicConfigManager;
import com.ycwl.basic.model.mobile.order.IsBuyRespVO;
import com.ycwl.basic.model.mobile.video.dto.VideoViewPermissionDTO;
import com.ycwl.basic.model.pc.task.entity.TaskEntity;
import com.ycwl.basic.model.pc.video.entity.UserVideoViewEntity;
import com.ycwl.basic.model.pc.video.entity.VideoEntity;
import com.ycwl.basic.repository.ScenicRepository;
import com.ycwl.basic.repository.UserVideoViewRepository;
import com.ycwl.basic.repository.VideoRepository;
import com.ycwl.basic.repository.VideoTaskRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.Map;

/**
 * 视频查看权限服务
 * 处理用户查看vlog视频的权限控制和记录
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class VideoViewPermissionService {

    private final UserVideoViewRepository userVideoViewRepository;
    private final VideoRepository videoRepository;
    private final ScenicRepository scenicRepository;
    private final OrderBiz orderBiz;
    private final VideoTaskRepository videoTaskRepository;

    /**
     * 检查并记录用户查看视频
     *
     * @param userId  用户ID
     * @param videoId 视频ID
     * @return 查看权限信息
     */
    public VideoViewPermissionDTO checkAndRecordView(Long userId, Long videoId) {
        try {
            // 获取视频信息
            VideoEntity video = videoRepository.getVideo(videoId);
            if (video == null) {
                log.warn("视频不存在: videoId={}", videoId);
                return createErrorPermission("视频不存在");
            }

            Long scenicId = video.getScenicId();
            if (scenicId == null) {
                log.warn("视频缺少景区信息: videoId={}", videoId);
                return createErrorPermission("视频信息不完整");
            }

            // 检查用户是否已购买
            IsBuyRespVO buy = orderBiz.isBuy(scenicId, userId, video.getFaceId(), 0, videoId);
            if (buy != null && (buy.isBuy() || buy.isFree())) {
                // 已购买，不限制查看
                log.debug("用户已购买视频，无查看限制: userId={}, videoId={}", userId, videoId);
                return VideoViewPermissionDTO.createUnlimitedPermission(0);
            }

            // 使用分布式锁执行查看记录操作
            VideoViewPermissionDTO result = userVideoViewRepository.executeWithLock(userId, videoId, () -> {
                try {
                    // 获取景区配置
                    ScenicConfigManager scenicConfig = scenicRepository.getScenicConfigManager(scenicId);

                    // 解析配置参数
                    Integer vlogViewLimit = scenicConfig.getInteger("vlog_view_limit", 0);
                    Integer vlogTimeLimit = scenicConfig.getInteger("vlog_time_limit", 0);

                    // 获取用户查看记录
                    UserVideoViewEntity viewRecord = userVideoViewRepository.getViewRecord(userId, videoId);
                    int currentViewCount = 0;

                    if (viewRecord == null) {
                        // 首次查看，创建记录
                        viewRecord = userVideoViewRepository.createViewRecord(userId, videoId, scenicId);
                        currentViewCount = 1;
                    } else {
                        // 增加查看次数
                        currentViewCount = viewRecord.getViewCount() + 1;
                        userVideoViewRepository.updateViewCount(userId, videoId, currentViewCount);
                    }

                    // 根据配置判断权限
                    return calculatePermission(currentViewCount, vlogViewLimit, vlogTimeLimit);

                } catch (Exception e) {
                    log.error("检查视频查看权限失败: userId={}, videoId={}", userId, videoId, e);
                    return createErrorPermission("系统异常，请稍后重试");
                }
            });

            return result != null ? result : createErrorPermission("获取权限信息失败");

        } catch (Exception e) {
            log.error("检查并记录视频查看失败: userId={}, videoId={}", userId, videoId, e);
            return createErrorPermission("系统异常，请稍后重试");
        }
    }

    /**
     * 仅检查用户查看权限，不记录查看次数
     *
     * @param userId  用户ID
     * @param videoId 视频ID
     * @return 查看权限信息
     */
    public VideoViewPermissionDTO checkViewPermission(Long userId, Long videoId) {
        try {
            // 获取视频信息
            VideoEntity video = videoRepository.getVideo(videoId);
            if (video == null) {
                return createErrorPermission("视频不存在");
            }

            Long scenicId = video.getScenicId();
            if (scenicId == null) {
                return createErrorPermission("视频信息不完整");
            }

            // 检查用户是否已购买
            IsBuyRespVO buy = orderBiz.isBuy(scenicId, userId, video.getFaceId(), 0, videoId);
            if (buy != null && (buy.isBuy() || buy.isFree())) {
                // 已购买，不限制查看
                log.debug("用户已购买视频，无查看限制: userId={}, videoId={}", userId, videoId);
                return VideoViewPermissionDTO.createUnlimitedPermission(0);
            }

            // 获取景区配置
            ScenicConfigManager scenicConfig = scenicRepository.getScenicConfigManager(scenicId);

            // 解析配置参数
            Integer vlogViewLimit = scenicConfig.getInteger("vlog_view_limit", 0);
            Integer vlogTimeLimit = scenicConfig.getInteger("vlog_time_limit", 0);

            // 获取用户查看记录
            UserVideoViewEntity viewRecord = userVideoViewRepository.getViewRecord(userId, videoId);
            int currentViewCount = viewRecord != null ? viewRecord.getViewCount() : 0;

            // 根据配置判断权限
            return calculatePermission(currentViewCount, vlogViewLimit, vlogTimeLimit);

        } catch (Exception e) {
            log.error("检查视频查看权限失败: userId={}, videoId={}", userId, videoId, e);
            return createErrorPermission("系统异常，请稍后重试");
        }
    }

    /**
     * 根据配置计算查看权限
     *
     * @param currentViewCount 当前查看次数
     * @param vlogViewLimit    视频查看次数限制
     * @param vlogTimeLimit    时间限制（秒）
     * @return 查看权限信息
     */
    private VideoViewPermissionDTO calculatePermission(int currentViewCount, Integer vlogViewLimit, Integer vlogTimeLimit) {
        // 1. 两个值都为0或负数则为不限制
        if ((vlogViewLimit == null || vlogViewLimit <= 0) && (vlogTimeLimit == null || vlogTimeLimit <= 0)) {
            return VideoViewPermissionDTO.createUnlimitedPermission(currentViewCount);
        }

        // 2. vlog_view_limit为0则仅通过vlog_time_limit限制
        if (vlogViewLimit == null || vlogViewLimit <= 0) {
            if (vlogTimeLimit != null && vlogTimeLimit > 0) {
                return VideoViewPermissionDTO.createTimeLimitPermission(currentViewCount, 0, vlogTimeLimit);
            } else {
                return VideoViewPermissionDTO.createUnlimitedPermission(currentViewCount);
            }
        }

        // 3. vlog_view_limit不为0，判断是否超过次数限制
        if (currentViewCount <= vlogViewLimit) {
            // 未超过次数限制，可完整查看
            return VideoViewPermissionDTO.createFullViewPermission(currentViewCount, vlogViewLimit);
        } else {
            // 已超过次数限制
            if (vlogTimeLimit == null || vlogTimeLimit <= 0) {
                // 4. vlog_time_limit为0就不允许查看了
                return VideoViewPermissionDTO.createNoPermission(currentViewCount, vlogViewLimit);
            } else {
                // 通过时间限制查看
                return VideoViewPermissionDTO.createTimeLimitPermission(currentViewCount, vlogViewLimit, vlogTimeLimit);
            }
        }
    }

    /**
     * 解析配置值
     *
     * @param config       配置Map
     * @param key         配置键
     * @param defaultValue 默认值
     * @return 解析后的值
     */
    private Integer parseConfigValue(Map<String, Object> config, String key, Integer defaultValue) {
        if (config == null || !config.containsKey(key)) {
            return defaultValue;
        }

        Object value = config.get(key);
        if (value instanceof Number) {
            return ((Number) value).intValue();
        } else if (value instanceof String) {
            try {
                return Integer.valueOf((String) value);
            } catch (NumberFormatException e) {
                log.warn("配置值解析失败: key={}, value={}, 使用默认值: {}", key, value, defaultValue);
                return defaultValue;
            }
        }

        return defaultValue;
    }

    /**
     * 创建错误权限对象
     *
     * @param message 错误消息
     * @return 错误权限对象
     */
    private VideoViewPermissionDTO createErrorPermission(String message) {
        VideoViewPermissionDTO dto = new VideoViewPermissionDTO();
        dto.setCanView(false);
        dto.setMessage(message);
        return dto;
    }
}