package com.lingyue.extract.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lingyue.common.domain.AjaxResult;
import com.lingyue.extract.dto.request.AddSourceFileRequest;
import com.lingyue.extract.dto.request.AddVariableRequest;
import com.lingyue.extract.dto.request.CreateTemplateRequest;
import com.lingyue.extract.dto.request.UpdateTemplateRequest;
import com.lingyue.extract.dto.response.SourceFileResponse;
import com.lingyue.extract.dto.response.TemplateDetailResponse;
import com.lingyue.extract.dto.response.TemplateListResponse;
import com.lingyue.extract.dto.response.VariableResponse;
import com.lingyue.extract.entity.SourceFile;
import com.lingyue.extract.entity.Template;
import com.lingyue.extract.entity.Variable;
import com.lingyue.extract.service.SourceFileService;
import com.lingyue.extract.service.TemplateService;
import com.lingyue.extract.service.VariableService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 模板管理控制器
 * 
 * @author lingyue
 * @since 2026-01-23
 */
@Slf4j
@RestController
@RequestMapping("/api/v1/templates")
@RequiredArgsConstructor
@Tag(name = "模板管理", description = "报告模板 CRUD 接口")
public class TemplateController {
    
    private final TemplateService templateService;
    private final SourceFileService sourceFileService;
    private final VariableService variableService;
    
    /**
     * 获取当前用户ID
     * 开发阶段：如果未登录，使用默认测试用户
     */
    private String getCurrentUserId() {
        String userId = com.lingyue.common.util.SecurityUtils.getCurrentUserId();
        // 开发阶段：未登录时使用测试用户
        return userId != null ? userId : "00000000000000000000000000000002";
    }
    
    // ==================== 模板 CRUD ====================
    
    @PostMapping
    @Operation(summary = "创建模板", description = "创建新的报告模板")
    public AjaxResult<?> createTemplate(@Valid @RequestBody CreateTemplateRequest request) {
        try {
            String userId = getCurrentUserId();
            Template template = templateService.create(userId, request);
            return AjaxResult.success("创建成功", TemplateDetailResponse.fromEntity(template));
        } catch (Exception e) {
            log.error("创建模板失败", e);
            return AjaxResult.error("创建失败: " + e.getMessage());
        }
    }
    
    @GetMapping("/{id}")
    @Operation(summary = "获取模板详情", description = "获取模板详情，包含来源文件和变量列表")
    public AjaxResult<?> getTemplate(
            @Parameter(description = "模板ID") @PathVariable String id) {
        TemplateDetailResponse response = templateService.getTemplateDetail(id);
        if (response == null) {
            return AjaxResult.error("模板不存在");
        }
        return AjaxResult.success(response);
    }
    
    @GetMapping
    @Operation(summary = "获取模板列表", description = "分页获取当前用户的模板列表")
    public AjaxResult<?> listTemplates(
            @Parameter(description = "页码") @RequestParam(defaultValue = "1") int page,
            @Parameter(description = "每页数量") @RequestParam(defaultValue = "20") int size) {
        String userId = getCurrentUserId();
        Page<TemplateListResponse> result = templateService.listByUserId(userId, page, size);
        return AjaxResult.success(result);
    }
    
    @GetMapping("/accessible")
    @Operation(summary = "获取可访问的模板", description = "获取用户可见的模板（自己的 + 公开的）")
    public AjaxResult<?> listAccessibleTemplates() {
        String userId = getCurrentUserId();
        List<TemplateListResponse> result = templateService.listAccessible(userId);
        return AjaxResult.success(result);
    }
    
    @GetMapping("/search")
    @Operation(summary = "搜索模板", description = "按名称搜索模板")
    public AjaxResult<?> searchTemplates(
            @Parameter(description = "关键词") @RequestParam String keyword) {
        String userId = getCurrentUserId();
        List<TemplateListResponse> result = templateService.search(userId, keyword);
        return AjaxResult.success(result);
    }
    
    @GetMapping("/stats")
    @Operation(summary = "获取统计数据", description = "获取首页展示的统计数据")
    public AjaxResult<?> getStats() {
        String userId = getCurrentUserId();
        java.util.Map<String, Object> stats = templateService.getStats(userId);
        return AjaxResult.success(stats);
    }
    
    @PutMapping("/{id}")
    @Operation(summary = "更新模板", description = "更新模板基本信息")
    public AjaxResult<?> updateTemplate(
            @Parameter(description = "模板ID") @PathVariable String id,
            @Valid @RequestBody UpdateTemplateRequest request) {
        try {
            Template template = templateService.update(id, request);
            if (template == null) {
                return AjaxResult.error("模板不存在");
            }
            return AjaxResult.success("更新成功", TemplateDetailResponse.fromEntity(template));
        } catch (Exception e) {
            log.error("更新模板失败", e);
            return AjaxResult.error("更新失败: " + e.getMessage());
        }
    }
    
    @DeleteMapping("/{id}")
    @Operation(summary = "删除模板", description = "删除模板（级联删除来源文件和变量）")
    public AjaxResult<?> deleteTemplate(
            @Parameter(description = "模板ID") @PathVariable String id) {
        try {
            boolean success = templateService.delete(id);
            if (!success) {
                return AjaxResult.error("模板不存在");
            }
            return AjaxResult.success("删除成功");
        } catch (Exception e) {
            log.error("删除模板失败", e);
            return AjaxResult.error("删除失败: " + e.getMessage());
        }
    }
    
    // ==================== 模板状态操作 ====================
    
    @PostMapping("/{id}/publish")
    @Operation(summary = "发布模板", description = "将模板状态改为已发布")
    public AjaxResult<?> publishTemplate(
            @Parameter(description = "模板ID") @PathVariable String id) {
        try {
            Template template = templateService.publish(id);
            if (template == null) {
                return AjaxResult.error("模板不存在");
            }
            return AjaxResult.success("发布成功", TemplateDetailResponse.fromEntity(template));
        } catch (Exception e) {
            log.error("发布模板失败", e);
            return AjaxResult.error("发布失败: " + e.getMessage());
        }
    }
    
    @PostMapping("/{id}/archive")
    @Operation(summary = "归档模板", description = "将模板状态改为已归档")
    public AjaxResult<?> archiveTemplate(
            @Parameter(description = "模板ID") @PathVariable String id) {
        try {
            Template template = templateService.archive(id);
            if (template == null) {
                return AjaxResult.error("模板不存在");
            }
            return AjaxResult.success("归档成功", TemplateDetailResponse.fromEntity(template));
        } catch (Exception e) {
            log.error("归档模板失败", e);
            return AjaxResult.error("归档失败: " + e.getMessage());
        }
    }
    
    @PostMapping("/{id}/duplicate")
    @Operation(summary = "复制模板", description = "复制模板及其来源文件和变量")
    public AjaxResult<?> duplicateTemplate(
            @Parameter(description = "模板ID") @PathVariable String id,
            @Parameter(description = "新模板名称") @RequestParam(required = false) String newName) {
        try {
            String userId = getCurrentUserId();
            Template template = templateService.duplicate(id, userId, newName);
            if (template == null) {
                return AjaxResult.error("模板不存在");
            }
            return AjaxResult.success("复制成功", TemplateDetailResponse.fromEntity(template));
        } catch (Exception e) {
            log.error("复制模板失败", e);
            return AjaxResult.error("复制失败: " + e.getMessage());
        }
    }
    
    // ==================== 来源文件管理 ====================
    
    @PostMapping("/{templateId}/source-files")
    @Operation(summary = "添加来源文件定义", description = "为模板添加来源文件定义")
    public AjaxResult<?> addSourceFile(
            @Parameter(description = "模板ID") @PathVariable String templateId,
            @Valid @RequestBody AddSourceFileRequest request) {
        try {
            SourceFile sourceFile = sourceFileService.add(templateId, request);
            return AjaxResult.success("添加成功", SourceFileResponse.fromEntity(sourceFile));
        } catch (Exception e) {
            log.error("添加来源文件定义失败", e);
            return AjaxResult.error("添加失败: " + e.getMessage());
        }
    }
    
    @GetMapping("/{templateId}/source-files")
    @Operation(summary = "获取来源文件定义列表", description = "获取模板的所有来源文件定义")
    public AjaxResult<?> listSourceFiles(
            @Parameter(description = "模板ID") @PathVariable String templateId) {
        List<SourceFile> sourceFiles = sourceFileService.listByTemplateId(templateId);
        List<SourceFileResponse> responses = sourceFiles.stream()
                .map(SourceFileResponse::fromEntity)
                .collect(Collectors.toList());
        return AjaxResult.success(responses);
    }
    
    @PutMapping("/source-files/{id}")
    @Operation(summary = "更新来源文件定义", description = "更新来源文件定义")
    public AjaxResult<?> updateSourceFile(
            @Parameter(description = "来源文件定义ID") @PathVariable String id,
            @Valid @RequestBody AddSourceFileRequest request) {
        try {
            SourceFile sourceFile = sourceFileService.update(id, request);
            if (sourceFile == null) {
                return AjaxResult.error("来源文件定义不存在");
            }
            return AjaxResult.success("更新成功", SourceFileResponse.fromEntity(sourceFile));
        } catch (Exception e) {
            log.error("更新来源文件定义失败", e);
            return AjaxResult.error("更新失败: " + e.getMessage());
        }
    }
    
    @DeleteMapping("/source-files/{id}")
    @Operation(summary = "删除来源文件定义", description = "删除来源文件定义")
    public AjaxResult<?> deleteSourceFile(
            @Parameter(description = "来源文件定义ID") @PathVariable String id,
            @Parameter(description = "是否强制删除") @RequestParam(defaultValue = "false") boolean force) {
        try {
            boolean success = force ? sourceFileService.forceDelete(id) : sourceFileService.delete(id);
            if (!success) {
                return AjaxResult.error("来源文件定义不存在");
            }
            return AjaxResult.success("删除成功");
        } catch (Exception e) {
            log.error("删除来源文件定义失败", e);
            return AjaxResult.error("删除失败: " + e.getMessage());
        }
    }
    
    // ==================== 变量管理 ====================
    
    @PostMapping("/{templateId}/variables")
    @Operation(summary = "添加变量", description = "为模板添加变量")
    public AjaxResult<?> addVariable(
            @Parameter(description = "模板ID") @PathVariable String templateId,
            @Valid @RequestBody AddVariableRequest request) {
        try {
            Variable variable = variableService.add(templateId, request);
            return AjaxResult.success("添加成功", VariableResponse.fromEntity(variable));
        } catch (Exception e) {
            log.error("添加变量失败", e);
            return AjaxResult.error("添加失败: " + e.getMessage());
        }
    }
    
    @GetMapping("/{templateId}/variables")
    @Operation(summary = "获取变量列表", description = "获取模板的所有变量")
    public AjaxResult<?> listVariables(
            @Parameter(description = "模板ID") @PathVariable String templateId,
            @Parameter(description = "来源文件别名过滤") @RequestParam(required = false) String sourceFileAlias,
            @Parameter(description = "变量分组过滤") @RequestParam(required = false) String group,
            @Parameter(description = "变量类别过滤") @RequestParam(required = false) String category) {
        List<Variable> variables;
        
        if (sourceFileAlias != null) {
            variables = variableService.listBySourceFileAlias(templateId, sourceFileAlias);
        } else if (group != null) {
            variables = variableService.listByGroup(templateId, group);
        } else if (category != null) {
            variables = variableService.listByCategory(templateId, category);
        } else {
            variables = variableService.listByTemplateId(templateId);
        }
        
        List<VariableResponse> responses = variables.stream()
                .map(VariableResponse::fromEntity)
                .collect(Collectors.toList());
        return AjaxResult.success(responses);
    }
    
    @GetMapping("/{templateId}/variables/grouped")
    @Operation(summary = "获取变量按类别分组", description = "获取模板的所有变量，按 category 分组返回")
    public AjaxResult<?> listVariablesGrouped(
            @Parameter(description = "模板ID") @PathVariable String templateId) {
        java.util.Map<String, List<Variable>> grouped = variableService.listGroupedByCategory(templateId);
        
        // 转换为 VariableResponse
        java.util.Map<String, List<VariableResponse>> result = new java.util.LinkedHashMap<>();
        // 按固定顺序排列类别
        String[] categoryOrder = {"entity", "concept", "data", "location", "asset", "other"};
        for (String cat : categoryOrder) {
            List<Variable> vars = grouped.get(cat);
            if (vars != null && !vars.isEmpty()) {
                result.put(cat, vars.stream()
                        .map(VariableResponse::fromEntity)
                        .collect(Collectors.toList()));
            }
        }
        
        return AjaxResult.success(result);
    }
    
    @GetMapping("/variables/{id}")
    @Operation(summary = "获取变量详情", description = "获取变量详情")
    public AjaxResult<?> getVariable(
            @Parameter(description = "变量ID") @PathVariable String id) {
        Variable variable = variableService.getById(id);
        if (variable == null) {
            return AjaxResult.error("变量不存在");
        }
        return AjaxResult.success(VariableResponse.fromEntity(variable));
    }
    
    @PutMapping("/variables/{id}")
    @Operation(summary = "更新变量", description = "更新变量")
    public AjaxResult<?> updateVariable(
            @Parameter(description = "变量ID") @PathVariable String id,
            @Valid @RequestBody AddVariableRequest request) {
        try {
            Variable variable = variableService.update(id, request);
            if (variable == null) {
                return AjaxResult.error("变量不存在");
            }
            return AjaxResult.success("更新成功", VariableResponse.fromEntity(variable));
        } catch (Exception e) {
            log.error("更新变量失败", e);
            return AjaxResult.error("更新失败: " + e.getMessage());
        }
    }
    
    @DeleteMapping("/variables/{id}")
    @Operation(summary = "删除变量", description = "删除变量")
    public AjaxResult<?> deleteVariable(
            @Parameter(description = "变量ID") @PathVariable String id,
            @Parameter(description = "是否强制删除") @RequestParam(defaultValue = "false") boolean force) {
        try {
            boolean success = force ? variableService.forceDelete(id) : variableService.delete(id);
            if (!success) {
                return AjaxResult.error("变量不存在");
            }
            return AjaxResult.success("删除成功");
        } catch (Exception e) {
            log.error("删除变量失败", e);
            return AjaxResult.error("删除失败: " + e.getMessage());
        }
    }
    
    @PostMapping("/variables/{id}/preview")
    @Operation(summary = "预览变量提取结果", description = "使用指定文档测试变量提取配置")
    public AjaxResult<?> previewVariable(
            @Parameter(description = "变量ID") @PathVariable String id,
            @Parameter(description = "测试文档ID") @RequestParam String documentId) {
        try {
            var result = variableService.preview(id, documentId);
            return AjaxResult.success(result);
        } catch (Exception e) {
            log.error("预览变量提取失败", e);
            return AjaxResult.error("预览失败: " + e.getMessage());
        }
    }
    
    // ==================== 重排序接口 ====================
    
    @PostMapping("/{templateId}/source-files/reorder")
    @Operation(summary = "重排序来源文件", description = "调整来源文件的显示顺序")
    public AjaxResult<?> reorderSourceFiles(
            @Parameter(description = "模板ID") @PathVariable String templateId,
            @Valid @RequestBody com.lingyue.extract.dto.request.ReorderRequest request) {
        try {
            sourceFileService.reorder(templateId, request.getOrderedIds());
            return AjaxResult.success("重排序成功");
        } catch (Exception e) {
            log.error("重排序来源文件失败", e);
            return AjaxResult.error("重排序失败: " + e.getMessage());
        }
    }
    
    @PostMapping("/{templateId}/variables/reorder")
    @Operation(summary = "重排序变量", description = "调整变量的显示顺序")
    public AjaxResult<?> reorderVariables(
            @Parameter(description = "模板ID") @PathVariable String templateId,
            @Valid @RequestBody com.lingyue.extract.dto.request.ReorderRequest request) {
        try {
            variableService.reorder(templateId, request.getOrderedIds());
            return AjaxResult.success("重排序成功");
        } catch (Exception e) {
            log.error("重排序变量失败", e);
            return AjaxResult.error("重排序失败: " + e.getMessage());
        }
    }
}
