package com.agileboot.codegen.service;

import com.agileboot.codegen.entity.ClassInfo;
import com.agileboot.codegen.entity.UserTemplate;
import com.agileboot.codegen.mapper.UserTemplateMapper;
import com.agileboot.codegen.util.FreemarkerUtil;
import com.agileboot.codegen.util.MapUtil;
import com.agileboot.codegen.util.TableParseUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author cuiJiaWang
 * @Create 2025-09-24 14:31
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class GeneratorServiceImpl implements IGeneratorService {

    private final UserTemplateMapper userTemplateMapper;
    private final IUserTemplateService userTemplateService;

    @Override
    public String getTemplateConfig() {
        String templateConfig = "";
        try {
            InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("wol-module-codegen/src/main/resources/template.json");
            if (inputStream != null) {
                templateConfig = new BufferedReader(new InputStreamReader(inputStream)).lines().collect(Collectors.joining(System.lineSeparator()));
                inputStream.close();
            }
        } catch (IOException e) {
            log.error("读取模板配置失败", e);
        }
        return templateConfig;
    }

    @Override
    public Map<String, String> getResultByParams(Map<String, Object> options) {
        // 使用默认的系统模板配置
        return getResultByParams(options, getTemplateConfig());
    }

    @Override
    public Map<String, String> getResultByParams(Map<String, Object> options, String templateConfig) {
        Map<String, String> result = new HashMap<>();

        try {
            // 1. 解析SQL获取表结构信息
            String tableSql = MapUtil.getString(options, "tableSql");
            String ignorePrefix = MapUtil.getString(options, "ignorePrefix", "");
            String dataType = MapUtil.getString(options, "dataType", "sql");

            if (StringUtils.isBlank(tableSql)) {
                log.error("SQL语句为空");
                result.put("error", "SQL语句不能为空");
                return result;
            }

            // 根据解析引擎类型选择不同的解析方法
            ClassInfo classInfo = null;
            try {
                switch (dataType) {
                    case "sql":
                        classInfo = TableParseUtil.parseTableSql(tableSql, ignorePrefix);
                        break;
                    case "select-sql":
                        log.warn("SELECT SQL解析引擎暂未实现，使用DDL引擎降级处理");
                        result.put("error", "SELECT SQL解析引擎暂未实现，请使用DDL SQL引擎或提供CREATE TABLE语句");
                        return result;
                    case "create-sql":
                        log.warn("CREATE SQL@JSqlParser引擎暂未实现，使用DDL引擎降级处理");
                        result.put("error", "CREATE SQL@JSqlParser引擎暂未实现，请使用DDL SQL@自研引擎");
                        return result;
                    case "json":
                        log.warn("JSON解析引擎暂未实现，使用DDL引擎降级处理");
                        result.put("error", "JSON解析引擎暂未实现，请使用DDL SQL引擎或提供CREATE TABLE语句");
                        return result;
                    case "insert-sql":
                        log.warn("INSERT SQL解析引擎暂未实现，使用DDL引擎降级处理");
                        result.put("error", "INSERT SQL解析引擎暂未实现，请使用DDL SQL引擎或提供CREATE TABLE语句");
                        return result;
                    default:
                        log.warn("未知的解析引擎类型: {}", dataType);
                        classInfo = TableParseUtil.parseTableSql(tableSql, ignorePrefix);
                        break;
                }
            } catch (Exception e) {
                log.error("解析SQL失败，引擎类型: {}", dataType, e);
                result.put("error", "解析SQL失败: " + e.getMessage());
                return result;
            }

            if (classInfo == null) {
                log.error("解析SQL失败，无法获取表结构信息");
                result.put("error", "解析SQL失败，请检查SQL语句格式是否正确");
                return result;
            }

            // 确保classComment不为空，提供默认值
            if (StringUtils.isBlank(classInfo.getClassComment())) {
                classInfo.setClassComment("数据表");
                log.info("表注释为空，使用默认值: 数据表");
            }

            // 2. 设置生成参数
            options.put("classInfo", classInfo);
            options.put("tableName", classInfo.getTableName());
            options.put("authorName", MapUtil.getString(options, "authorName", "Wol"));

            // 3. 根据模板配置生成代码
            JSONArray templateGroups = JSONArray.parseArray(templateConfig);

            for (Object groupObj : templateGroups) {
                JSONObject group = (JSONObject) groupObj;
                String groupName = group.getString("group");
                JSONArray templates = group.getJSONArray("wol-module-codegen/src/main/resources/templates");

                for (Object templateObj : templates) {
                    JSONObject template = (JSONObject) templateObj;
                    String templateId = template.getString("id");
                    String templateName = template.getString("name");
                    String templateSource = template.getString("source");

                    // 生成代码
                    String generatedCode = generateCodeByTemplate(templateId, templateName, templateSource, groupName, options);
                    result.put(templateName, generatedCode);
                }
            }

            // 添加表名信息
            result.put("tableName", classInfo.getTableName());

        } catch (Exception e) {
            log.error("生成代码失败", e);
            result.put("error", "生成代码失败: " + e.getMessage());
        }

        return result;
    }

    /**
     * 根据模板生成代码
     */
    private String generateCodeByTemplate(String templateId, String templateName, String templateSource,
                                        String groupName, Map<String, Object> options) {
        try {
            if ("user".equals(templateSource)) {
                // 用户自定义模板：从数据库获取模板内容
                UserTemplate userTemplate = userTemplateMapper.selectById(Long.valueOf(templateId));
                if (userTemplate != null && StringUtils.isNotBlank(userTemplate.getTemplateContent())) {
                    // 增加使用次数
                    userTemplateService.increaseUseCount(Long.valueOf(templateId));
                    return FreemarkerUtil.generateByContent(userTemplate.getTemplateContent(), options);
                } else {
                    log.warn("用户模板不存在或内容为空: templateId={}", templateId);
                    return "// 用户模板不存在或内容为空: " + templateId;
                }
            } else {
                // 系统模板：从文件系统获取
                String templatePath = groupName + "/" + templateName + ".ftl";
                if (FreemarkerUtil.templateExists(templatePath)) {
                    return FreemarkerUtil.generateByTemplate(templatePath, options);
                } else {
                    log.warn("系统模板文件不存在: {}", templatePath);
                    return "// 系统模板文件不存在: " + templatePath;
                }
            }
        } catch (Exception e) {
            log.error("生成代码失败: templateId={}, templateName={}", templateId, templateName, e);
            return "// 生成失败: " + e.getMessage();
        }
    }

    @Override
    public String getTemplateContentBySource(String templateSource, String templateId) {
        try {
            if ("user".equals(templateSource)) {
                // 用户模板：从数据库获取
                return userTemplateService.getTemplateContent(Long.valueOf(templateId));
            } else if ("system".equals(templateSource)) {
                // 系统模板：从文件系统获取
                return getSystemTemplateContent(templateId);
            } else {
                throw new RuntimeException("不支持的模板来源: " + templateSource);
            }
        } catch (Exception e) {
            log.error("获取模板内容失败: templateSource={}, templateId={}", templateSource, templateId, e);
            throw new RuntimeException("获取模板内容失败: " + e.getMessage());
        }
    }

    /**
     * 获取系统模板内容
     */
    private String getSystemTemplateContent(String templateId) {
        try {
            // 从template.json配置中找到对应模板的文件路径
            JSONArray allTemplates = JSONArray.parseArray(getTemplateConfig());
            for (Object groupObj : allTemplates) {
                JSONObject group = (JSONObject) groupObj;
                String groupName = group.getString("group");
                JSONArray templates = group.getJSONArray("wol-module-codegen/src/main/resources/templates");

                for (Object templateObj : templates) {
                    JSONObject template = (JSONObject) templateObj;
                    if (templateId.equals(template.getString("id"))) {
                        String templateName = template.getString("name");
                        String templatePath = groupName + "/" + templateName + ".ftl";

                        // 读取模板文件内容
                        return FreemarkerUtil.getTemplateContent(templatePath);
                    }
                }
            }
            return "// 系统模板不存在: " + templateId;
        } catch (Exception e) {
            log.error("获取系统模板内容失败", e);
            return "// 获取系统模板内容失败: " + e.getMessage();
        }
    }

    @Override
    public String previewSingleTemplate(String templateSource, String templateId, String templateContent, Map<String, Object> options) {
        try {
            // 1. 解析SQL获取表结构信息
            String tableSql = MapUtil.getString(options, "tableSql");
            String ignorePrefix = MapUtil.getString(options, "ignorePrefix", "");
            String dataType = MapUtil.getString(options, "dataType", "sql");

            if (StringUtils.isBlank(tableSql)) {
                log.error("SQL语句为空");
                return "// 错误: SQL语句不能为空";
            }

            // 根据解析引擎类型选择不同的解析方法
            ClassInfo classInfo = null;
            try {
                switch (dataType) {
                    case "sql":
                        classInfo = TableParseUtil.parseTableSql(tableSql, ignorePrefix);
                        break;
                    case "select-sql":
                        return "// 错误: SELECT SQL解析引擎暂未实现，请使用DDL SQL引擎或提供CREATE TABLE语句";
                    case "create-sql":
                        return "// 错误: CREATE SQL@JSqlParser引擎暂未实现，请使用DDL SQL@自研引擎";
                    case "json":
                        return "// 错误: JSON解析引擎暂未实现，请使用DDL SQL引擎或提供CREATE TABLE语句";
                    case "insert-sql":
                        return "// 错误: INSERT SQL解析引擎暂未实现，请使用DDL SQL引擎或提供CREATE TABLE语句";
                    default:
                        log.warn("未知的解析引擎类型: {}, 使用默认DDL引擎", dataType);
                        classInfo = TableParseUtil.parseTableSql(tableSql, ignorePrefix);
                        break;
                }
            } catch (Exception e) {
                log.error("解析SQL失败，引擎类型: {}", dataType, e);
                return "// 错误: 解析SQL失败: " + e.getMessage();
            }

            if (classInfo == null) {
                log.error("解析SQL失败，无法获取表结构信息");
                return "// 错误: 解析SQL失败，请检查SQL语句格式是否正确";
            }

            // 确保classComment不为空，提供默认值
            if (StringUtils.isBlank(classInfo.getClassComment())) {
                classInfo.setClassComment("数据表");
                log.info("表注释为空，使用默认值: 数据表");
            }

            // 2. 设置生成参数
            options.put("classInfo", classInfo);
            options.put("tableName", classInfo.getTableName());
            options.put("authorName", MapUtil.getString(options, "authorName", "Wol"));

            // 3. 根据模板来源生成代码
            String generatedCode;

            switch (templateSource.toLowerCase()) {
                case "user":
                    // 用户自定义模板：从数据库获取模板内容
                    UserTemplate userTemplate = userTemplateMapper.selectById(Long.valueOf(templateId));
                    if (userTemplate != null && StringUtils.isNotBlank(userTemplate.getTemplateContent())) {
                        // 增加使用次数
                        userTemplateService.increaseUseCount(Long.valueOf(templateId));
                        generatedCode = FreemarkerUtil.generateByContent(userTemplate.getTemplateContent(), options);
                    } else {
                        log.warn("用户模板不存在或内容为空: templateId={}", templateId);
                        generatedCode = "// 用户模板不存在或内容为空: " + templateId;
                    }
                    break;

                case "system":
                    // 系统模板：需要根据templateId查找对应的模板文件
                    generatedCode = generateSystemTemplate(templateId, options);
                    break;

                case "content":
                    // 直接使用提供的模板内容
                    if (StringUtils.isNotBlank(templateContent)) {
                        generatedCode = FreemarkerUtil.generateByContent(templateContent, options);
                    } else {
                        generatedCode = "// 错误: 模板内容为空";
                    }
                    break;

                default:
                    generatedCode = "// 错误: 不支持的模板来源: " + templateSource;
                    break;
            }

            return generatedCode;

        } catch (Exception e) {
            log.error("预览模板失败: templateSource={}, templateId={}", templateSource, templateId, e);
            return "// 预览失败: " + e.getMessage();
        }
    }

    /**
     * 生成系统模板代码
     */
    private String generateSystemTemplate(String templateId, Map<String, Object> options) {
        try {
            // 从系统模板配置中查找对应的模板信息
            String templateConfig = getTemplateConfig();
            JSONArray templateGroups = JSONArray.parseArray(templateConfig);

            for (Object groupObj : templateGroups) {
                JSONObject group = (JSONObject) groupObj;
                String groupName = group.getString("group");
                JSONArray templates = group.getJSONArray("wol-module-codegen/src/main/resources/templates");

                for (Object templateObj : templates) {
                    JSONObject template = (JSONObject) templateObj;
                    String id = template.getString("id");
                    String name = template.getString("name");

                    if (templateId.equals(id)) {
                        // 找到对应的模板，生成代码
                        String templatePath = groupName + "/" + name + ".ftl";
                        if (FreemarkerUtil.templateExists(templatePath)) {
                            return FreemarkerUtil.generateByTemplate(templatePath, options);
                        } else {
                            log.warn("系统模板文件不存在: {}", templatePath);
                            return "// 系统模板文件不存在: " + templatePath;
                        }
                    }
                }
            }

            return "// 系统模板不存在: " + templateId;

        } catch (Exception e) {
            log.error("生成系统模板失败: templateId={}", templateId, e);
            return "// 生成系统模板失败: " + e.getMessage();
        }
    }
}
