package com.dora.service.impl;

import com.dora.dto.ApiResponse;
import com.dora.dto.AdminContentAuditDto;
import com.dora.dto.VodDto;
import com.dora.mapper.ContentAuditMapper;
import com.dora.service.AdminContentAuditService;
import com.dora.service.AdminAuthService;
import com.dora.service.VodService;
import com.dora.config.VodConfig;
import com.dora.util.AdminSecurityUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.vod.model.v20170321.GetVideoPlayAuthRequest;
import com.aliyuncs.vod.model.v20170321.GetVideoPlayAuthResponse;
import com.aliyuncs.profile.DefaultProfile;

/**
 * 管理员内容审核服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AdminContentAuditServiceImpl implements AdminContentAuditService {

    private final ContentAuditMapper contentAuditMapper;
    private final AdminAuthService adminAuthService;
    private final VodService vodService;
    private final VodConfig vodConfig;

    @Override
    public ApiResponse<AdminContentAuditDto.ContentAuditListResponse> getContentAuditList(AdminContentAuditDto.ContentAuditListRequest request) {
        try {
            Long adminId = AdminSecurityUtil.getCurrentAdminId();
            
            // 验证管理员权限
            if (!adminAuthService.hasPermission(adminId, "content:audit")) {
                return ApiResponse.error(403, "权限不足");
            }

            // 参数校验
            if (request.getPage() == null || request.getPage() < 1) {
                request.setPage(1);
            }
            if (request.getSize() == null || request.getSize() < 1 || request.getSize() > 100) {
                request.setSize(10);
            }

            // 计算偏移量
            Long offset = (long) (request.getPage() - 1) * request.getSize();
            Long limit = (long) request.getSize();

            // 查询总数
            Long total = contentAuditMapper.countContentAuditList(request);
            if (total == null || total == 0) {
                AdminContentAuditDto.ContentAuditListResponse response = new AdminContentAuditDto.ContentAuditListResponse();
                response.setTotal(0L);
                response.setPage((long) request.getPage());
                response.setSize((long) request.getSize());
                response.setRecords(List.of());
                return ApiResponse.success(response);
            }

            // 查询列表
            List<AdminContentAuditDto.ContentAuditItem> records = contentAuditMapper.selectContentAuditList(request, offset, limit);

            // 构建响应
            AdminContentAuditDto.ContentAuditListResponse response = new AdminContentAuditDto.ContentAuditListResponse();
            response.setTotal(total);
            response.setPage((long) request.getPage());
            response.setSize((long) request.getSize());
            response.setRecords(records);

            log.info("管理员{}获取内容审核列表成功，总数：{}", adminId, total);
            return ApiResponse.success(response);

        } catch (Exception e) {
            log.error("获取内容审核列表失败", e);
            return ApiResponse.error("获取内容审核列表失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional
    public ApiResponse<String> auditContent(AdminContentAuditDto.ContentAuditRequest request) {
        try {
            Long adminId = AdminSecurityUtil.getCurrentAdminId();
            
            // 验证管理员权限
            if (!adminAuthService.hasPermission(adminId, "content:audit")) {
                return ApiResponse.error(403, "权限不足");
            }

            // 参数校验
            if (request.getAuditStatus() == null || (!request.getAuditStatus().equals(1) && !request.getAuditStatus().equals(2))) {
                return ApiResponse.error(400, "审核状态只能是1（通过）或2（拒绝）");
            }

            if (request.getAuditStatus().equals(2) && (request.getRejectReason() == null || request.getRejectReason().trim().isEmpty())) {
                return ApiResponse.error(400, "拒绝审核时必须填写拒绝原因");
            }

            // 根据内容类型执行审核
            int affected = 0;
            switch (request.getContentType().toLowerCase()) {
                case "video":
                    affected = contentAuditMapper.auditVideo(
                        request.getContentId(), 
                        request.getAuditStatus(), 
                        request.getRejectReason(), 
                        adminId
                    );
                    break;
                case "workflow":
                    affected = contentAuditMapper.auditWorkflow(
                        request.getContentId(), 
                        request.getAuditStatus(), 
                        request.getRejectReason(), 
                        adminId
                    );
                    break;
                case "course":
                    affected = contentAuditMapper.auditCourse(
                        request.getContentId(), 
                        request.getAuditStatus(), 
                        request.getRejectReason(), 
                        adminId
                    );
                    break;
                default:
                    return ApiResponse.error(400, "不支持的内容类型：" + request.getContentType());
            }

            if (affected <= 0) {
                return ApiResponse.error(400, "审核失败，内容不存在或已被审核");
            }

            String statusText = request.getAuditStatus().equals(1) ? "通过" : "拒绝";
            log.info("管理员{}审核{}内容{}：状态={}, 原因={}", 
                adminId, request.getContentType(), request.getContentId(), statusText, request.getRejectReason());
            
            return ApiResponse.success("审核" + statusText + "成功");

        } catch (Exception e) {
            log.error("审核内容失败", e);
            return ApiResponse.error("审核内容失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional
    public ApiResponse<String> batchAuditContent(AdminContentAuditDto.BatchAuditRequest request) {
        try {
            Long adminId = AdminSecurityUtil.getCurrentAdminId();
            
            // 验证管理员权限
            if (!adminAuthService.hasPermission(adminId, "content:audit")) {
                return ApiResponse.error(403, "权限不足");
            }

            if (request.getAuditItems() == null || request.getAuditItems().isEmpty()) {
                return ApiResponse.error(400, "审核项目不能为空");
            }

            if (request.getAuditItems().size() > 50) {
                return ApiResponse.error(400, "批量审核项目数量不能超过50个");
            }

            int successCount = 0;
            int failCount = 0;
            StringBuilder failMessages = new StringBuilder();

            // 逐个审核
            for (AdminContentAuditDto.ContentAuditRequest auditRequest : request.getAuditItems()) {
                try {
                    ApiResponse<String> result = auditContent(auditRequest);
                    if (result.getCode() == 200) {
                        successCount++;
                    } else {
                        failCount++;
                        failMessages.append(String.format("内容%s:%s; ", auditRequest.getContentId(), result.getMessage()));
                    }
                } catch (Exception e) {
                    failCount++;
                    failMessages.append(String.format("内容%s:系统错误; ", auditRequest.getContentId()));
                    log.warn("批量审核失败：内容ID={}，错误：{}", auditRequest.getContentId(), e.getMessage());
                }
            }

            String message = String.format("批量审核完成，成功：%d，失败：%d", successCount, failCount);
            if (failCount > 0) {
                message += "，失败原因：" + failMessages.toString();
            }

            log.info("管理员{}批量审核内容完成，成功：{}，失败：{}", adminId, successCount, failCount);
            return ApiResponse.success(message);

        } catch (Exception e) {
            log.error("批量审核内容失败", e);
            return ApiResponse.error("批量审核内容失败：" + e.getMessage());
        }
    }

    @Override
    public ApiResponse<AdminContentAuditDto.AuditStatistics> getAuditStatistics() {
        try {
            Long adminId = AdminSecurityUtil.getCurrentAdminId();
            
            // 验证管理员权限
            if (!adminAuthService.hasPermission(adminId, "content:read")) {
                return ApiResponse.error(403, "权限不足");
            }

            AdminContentAuditDto.AuditStatistics statistics = contentAuditMapper.selectAuditStatistics();
            if (statistics == null) {
                statistics = new AdminContentAuditDto.AuditStatistics();
                statistics.setPendingTotal(0L);
                statistics.setPendingVideos(0L);
                statistics.setPendingWorkflows(0L);
                statistics.setPendingCourses(0L);
                statistics.setTodayApprovedTotal(0L);
                statistics.setTodayRejectedTotal(0L);
            }

            return ApiResponse.success(statistics);

        } catch (Exception e) {
            log.error("获取审核统计失败", e);
            return ApiResponse.error("获取审核统计失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional
    public ApiResponse<String> updateCourseProperties(AdminContentAuditDto.CoursePropertiesUpdateRequest request) {
        try {
            Long adminId = AdminSecurityUtil.getCurrentAdminId();
            
            // 验证管理员权限
            if (!adminAuthService.hasPermission(adminId, "content:audit")) {
                return ApiResponse.error(403, "权限不足");
            }

            // 参数校验
            if (request.getIsFree() != null && (request.getIsFree() < 0 || request.getIsFree() > 1)) {
                return ApiResponse.error(400, "isFree参数只能是0或1");
            }

            if (request.getLevel() != null && (request.getLevel() < 0 || request.getLevel() > 3)) {
                return ApiResponse.error(400, "level参数只能是0-3之间的值");
            }

            // 更新课程属性
            int affected = contentAuditMapper.updateCourseProperties(
                request.getCourseId(),
                request.getIsFree(),
                request.getLevel(),
                request.getCategory()
            );

            if (affected <= 0) {
                return ApiResponse.error(400, "课程不存在或更新失败");
            }

            log.info("管理员{}更新课程{}属性成功", adminId, request.getCourseId());
            return ApiResponse.success("课程属性更新成功");

        } catch (Exception e) {
            log.error("更新课程属性失败", e);
            return ApiResponse.error("更新课程属性失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional
    public ApiResponse<String> updateWorkflowProperties(AdminContentAuditDto.WorkflowPropertiesUpdateRequest request) {
        try {
            Long adminId = AdminSecurityUtil.getCurrentAdminId();
            
            // 验证管理员权限
            if (!adminAuthService.hasPermission(adminId, "content:audit")) {
                return ApiResponse.error(403, "权限不足");
            }

            // 参数校验
            if (request.getIsFree() != null && (request.getIsFree() < 0 || request.getIsFree() > 1)) {
                return ApiResponse.error(400, "isFree参数只能是0或1");
            }

            if (request.getFullAccessRole() != null && (request.getFullAccessRole() < 0 || request.getFullAccessRole() > 3)) {
                return ApiResponse.error(400, "fullAccessRole参数只能是0-3之间的值");
            }

            if (request.getCopyAccessRole() != null && (request.getCopyAccessRole() < 0 || request.getCopyAccessRole() > 3)) {
                return ApiResponse.error(400, "copyAccessRole参数只能是0-3之间的值");
            }

            if (request.getRating() != null && (request.getRating() < 1 || request.getRating() > 5)) {
                return ApiResponse.error(400, "rating参数只能是1-5之间的值");
            }

            // 更新工作流属性
            int affected = contentAuditMapper.updateWorkflowProperties(
                request.getWorkflowId(),
                request.getIsFree(),
                request.getFullAccessRole(),
                request.getCopyAccessRole(),
                request.getCategory(),
                request.getRating()
            );

            if (affected <= 0) {
                return ApiResponse.error(400, "工作流不存在或更新失败");
            }

            log.info("管理员{}更新工作流{}属性成功", adminId, request.getWorkflowId());
            return ApiResponse.success("工作流属性更新成功");

        } catch (Exception e) {
            log.error("更新工作流属性失败", e);
            return ApiResponse.error("更新工作流属性失败：" + e.getMessage());
        }
    }

    @Override
    public ApiResponse<Object> getVideoPlayAuth(AdminContentAuditDto.VideoPlayAuthRequest request) {
        try {
            Long adminId = AdminSecurityUtil.getCurrentAdminId();
            
            // 验证管理员权限
            if (!adminAuthService.hasPermission(adminId, "content:audit")) {
                return ApiResponse.error(403, "权限不足");
            }

            // 参数校验
            if (request.getVodVideoId() == null || request.getVodVideoId().trim().isEmpty()) {
                return ApiResponse.error(400, "阿里云视频ID不能为空");
            }

            try {
                // 创建播放凭证请求对象
                VodDto.GetVideoPlayAuthRequest vodRequest = new VodDto.GetVideoPlayAuthRequest();
                vodRequest.setVideoId(request.getVodVideoId());
                vodRequest.setCourseId(request.getCourseId());
                vodRequest.setChapterId(request.getChapterId());
                vodRequest.setAuthInfoTimeout(3600L); // 设置播放凭证有效期为1小时
                
                // 调用VodService获取播放凭证
                // 注意：这里我们需要绕过权限验证，因为管理员审核时需要播放视频
                // 我们直接调用阿里云VOD API获取播放凭证
                
                // 创建阿里云VOD客户端
                DefaultAcsClient client = createVodClient();
                
                // 调用GetVideoPlayAuth接口
                GetVideoPlayAuthRequest aliyunRequest = new GetVideoPlayAuthRequest();
                aliyunRequest.setVideoId(request.getVodVideoId());
                aliyunRequest.setAuthInfoTimeout(3600L);
                
                GetVideoPlayAuthResponse response = client.getAcsResponse(aliyunRequest);
                
                // 构建响应对象
                VodDto.VideoPlayAuthResponse result = new VodDto.VideoPlayAuthResponse();
                result.setPlayAuth(response.getPlayAuth());
                result.setRequestId(response.getRequestId());
                
                // 设置视频元信息
                if (response.getVideoMeta() != null) {
                    VodDto.VideoMeta videoMeta = new VodDto.VideoMeta();
                    videoMeta.setVideoId(response.getVideoMeta().getVideoId());
                    videoMeta.setTitle(response.getVideoMeta().getTitle());
                    videoMeta.setDuration(response.getVideoMeta().getDuration());
                    videoMeta.setCoverURL(response.getVideoMeta().getCoverURL());
                    videoMeta.setStatus(response.getVideoMeta().getStatus());
                    result.setVideoMeta(videoMeta);
                }
                
                log.info("管理员{}获取视频{}播放凭证成功", adminId, request.getVodVideoId());
                return ApiResponse.success(result);
                
            } catch (Exception e) {
                log.error("获取视频播放凭证失败", e);
                return ApiResponse.error("获取视频播放凭证失败：" + e.getMessage());
            }

        } catch (Exception e) {
            log.error("管理员获取视频播放凭证失败", e);
            return ApiResponse.error("管理员获取视频播放凭证失败：" + e.getMessage());
        }
    }
    
    /**
     * 创建阿里云VOD客户端
     */
    private DefaultAcsClient createVodClient() throws Exception {
        return new DefaultAcsClient(
            DefaultProfile.getProfile(
                vodConfig.getRegion(),
                vodConfig.getAccessKeyId(),
                vodConfig.getAccessKeySecret()
            )
        );
    }
}
