package com.lingyue.extract.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lingyue.extract.dto.request.CreateTemplateRequest;
import com.lingyue.extract.dto.request.UpdateTemplateRequest;
import com.lingyue.extract.dto.response.TemplateDetailResponse;
import com.lingyue.extract.dto.response.TemplateListResponse;
import com.lingyue.extract.entity.Generation;
import com.lingyue.extract.entity.SourceFile;
import com.lingyue.extract.entity.Template;
import com.lingyue.extract.entity.Variable;
import com.lingyue.extract.repository.GenerationRepository;
import com.lingyue.extract.repository.SourceFileRepository;
import com.lingyue.extract.repository.TemplateRepository;
import com.lingyue.extract.repository.VariableRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * 模板服务
 * 
 * @author lingyue
 * @since 2026-01-23
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class TemplateService {
    
    private final TemplateRepository templateRepository;
    private final SourceFileRepository sourceFileRepository;
    private final VariableRepository variableRepository;
    private final GenerationRepository generationRepository;
    
    /**
     * 创建模板
     */
    @Transactional
    public Template create(String userId, CreateTemplateRequest request) {
        Template template = new Template();
        template.setId(UUID.randomUUID().toString().replace("-", ""));
        template.setUserId(userId);
        template.setName(request.getName());
        template.setDescription(request.getDescription());
        template.setBaseDocumentId(request.getBaseDocumentId());
        template.setStatus(Template.STATUS_DRAFT);
        template.setConfig(request.getConfig());
        template.setIsPublic(request.getIsPublic() != null ? request.getIsPublic() : false);
        template.setUseCount(0);
        template.setCreateTime(new Date());
        template.setUpdateTime(new Date());
        
        templateRepository.insert(template);
        log.info("创建模板成功: id={}, name={}, userId={}", template.getId(), template.getName(), userId);
        
        return template;
    }
    
    /**
     * 根据ID获取模板
     */
    public Template getById(String id) {
        return templateRepository.selectById(id);
    }
    
    /**
     * 获取模板详情（包含来源文件和变量）
     */
    public TemplateDetailResponse getTemplateDetail(String id) {
        Template template = templateRepository.selectById(id);
        if (template == null) {
            return null;
        }
        
        TemplateDetailResponse response = TemplateDetailResponse.fromEntity(template);
        
        // 获取来源文件列表
        List<SourceFile> sourceFiles = sourceFileRepository.findByTemplateId(id);
        response.setSourceFiles(sourceFiles);
        response.setSourceFileCount(sourceFiles.size());
        
        // 获取变量列表
        List<Variable> variables = variableRepository.findByTemplateId(id);
        response.setVariables(variables);
        response.setVariableCount(variables.size());
        
        // 获取生成次数
        int generationCount = generationRepository.countByTemplateId(id);
        response.setGenerationCount(generationCount);
        
        return response;
    }
    
    /**
     * 分页查询用户的模板
     */
    public Page<TemplateListResponse> listByUserId(String userId, int page, int size) {
        Page<Template> pageRequest = new Page<>(page, size);
        
        LambdaQueryWrapper<Template> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Template::getUserId, userId)
               .orderByDesc(Template::getCreateTime);
        
        Page<Template> templatePage = templateRepository.selectPage(pageRequest, wrapper);
        
        // 转换为响应对象
        Page<TemplateListResponse> responsePage = new Page<>(page, size, templatePage.getTotal());
        List<TemplateListResponse> records = templatePage.getRecords().stream()
                .map(template -> {
                    TemplateListResponse response = TemplateListResponse.fromEntity(template);
                    // 填充统计信息
                    response.setSourceFileCount(sourceFileRepository.countByTemplateId(template.getId()));
                    response.setVariableCount(variableRepository.countByTemplateId(template.getId()));
                    return response;
                })
                .collect(Collectors.toList());
        responsePage.setRecords(records);
        
        return responsePage;
    }
    
    /**
     * 查询用户可见的模板（自己的 + 公开的）
     */
    public List<TemplateListResponse> listAccessible(String userId) {
        List<Template> templates = templateRepository.findAccessibleByUserId(userId);
        return templates.stream()
                .map(template -> {
                    TemplateListResponse response = TemplateListResponse.fromEntity(template);
                    response.setSourceFileCount(sourceFileRepository.countByTemplateId(template.getId()));
                    response.setVariableCount(variableRepository.countByTemplateId(template.getId()));
                    return response;
                })
                .collect(Collectors.toList());
    }
    
    /**
     * 搜索模板
     */
    public List<TemplateListResponse> search(String userId, String keyword) {
        List<Template> templates = templateRepository.searchByName(userId, keyword);
        return templates.stream()
                .map(TemplateListResponse::fromEntity)
                .collect(Collectors.toList());
    }
    
    /**
     * 更新模板
     */
    @Transactional
    public Template update(String id, UpdateTemplateRequest request) {
        Template template = templateRepository.selectById(id);
        if (template == null) {
            return null;
        }
        
        if (request.getName() != null) {
            template.setName(request.getName());
        }
        if (request.getDescription() != null) {
            template.setDescription(request.getDescription());
        }
        if (request.getConfig() != null) {
            template.setConfig(request.getConfig());
        }
        if (request.getIsPublic() != null) {
            template.setIsPublic(request.getIsPublic());
        }
        template.setUpdateTime(new Date());
        
        templateRepository.updateById(template);
        log.info("更新模板成功: id={}", id);
        
        return template;
    }
    
    /**
     * 删除模板（级联删除来源文件、变量）
     */
    @Transactional
    public boolean delete(String id) {
        Template template = templateRepository.selectById(id);
        if (template == null) {
            return false;
        }
        
        // 检查是否有生成任务
        int generationCount = generationRepository.countByTemplateId(id);
        if (generationCount > 0) {
            log.warn("模板有关联的生成任务，无法删除: id={}, generationCount={}", id, generationCount);
            throw new RuntimeException("模板有关联的生成任务，无法删除。如需删除，请先删除相关生成任务。");
        }
        
        // 级联删除变量
        variableRepository.deleteByTemplateId(id);
        
        // 级联删除来源文件
        sourceFileRepository.deleteByTemplateId(id);
        
        // 删除模板
        templateRepository.deleteById(id);
        log.info("删除模板成功（级联删除）: id={}", id);
        
        return true;
    }
    
    /**
     * 发布模板
     */
    @Transactional
    public Template publish(String id) {
        Template template = templateRepository.selectById(id);
        if (template == null) {
            return null;
        }
        
        // 检查是否有变量
        int variableCount = variableRepository.countByTemplateId(id);
        if (variableCount == 0) {
            throw new RuntimeException("模板没有定义变量，无法发布");
        }
        
        template.setStatus(Template.STATUS_PUBLISHED);
        template.setUpdateTime(new Date());
        templateRepository.updateById(template);
        
        log.info("发布模板成功: id={}", id);
        return template;
    }
    
    /**
     * 归档模板
     */
    @Transactional
    public Template archive(String id) {
        Template template = templateRepository.selectById(id);
        if (template == null) {
            return null;
        }
        
        template.setStatus(Template.STATUS_ARCHIVED);
        template.setUpdateTime(new Date());
        templateRepository.updateById(template);
        
        log.info("归档模板成功: id={}", id);
        return template;
    }
    
    /**
     * 复制模板
     */
    @Transactional
    public Template duplicate(String id, String userId, String newName) {
        Template source = templateRepository.selectById(id);
        if (source == null) {
            return null;
        }
        
        // 创建新模板
        Template newTemplate = new Template();
        newTemplate.setId(UUID.randomUUID().toString().replace("-", ""));
        newTemplate.setUserId(userId);
        newTemplate.setName(newName != null ? newName : source.getName() + " (副本)");
        newTemplate.setDescription(source.getDescription());
        newTemplate.setBaseDocumentId(source.getBaseDocumentId());
        newTemplate.setStatus(Template.STATUS_DRAFT);
        newTemplate.setConfig(source.getConfig());
        newTemplate.setIsPublic(false);
        newTemplate.setUseCount(0);
        newTemplate.setCreateTime(new Date());
        newTemplate.setUpdateTime(new Date());
        
        templateRepository.insert(newTemplate);
        
        // 复制来源文件
        List<SourceFile> sourceFiles = sourceFileRepository.findByTemplateId(id);
        for (SourceFile sf : sourceFiles) {
            SourceFile newSf = new SourceFile();
            newSf.setId(UUID.randomUUID().toString().replace("-", ""));
            newSf.setTemplateId(newTemplate.getId());
            newSf.setAlias(sf.getAlias());
            newSf.setDescription(sf.getDescription());
            newSf.setFileTypes(sf.getFileTypes());
            newSf.setRequired(sf.getRequired());
            newSf.setExampleDocumentId(sf.getExampleDocumentId());
            newSf.setDisplayOrder(sf.getDisplayOrder());
            newSf.setCreateTime(new Date());
            sourceFileRepository.insert(newSf);
        }
        
        // 复制变量
        List<Variable> variables = variableRepository.findByTemplateId(id);
        for (Variable v : variables) {
            Variable newV = new Variable();
            newV.setId(UUID.randomUUID().toString().replace("-", ""));
            newV.setTemplateId(newTemplate.getId());
            newV.setName(v.getName());
            newV.setDisplayName(v.getDisplayName());
            newV.setVariableGroup(v.getVariableGroup());
            newV.setLocation(v.getLocation());
            newV.setExampleValue(v.getExampleValue());
            newV.setValueType(v.getValueType());
            newV.setSourceFileAlias(v.getSourceFileAlias());
            newV.setSourceType(v.getSourceType());
            newV.setSourceConfig(v.getSourceConfig());
            newV.setExtractType(v.getExtractType());
            newV.setExtractConfig(v.getExtractConfig());
            newV.setDisplayOrder(v.getDisplayOrder());
            newV.setCreateTime(new Date());
            newV.setUpdateTime(new Date());
            variableRepository.insert(newV);
        }
        
        log.info("复制模板成功: sourceId={}, newId={}", id, newTemplate.getId());
        return newTemplate;
    }
    
    /**
     * 增加使用次数
     */
    public void incrementUseCount(String id) {
        templateRepository.incrementUseCount(id);
    }
    
    /**
     * 检查用户是否有访问权限
     */
    public boolean hasAccess(String templateId, String userId) {
        Template template = templateRepository.selectById(templateId);
        if (template == null) {
            return false;
        }
        // 自己的模板或公开的已发布模板
        return template.getUserId().equals(userId) || 
               (Boolean.TRUE.equals(template.getIsPublic()) && Template.STATUS_PUBLISHED.equals(template.getStatus()));
    }
    
    /**
     * 获取首页统计数据
     */
    public java.util.Map<String, Object> getStats(String userId) {
        java.util.Map<String, Object> stats = new java.util.HashMap<>();
        
        // 获取用户的生成任务数（报告数）
        LambdaQueryWrapper<Generation> generationQuery = new LambdaQueryWrapper<>();
        generationQuery.eq(Generation::getUserId, userId);
        long reportCount = generationRepository.selectCount(generationQuery);
        stats.put("reportCount", reportCount);
        
        // 获取可用模板数（用户自己的 + 公开已发布的）
        LambdaQueryWrapper<Template> templateQuery = new LambdaQueryWrapper<>();
        templateQuery.and(wrapper -> wrapper
                .eq(Template::getUserId, userId)
                .or()
                .and(w -> w.eq(Template::getIsPublic, true).eq(Template::getStatus, Template.STATUS_PUBLISHED))
        );
        long templateCount = templateRepository.selectCount(templateQuery);
        stats.put("templateCount", templateCount);
        
        // 获取变量总数（用户模板中的变量）
        List<Template> userTemplates = templateRepository.selectList(
                new LambdaQueryWrapper<Template>().eq(Template::getUserId, userId));
        long variableCount = 0;
        for (Template t : userTemplates) {
            variableCount += variableRepository.countByTemplateId(t.getId());
        }
        stats.put("variableCount", variableCount);
        
        // 来源文件数
        long sourceFileCount = 0;
        for (Template t : userTemplates) {
            sourceFileCount += sourceFileRepository.selectCount(
                    new LambdaQueryWrapper<SourceFile>().eq(SourceFile::getTemplateId, t.getId()));
        }
        stats.put("sourceFileCount", sourceFileCount);
        
        return stats;
    }
}
