package com.dora.controller;

import com.dora.common.Result;
import com.dora.dto.PageResultDto;
import com.dora.dto.WorkflowCategoryDto;
import com.dora.dto.WorkflowListItemDto;
import com.dora.dto.WorkflowDetailDto;
import com.dora.dto.WorkflowVideoPlayDto;
import com.dora.dto.WorkflowDataDto;
import com.dora.dto.CategoryDto;
import com.dora.entity.Category;
import com.dora.entity.Workflow;
import com.dora.service.CategoryService;
import com.dora.service.PlazaService;
import com.dora.dto.PlazaWorkDto.WorkDetailResponse;
import com.dora.service.WorkflowService;
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.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.constraints.Min;
import jakarta.validation.Valid;
import com.dora.util.SecurityUtil;
import java.util.List;

/**
 * 工作流控制器
 */
@Slf4j
@RestController
@RequestMapping("/user/workflow")
@RequiredArgsConstructor
@Validated
@Tag(name = "工作流管理", description = "工作流相关的API接口")
public class WorkflowController {

    private final PlazaService plazaService;
    private final WorkflowService workflowService;
    private final CategoryService categoryService;

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

    @GetMapping("/hot")
    @Operation(summary = "获取热门工作流列表", description = "获取热门工作流的分页列表")
    public Result<PageResultDto<WorkflowListItemDto>> getHotWorkflows(
            @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<WorkflowListItemDto> result = workflowService.getHotWorkflows(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<WorkflowListItemDto>> getWorkflowsByCategory(
            @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<WorkflowListItemDto> result = workflowService.getWorkflowsByCategory(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<Workflow> getWorkflowById(
            @Parameter(description = "工作流ID", example = "1") @PathVariable Long id) {
        try {
            log.info("获取工作流详情 - id: {}", id);
            Workflow workflow = workflowService.getWorkflowById(id);
            if (workflow == null) {
                return Result.error(404, "工作流不存在");
            }
            return Result.success(workflow);
        } catch (Exception e) {
            log.error("获取工作流详情失败 - id: {}", id, e);
            return Result.error(500, "获取工作流详情失败");
        }
    }

    @PostMapping("/submit")
    @Operation(summary = "提交/保存工作流", description = "支持JSON模式(data)和文件模式(dataFileUrl)，其一必填")
    public Result<Long> submitWorkflow(@Valid @RequestBody Workflow workflow) {
        try {
            Long ownerId = SecurityUtil.getCurrentUserId();
            Long id = workflowService.createOrUpdateWorkflow(ownerId, workflow);
            return Result.success(id, "提交成功");
        } catch (Exception e) {
            log.error("提交工作流失败", e);
            return Result.error(400, e.getMessage());
        }
    }

    @GetMapping("/{workflowId}/detail")
    @Operation(summary = "获取工作流详情", description = "获取工作流的详细信息，包含权限信息，所有用户都可访问。如果传入WORK-开头的广场作品编号，会自动转发到广场作品接口。")
    public Result<?> getWorkflowDetail(
            @Parameter(description = "工作流ID", example = "1") @PathVariable String workflowId) {
        try {
            // 检查是否是广场作品编号（WORK-开头），如果是则自动转发到广场作品接口
            if (workflowId != null && workflowId.toUpperCase().startsWith("WORK-")) {
                log.info("检测到广场作品编号，自动转发到广场作品接口 - workNo: {}", workflowId);
                
                Long userId = null;
                try {
                    userId = SecurityUtil.getCurrentUserId();
                } catch (RuntimeException e) {
                    // 用户未登录
                }
                
                // 记录浏览
                plazaService.recordView(workflowId, userId);
                // 获取作品详情
                WorkDetailResponse response = plazaService.getWorkDetail(userId, workflowId);
                return Result.success(response);
            }
            
            // 解析工作流ID
            Long workflowIdLong;
            try {
                workflowIdLong = Long.parseLong(workflowId);
            } catch (NumberFormatException e) {
                log.warn("工作流ID格式错误 - workflowId: {}", workflowId);
                return Result.error(400, "工作流ID格式错误，应为数字类型");
            }
            
            log.info("获取工作流详情 - workflowId: {}", workflowIdLong);
            
            // 获取当前用户ID（可能为null，表示未登录用户）
            Long userId = null;
            try {
                userId = SecurityUtil.getCurrentUserId();
            } catch (RuntimeException e) {
                // 用户未登录，userId保持为null，允许匿名访问
                log.debug("用户未登录，以匿名身份访问工作流详情 - workflowId: {}", workflowId);
            }
            
            WorkflowDetailDto detail = workflowService.getWorkflowDetail(workflowIdLong, userId);
            return Result.success(detail);
        } catch (Exception e) {
            log.error("获取工作流详情失败 - workflowId: {}", workflowId, e);
            if (e instanceof com.dora.exception.BusinessException) {
                return Result.error(400, e.getMessage());
            }
            return Result.error(500, "获取工作流详情失败");
        }
    }

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

            log.info("获取工作流视频播放凭证 - workflowId: {}, userId: {}", workflowId, userId);
            
            // 设置路径参数
            request.setWorkflowId(workflowId);
            
            WorkflowVideoPlayDto.PlayAuthResponse response = workflowService.getWorkflowVideoPlayAuth(request, userId);
            return Result.success(response);
        } catch (Exception e) {
            log.error("获取工作流视频播放凭证失败 - workflowId: {}", workflowId, e);
            if (e instanceof com.dora.exception.BusinessException) {
                return Result.error(403, e.getMessage());
            }
            return Result.error(500, "获取播放凭证失败");
        }
    }

    @GetMapping("/{workflowId}/data-file")
    @Operation(summary = "获取工作流数据包下载地址", description = "获取工作流的数据包下载地址，需要登录和复制权限，会记录复制统计")
    public Result<WorkflowDataDto.DataFileResponse> getWorkflowDataFile(
            @Parameter(description = "工作流ID", example = "1") @PathVariable Long workflowId) {
        try {
            // 获取当前登录用户ID
            Long userId = SecurityUtil.getCurrentUserId();
            if (userId == null) {
                return Result.error(401, "请先登录");
            }

            log.info("获取工作流数据包下载地址 - workflowId: {}, userId: {}", workflowId, userId);
            
            WorkflowDataDto.DataFileResponse response = workflowService.getWorkflowDataFile(workflowId, userId);
            return Result.success(response, "获取数据包下载地址成功");
        } catch (Exception e) {
            log.error("获取工作流数据包下载地址失败 - workflowId: {}", workflowId, e);
            if (e instanceof com.dora.exception.BusinessException) {
                return Result.error(403, e.getMessage());
            }
            return Result.error(500, "获取数据包下载地址失败");
        }
    }

    @GetMapping("/{workflowId}/json-data")
    @Operation(summary = "获取工作流JSON数据", description = "获取工作流的JSON数据，需要登录和复制权限，会记录复制统计")
    public Result<WorkflowDataDto.JsonDataResponse> getWorkflowJsonData(
            @Parameter(description = "工作流ID", example = "1") @PathVariable Long workflowId) {
        try {
            // 获取当前登录用户ID
            Long userId = SecurityUtil.getCurrentUserId();
            if (userId == null) {
                return Result.error(401, "请先登录");
            }

            log.info("获取工作流JSON数据 - workflowId: {}, userId: {}", workflowId, userId);
            
            WorkflowDataDto.JsonDataResponse response = workflowService.getWorkflowJsonData(workflowId, userId);
            return Result.success(response, "获取JSON数据成功");
        } catch (Exception e) {
            log.error("获取工作流JSON数据失败 - workflowId: {}", workflowId, e);
            if (e instanceof com.dora.exception.BusinessException) {
                return Result.error(403, e.getMessage());
            }
            return Result.error(500, "获取JSON数据失败");
        }
    }

    /**
     * 验证分类是否有效
     */
    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_WORKFLOW.equals(categoryDto.getType()) && 
                       categoryDto.getIsEnabled();
            } catch (NumberFormatException e) {
                // 不是数字，继续用传统方式验证（兼容老数据）
            }
            
            // 传统方式：检查是否有工作流使用该分类名
            PageResultDto<WorkflowListItemDto> result = workflowService.getWorkflowsByCategory(category, 1, 1);
            return result != null && result.getTotal() > 0;
        } catch (Exception e) {
            log.warn("验证工作流分类失败 - category: {}", category, e);
            return false;
        }
    }
} 