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;

    @Override
    public String getTemplateConfig() {
        String templateConfig = "";
        try {
            InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("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", "");

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

            ClassInfo classInfo = TableParseUtil.parseTableSql(tableSql, ignorePrefix);
            if (classInfo == null) {
                log.error("解析SQL失败");
                result.put("error", "解析SQL失败");
                return result;
            }

            // 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("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())) {
                    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();
        }
    }
}
