package com.dora.controller;

import com.dora.dto.VodDto;
import com.dora.service.VodService;
import com.dora.common.Result;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import com.dora.service.VideoPermissionService;

/**
 * 视频点播控制器
 */
@RestController
@RequestMapping("/user/vod")
@RequiredArgsConstructor
@Slf4j
@Tag(name = "视频点播", description = "视频点播相关接口")
public class VodController {

    private final VodService vodService;
    private final VideoPermissionService videoPermissionService;

    /**
     * 从请求中获取用户ID
     */
    private Long getUserIdFromRequest(HttpServletRequest request) {
        String userIdStr = (String) request.getAttribute("userId");
        if (userIdStr == null) {
            throw new RuntimeException("未提供认证令牌");
        }
        return Long.valueOf(userIdStr);
    }

    @PostMapping("/upload-auth")
    @Operation(summary = "获取视频上传凭证", description = "获取视频上传到阿里云VOD的凭证")
    @ApiResponses(value = {
        @ApiResponse(responseCode = "200", description = "获取成功", 
            content = @Content(schema = @Schema(implementation = VodDto.UploadAuthResponse.class))),
        @ApiResponse(responseCode = "400", description = "请求参数错误"),
        @ApiResponse(responseCode = "401", description = "未授权"),
        @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    public ResponseEntity<Result<VodDto.UploadAuthResponse>> getUploadAuth(
            @Valid @RequestBody VodDto.GetUploadAuthRequest request,
            HttpServletRequest httpRequest) {
        try {
            Long userId = getUserIdFromRequest(httpRequest);
            VodDto.UploadAuthResponse response = vodService.getUploadAuth(request);
            return ResponseEntity.ok(Result.success(response, "获取上传凭证成功"));
        } catch (RuntimeException e) {
            // JWT相关异常返回401
            if (e.getMessage().contains("认证令牌") || e.getMessage().contains("未提供认证令牌")) {
                log.warn("JWT认证失败: {}", e.getMessage());
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(Result.error(401, e.getMessage()));
            }
            log.error("获取视频上传凭证失败", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Result.error(500, e.getMessage()));
        } catch (Exception e) {
            log.error("获取视频上传凭证失败", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Result.error(500, "服务器内部错误"));
        }
    }

    @PostMapping("/refresh-upload-auth")
    @Operation(summary = "刷新视频上传凭证", description = "刷新视频上传凭证，用于续传")
    @ApiResponses(value = {
        @ApiResponse(responseCode = "200", description = "刷新成功", 
            content = @Content(schema = @Schema(implementation = VodDto.UploadAuthResponse.class))),
        @ApiResponse(responseCode = "400", description = "请求参数错误"),
        @ApiResponse(responseCode = "401", description = "未授权"),
        @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    public ResponseEntity<Result<VodDto.UploadAuthResponse>> refreshUploadAuth(
            @Valid @RequestBody VodDto.RefreshUploadAuthRequest request,
            HttpServletRequest httpRequest) {
        try {
            Long userId = getUserIdFromRequest(httpRequest);
            VodDto.UploadAuthResponse response = vodService.refreshUploadAuth(request);
            return ResponseEntity.ok(Result.success(response, "刷新上传凭证成功"));
        } catch (RuntimeException e) {
            // JWT相关异常返回401
            if (e.getMessage().contains("认证令牌") || e.getMessage().contains("未提供认证令牌")) {
                log.warn("JWT认证失败: {}", e.getMessage());
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(Result.error(401, e.getMessage()));
            }
            // 视频不存在的情况返回400
            if (e.getMessage().contains("视频不存在")) {
                log.warn("视频不存在: {}", e.getMessage());
                return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(Result.error(400, e.getMessage()));
            }
            log.error("刷新视频上传凭证失败", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Result.error(500, e.getMessage()));
        } catch (Exception e) {
            log.error("刷新视频上传凭证失败", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Result.error(500, "服务器内部错误"));
        }
    }

    @PostMapping("/play-auth")
    @Operation(summary = "获取视频播放凭证", description = "获取视频播放凭证，用于客户端播放视频")
    @ApiResponses(value = {
        @ApiResponse(responseCode = "200", description = "获取成功", 
            content = @Content(schema = @Schema(implementation = VodDto.PlayAuthResponse.class))),
        @ApiResponse(responseCode = "400", description = "请求参数错误"),
        @ApiResponse(responseCode = "401", description = "未授权"),
        @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    public ResponseEntity<Result<VodDto.PlayAuthResponse>> getPlayAuth(
            @Valid @RequestBody VodDto.GetPlayAuthRequest request,
            HttpServletRequest httpRequest) {
        try {
            Long userId = getUserIdFromRequest(httpRequest);
            VodDto.PlayAuthResponse response = vodService.getPlayAuth(request);
            return ResponseEntity.ok(Result.success(response, "获取播放凭证成功"));
        } catch (RuntimeException e) {
            // JWT相关异常返回401
            if (e.getMessage().contains("认证令牌") || e.getMessage().contains("未提供认证令牌")) {
                log.warn("JWT认证失败: {}", e.getMessage());
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(Result.error(401, e.getMessage()));
            }
            log.error("获取视频播放凭证失败", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Result.error(500, e.getMessage()));
        } catch (Exception e) {
            log.error("获取视频播放凭证失败", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Result.error(500, "服务器内部错误"));
        }
    }

    @PostMapping("/play-auth-with-view-count")
    @Operation(summary = "获取视频播放凭证并增加播放次数", description = "获取视频播放凭证，同时自动增加视频的播放次数和观看统计")
    @ApiResponses(value = {
        @ApiResponse(responseCode = "200", description = "获取成功", 
            content = @Content(schema = @Schema(implementation = VodDto.PlayAuthWithViewCountResponse.class))),
        @ApiResponse(responseCode = "400", description = "请求参数错误"),
        @ApiResponse(responseCode = "401", description = "未授权"),
        @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    public ResponseEntity<Result<VodDto.PlayAuthWithViewCountResponse>> getPlayAuthWithViewCount(
            @Valid @RequestBody VodDto.GetPlayAuthWithViewCountRequest request,
            HttpServletRequest httpRequest) {
        try {
            Long userId = getUserIdFromRequest(httpRequest);
            VodDto.PlayAuthWithViewCountResponse response = vodService.getPlayAuthWithViewCount(request, userId);
            return ResponseEntity.ok(Result.success(response, "获取播放凭证成功，播放次数已更新"));
        } catch (RuntimeException e) {
            // JWT相关异常返回401
            if (e.getMessage().contains("认证令牌") || e.getMessage().contains("未提供认证令牌")) {
                log.warn("JWT认证失败: {}", e.getMessage());
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(Result.error(401, e.getMessage()));
            }
            log.error("获取视频播放凭证并增加播放次数失败", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Result.error(500, e.getMessage()));
        } catch (Exception e) {
            log.error("获取视频播放凭证并增加播放次数失败", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Result.error(500, "服务器内部错误"));
        }
    }

    @PostMapping("/video-info")
    @Operation(summary = "获取视频信息", description = "获取视频的详细信息")
    @ApiResponses(value = {
        @ApiResponse(responseCode = "200", description = "获取成功", 
            content = @Content(schema = @Schema(implementation = VodDto.VideoInfoResponse.class))),
        @ApiResponse(responseCode = "400", description = "请求参数错误"),
        @ApiResponse(responseCode = "401", description = "未授权"),
        @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    public ResponseEntity<Result<VodDto.VideoInfoResponse>> getVideoInfo(
            @Valid @RequestBody VodDto.GetVideoInfoRequest request,
            HttpServletRequest httpRequest) {
        try {
            Long userId = getUserIdFromRequest(httpRequest);
            VodDto.VideoInfoResponse response = vodService.getVideoInfo(request);
            return ResponseEntity.ok(Result.success(response, "获取视频信息成功"));
        } catch (RuntimeException e) {
            // JWT相关异常返回401
            if (e.getMessage().contains("认证令牌") || e.getMessage().contains("未提供认证令牌")) {
                log.warn("JWT认证失败: {}", e.getMessage());
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(Result.error(401, e.getMessage()));
            }
            log.error("获取视频信息失败", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Result.error(500, e.getMessage()));
        } catch (Exception e) {
            log.error("获取视频信息失败", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Result.error(500, "服务器内部错误"));
        }
    }

    @PostMapping("/play-info")
    @Operation(summary = "获取音视频播放地址", description = "获取音视频播放地址，需要权限验证")
    @ApiResponses(value = {
        @ApiResponse(responseCode = "200", description = "获取成功", 
            content = @Content(schema = @Schema(implementation = VodDto.PlayInfoResponse.class))),
        @ApiResponse(responseCode = "400", description = "请求参数错误"),
        @ApiResponse(responseCode = "401", description = "未授权"),
        @ApiResponse(responseCode = "403", description = "无权限访问"),
        @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    public ResponseEntity<Result<VodDto.PlayInfoResponse>> getPlayInfo(
            @Valid @RequestBody VodDto.GetPlayInfoRequest request,
            HttpServletRequest httpRequest) {
        try {
            Long userId = getUserIdFromRequest(httpRequest);
            VodDto.PlayInfoResponse response = vodService.getPlayInfo(request, userId);
            return ResponseEntity.ok(Result.success(response, "获取播放地址成功"));
        } catch (RuntimeException e) {
            // JWT相关异常返回401
            if (e.getMessage().contains("认证令牌") || e.getMessage().contains("未提供认证令牌")) {
                log.warn("JWT认证失败: {}", e.getMessage());
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(Result.error(401, e.getMessage()));
            }
            // 权限不足返回403
            if (e.getMessage().contains("无权限")) {
                log.warn("用户无权限访问视频: {}", e.getMessage());
                return ResponseEntity.status(HttpStatus.FORBIDDEN).body(Result.error(403, e.getMessage()));
            }
            log.error("获取播放地址失败", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Result.error(500, e.getMessage()));
        } catch (Exception e) {
            log.error("获取播放地址失败", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Result.error(500, "服务器内部错误"));
        }
    }

    @PostMapping("/video-play-auth")
    @Operation(summary = "获取音视频播放凭证", description = "获取音视频播放凭证，需要权限验证")
    @ApiResponses(value = {
        @ApiResponse(responseCode = "200", description = "获取成功", 
            content = @Content(schema = @Schema(implementation = VodDto.VideoPlayAuthResponse.class))),
        @ApiResponse(responseCode = "400", description = "请求参数错误"),
        @ApiResponse(responseCode = "401", description = "未授权"),
        @ApiResponse(responseCode = "403", description = "无权限访问"),
        @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    public ResponseEntity<Result<VodDto.VideoPlayAuthResponse>> getVideoPlayAuth(
            @Valid @RequestBody VodDto.GetVideoPlayAuthRequest request,
            HttpServletRequest httpRequest) {
        try {
            Long userId = getUserIdFromRequest(httpRequest);
            VodDto.VideoPlayAuthResponse response = vodService.getVideoPlayAuth(request, userId);
            return ResponseEntity.ok(Result.success(response, "获取播放凭证成功"));
        } catch (RuntimeException e) {
            // JWT相关异常返回401
            if (e.getMessage().contains("认证令牌") || e.getMessage().contains("未提供认证令牌")) {
                log.warn("JWT认证失败: {}", e.getMessage());
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(Result.error(401, e.getMessage()));
            }
            // 权限不足返回403
            if (e.getMessage().contains("无权限")) {
                log.warn("用户无权限访问视频: {}", e.getMessage());
                return ResponseEntity.status(HttpStatus.FORBIDDEN).body(Result.error(403, e.getMessage()));
            }
            log.error("获取播放凭证失败", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Result.error(500, e.getMessage()));
        } catch (Exception e) {
            log.error("获取播放凭证失败", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Result.error(500, "服务器内部错误"));
        }
    }

    @GetMapping("/test-permission")
    @Operation(summary = "测试权限检查", description = "测试视频权限检查功能")
    @ApiResponses(value = {
        @ApiResponse(responseCode = "200", description = "测试成功"),
        @ApiResponse(responseCode = "401", description = "未授权"),
        @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    public ResponseEntity<Result<String>> testPermission(
            @RequestParam String videoId,
            @RequestParam(required = false) Long courseId,
            @RequestParam(required = false) Long chapterId,
            HttpServletRequest httpRequest) {
        try {
            Long userId = getUserIdFromRequest(httpRequest);
            boolean hasPermission = videoPermissionService.hasVideoAccessPermission(userId, videoId, courseId, chapterId);
            String message = hasPermission ? "用户有权限访问该视频" : "用户无权限访问该视频";
            return ResponseEntity.ok(Result.success(message, "权限检查完成"));
        } catch (RuntimeException e) {
            if (e.getMessage().contains("认证令牌") || e.getMessage().contains("未提供认证令牌")) {
                log.warn("JWT认证失败: {}", e.getMessage());
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(Result.error(401, e.getMessage()));
            }
            log.error("权限检查失败", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Result.error(500, e.getMessage()));
        } catch (Exception e) {
            log.error("权限检查失败", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Result.error(500, "服务器内部错误"));
        }
    }
} 