package com.dora.controller;

import com.dora.common.Result;
import com.dora.dto.CourseCategoryDto;
import com.dora.dto.CourseDetailDto;
import com.dora.dto.CourseListItemDto;
import com.dora.dto.CourseUpdateDto;
import com.dora.dto.CourseVideoDetailDto;
import com.dora.dto.CourseVideoPlayDto;
import com.dora.dto.CategoryDto;
import com.dora.dto.PageResultDto;
import com.dora.entity.Category;
import com.dora.service.CategoryService;
import com.dora.service.CourseService;
import com.dora.util.SecurityUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.Valid;
import jakarta.validation.constraints.Min;
import java.util.List;

/**
 * 课程控制器
 */
@Slf4j
@RestController
@RequestMapping("/user/course")
@RequiredArgsConstructor
@Tag(name = "课程管理", description = "课程相关的API接口")
public class CourseController {

    private final CourseService courseService;
    private final CategoryService categoryService;

    @GetMapping("/categories")
    @Operation(summary = "获取课程分类列表", description = "获取所有课程分类及其对应的数量统计")
    public Result<List<CourseCategoryDto>> getCategories() {
        try {
            log.info("获取课程分类列表");
            List<CourseCategoryDto> categories = courseService.getCategories();
            return Result.success(categories);
        } catch (Exception e) {
            log.error("获取课程分类列表失败", e);
            return Result.error(500, "获取课程分类列表失败");
        }
    }

    @GetMapping("/hot")
    @Operation(summary = "获取热门课程列表", description = "获取热门课程的分页列表")
    public Result<PageResultDto<CourseListItemDto>> getHotCourses(
            @Parameter(description = "页码", example = "1") @RequestParam(defaultValue = "1") @Min(1) int page,
            @Parameter(description = "每页数量", example = "10") @RequestParam(defaultValue = "10") @Min(1) int size) {
        try {
            log.info("获取热门课程列表 - page: {}, size: {}", page, size);
            PageResultDto<CourseListItemDto> result = courseService.getHotCourses(page, size);
            return Result.success(result);
        } catch (Exception e) {
            log.error("获取热门课程列表失败 - page: {}, size: {}", page, size, e);
            return Result.error(500, "获取热门课程列表失败");
        }
    }

    @GetMapping("/category/{category}")
    @Operation(summary = "根据分类获取课程列表", description = "根据指定分类获取课程的分页列表")
    public Result<PageResultDto<CourseListItemDto>> getCoursesByCategory(
            @Parameter(description = "分类名称", example = "hot") @PathVariable String category,
            @Parameter(description = "页码", example = "1") @RequestParam(defaultValue = "1") @Min(1) int page,
            @Parameter(description = "每页数量", example = "10") @RequestParam(defaultValue = "10") @Min(1) int size) {
        try {
            log.info("根据分类获取课程列表 - category: {}, page: {}, size: {}", category, page, size);
            
            // 验证分类是否有效
            if (!isValidCategory(category)) {
                return Result.error(400, "无效的分类名称");
            }
            
            PageResultDto<CourseListItemDto> result = courseService.getCoursesByCategory(category, page, size);
            return Result.success(result);
        } catch (Exception e) {
            log.error("根据分类获取课程列表失败 - category: {}, page: {}, size: {}", category, page, size, e);
            return Result.error(500, "获取课程列表失败");
        }
    }

    @GetMapping("/{id}")
    @Operation(summary = "获取课程详情", description = "根据课程ID获取课程的详细信息（包含章节和视频）")
    public Result<CourseDetailDto> getCourseById(
            @Parameter(description = "课程ID", example = "1") @PathVariable Long id) {
        try {
            // 获取当前用户ID（可能为null，表示未登录用户）
            Long userId = null;
            try {
                userId = SecurityUtil.getCurrentUserId();
            } catch (RuntimeException e) {
                // 用户未登录，userId保持为null，允许匿名访问已审核的课程
                log.debug("用户未登录，以匿名身份访问课程详情 - courseId: {}", id);
            }
            
            log.info("获取课程详情 - id: {}, userId: {}", id, userId);
            CourseDetailDto detail = courseService.getCourseDetail(id, userId);
            return Result.success(detail);
        } catch (Exception e) {
            log.error("获取课程详情失败 - id: {}", id, e);
            return Result.error(500, "获取课程详情失败");
        }
    }

    @PutMapping("/{id}")
    @Operation(summary = "更新课程", description = "更新课程信息，包括章节和视频的完整更新")
    public Result<CourseDetailDto> updateCourse(
            @Parameter(description = "课程ID", example = "1") @PathVariable Long id,
            @Valid @RequestBody CourseUpdateDto updateDto) {
        Long userId = null;
        try {
            // 获取当前登录用户ID
            userId = SecurityUtil.getCurrentUserId();
            if (userId == null) {
                return Result.error(401, "用户未登录");
            }

            log.info("更新课程 - courseId: {}, userId: {}", id, userId);
            CourseDetailDto updatedCourse = courseService.updateCourse(id, userId, updateDto);
            return Result.success(updatedCourse);
        } catch (Exception e) {
            log.error("更新课程失败 - courseId: {}, userId: {}", id, userId, e);
            if (e instanceof com.dora.exception.BusinessException) {
                return Result.error(400, e.getMessage());
            }
            return Result.error(500, "更新课程失败");
        }
    }

    /**
     * 验证分类是否有效
     */
    private boolean isValidCategory(String category) {
        // 热门分类始终有效
        if ("hot".equals(category)) {
            return true;
        }
        
        try {
            // 首先尝试作为category_id（数字）验证
            try {
                Long categoryId = Long.parseLong(category);
                CategoryDto categoryDto = categoryService.getCategoryById(categoryId);
                // 检查是否是课程分类且已启用
                return categoryDto != null && 
                       Category.TYPE_COURSE.equals(categoryDto.getType()) && 
                       categoryDto.getIsEnabled();
            } catch (NumberFormatException e) {
                // 不是数字，继续用传统方式验证（兼容老数据）
            }
            
            // 传统方式：检查是否有课程使用该分类名
            PageResultDto<CourseListItemDto> result = courseService.getCoursesByCategory(category, 1, 1);
            return result != null && result.getTotal() > 0;
        } catch (Exception e) {
            log.warn("验证分类失败 - category: {}", category, e);
            return false;
        }
    }

    @GetMapping("/{courseId}/video-detail")
    @Operation(summary = "获取课程视频详情", description = "获取课程的视频详情信息，包含章节和视频列表，所有用户都可访问")
    public Result<CourseVideoDetailDto> getCourseVideoDetail(
            @Parameter(description = "课程ID", example = "1") @PathVariable Long courseId) {
        try {
            log.info("获取课程视频详情 - courseId: {}", courseId);
            
            // 获取当前用户ID（可能为null，表示未登录用户）
            Long userId = null;
            try {
                userId = SecurityUtil.getCurrentUserId();
            } catch (RuntimeException e) {
                // 用户未登录，userId保持为null，允许匿名访问
                log.debug("用户未登录，以匿名身份访问课程视频详情 - courseId: {}", courseId);
            }
            
            CourseVideoDetailDto detail = courseService.getCourseVideoDetail(courseId, userId);
            return Result.success(detail);
        } catch (Exception e) {
            log.error("获取课程视频详情失败 - courseId: {}", courseId, e);
            if (e instanceof com.dora.exception.BusinessException) {
                return Result.error(400, e.getMessage());
            }
            return Result.error(500, "获取课程视频详情失败");
        }
    }

    @PostMapping("/{courseId}/video/{videoId}/play-auth")
    @Operation(summary = "获取课程视频播放凭证", description = "根据用户权限获取课程视频的播放凭证，需要登录和权限验证")
    public Result<CourseVideoPlayDto.PlayAuthResponse> getCourseVideoPlayAuth(
            @Parameter(description = "课程ID", example = "1") @PathVariable Long courseId,
            @Parameter(description = "视频ID", example = "1") @PathVariable Long videoId,
            @Valid @RequestBody CourseVideoPlayDto.GetPlayAuthRequest request) {
        try {
            // 获取当前登录用户ID
            Long userId = SecurityUtil.getCurrentUserId();
            if (userId == null) {
                return Result.error(401, "请先登录");
            }

            log.info("获取课程视频播放凭证 - courseId: {}, videoId: {}, userId: {}", courseId, videoId, userId);
            
            // 设置路径参数
            request.setCourseId(courseId);
            request.setVideoId(videoId);
            
            CourseVideoPlayDto.PlayAuthResponse response = courseService.getCourseVideoPlayAuth(request, userId);
            return Result.success(response);
        } catch (Exception e) {
            log.error("获取课程视频播放凭证失败 - courseId: {}, videoId: {}", courseId, videoId, e);
            if (e instanceof com.dora.exception.BusinessException) {
                return Result.error(403, e.getMessage());
            }
            return Result.error(500, "获取播放凭证失败");
        }
    }
} 