package com.lingyue.extract.service;

import com.lingyue.extract.entity.Generation;
import com.lingyue.extract.entity.Template;
import com.lingyue.extract.entity.Variable;
import com.lingyue.extract.repository.GenerationRepository;
import com.lingyue.extract.repository.TemplateRepository;
import com.lingyue.extract.repository.VariableRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * 文档生成服务
 * 
 * 负责根据模板和变量值生成最终文档
 * 
 * @author lingyue
 * @since 2026-01-24
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class DocumentGenerationService {
    
    private final GenerationRepository generationRepository;
    private final TemplateRepository templateRepository;
    private final VariableRepository variableRepository;
    
    @Value("${file.output-path:/tmp/lingyue/output}")
    private String outputPath;
    
    /**
     * 生成文档
     */
    @Transactional
    public void generateDocument(String generationId) {
        Generation generation = generationRepository.selectById(generationId);
        if (generation == null) {
            throw new RuntimeException("生成任务不存在");
        }
        
        Template template = templateRepository.selectById(generation.getTemplateId());
        if (template == null) {
            throw new RuntimeException("模板不存在");
        }
        
        try {
            // 更新状态为生成中
            generation.setStatus(Generation.STATUS_GENERATING);
            generationRepository.updateById(generation);
            
            // 获取变量列表
            List<Variable> variables = variableRepository.findByTemplateId(generation.getTemplateId());
            
            // 生成输出文件路径
            String outputFileName = generateFileName(generation, template);
            Path outputFilePath = Paths.get(outputPath, outputFileName);
            
            // 确保输出目录存在
            Files.createDirectories(outputFilePath.getParent());
            
            // TODO: 实际的文档生成逻辑
            // 1. 获取模板基础文档
            // 2. 替换变量
            // 3. 保存输出文件
            
            // 模拟生成：创建一个简单的文本文件
            StringBuilder content = new StringBuilder();
            content.append("=== 生成的报告 ===\n\n");
            content.append("模板: ").append(template.getName()).append("\n");
            content.append("生成时间: ").append(new Date()).append("\n\n");
            content.append("变量值:\n");
            
            for (Variable variable : variables) {
                Generation.VariableValue vv = generation.getVariableValues().get(variable.getName());
                String value = vv != null ? vv.getValue() : "(未提取)";
                content.append("  - ").append(variable.getDisplayName())
                        .append(": ").append(value).append("\n");
            }
            
            Files.writeString(outputFilePath, content.toString());
            
            // 更新生成任务
            generation.setOutputFilePath(outputFilePath.toString());
            generation.setStatus(Generation.STATUS_COMPLETED);
            generation.setCompletedAt(new Date());
            generation.setProgress(100);
            generationRepository.updateById(generation);
            
            log.info("文档生成成功: generationId={}, outputPath={}", generationId, outputFilePath);
            
        } catch (Exception e) {
            log.error("文档生成失败: generationId={}", generationId, e);
            generation.setStatus(Generation.STATUS_ERROR);
            generation.setErrorMessage("文档生成失败: " + e.getMessage());
            generationRepository.updateById(generation);
            throw new RuntimeException("文档生成失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 生成文件名
     */
    private String generateFileName(Generation generation, Template template) {
        String baseName = generation.getName() != null ? generation.getName() : template.getName();
        // 清理文件名中的非法字符
        baseName = baseName.replaceAll("[\\\\/:*?\"<>|]", "_");
        String uuid = UUID.randomUUID().toString().substring(0, 8);
        return baseName + "_" + uuid + ".txt"; // TODO: 根据实际模板格式生成 .docx
    }
    
    /**
     * 获取输出文件资源
     */
    public Resource getOutputFileResource(String generationId) {
        Generation generation = generationRepository.selectById(generationId);
        if (generation == null) {
            throw new RuntimeException("生成任务不存在");
        }
        
        if (!Generation.STATUS_COMPLETED.equals(generation.getStatus())) {
            throw new RuntimeException("文档尚未生成完成");
        }
        
        if (generation.getOutputFilePath() == null) {
            throw new RuntimeException("输出文件不存在");
        }
        
        try {
            Path filePath = Paths.get(generation.getOutputFilePath());
            if (!Files.exists(filePath)) {
                throw new RuntimeException("文件不存在: " + generation.getOutputFilePath());
            }
            
            Resource resource = new UrlResource(filePath.toUri());
            if (!resource.exists() || !resource.isReadable()) {
                throw new RuntimeException("文件无法读取: " + generation.getOutputFilePath());
            }
            
            return resource;
            
        } catch (IOException e) {
            throw new RuntimeException("读取文件失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 获取输出文件名
     */
    public String getOutputFileName(String generationId) {
        Generation generation = generationRepository.selectById(generationId);
        if (generation == null || generation.getOutputFilePath() == null) {
            return "report.txt";
        }
        
        Path path = Paths.get(generation.getOutputFilePath());
        return path.getFileName().toString();
    }
    
    /**
     * 删除输出文件
     */
    public void deleteOutputFile(String generationId) {
        Generation generation = generationRepository.selectById(generationId);
        if (generation == null || generation.getOutputFilePath() == null) {
            return;
        }
        
        try {
            Path filePath = Paths.get(generation.getOutputFilePath());
            Files.deleteIfExists(filePath);
            log.info("删除输出文件: {}", generation.getOutputFilePath());
        } catch (IOException e) {
            log.warn("删除输出文件失败: {}", e.getMessage());
        }
    }
}
