package com.axis.innovators.box.register;

import com.axis.innovators.box.plugins.PluginLoader;
import com.axis.innovators.box.tools.FolderCreator;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.*;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * 语言管理器
 * @author tzdwindows 7
 */
public class LanguageManager {
    private static Language loadedLanguages;
    private static final String LANGUAGE_PATH = FolderCreator.getLanguageFolder();
    private static final List<Language> LANGUAGES = new ArrayList<>();
    private static final String SAVED_LANGUAGE_FILE = LANGUAGE_PATH + "\\saved_language.properties";
    private static final Logger logger = LogManager.getLogger(PluginLoader.class);

    static {
        LANGUAGES.add(new Language("简体中文", "system:zh_CN", "sys_zh_CN"));
        LANGUAGES.add(new Language("繁體中文（台灣）", "system:zh_TW", "sys_zh_TW"));
        LANGUAGES.add(new Language("English (International)", "system:en_US", "sys_en_US"));
        LANGUAGES.add(new Language("日本語", "system:ja_JP", "sys_ja_JP"));
    }

    /**
     * 添加/合并语言资源
     * @param language 要添加的语言对象
     * 处理规则：
     * 1. 注册名相同时保留原有基础信息
     * 2. 相同键值的新内容覆盖旧内容
     * 3. 详细记录新增、更新的键值数量
     * 4. 提供关键示例用于调试
     */
    public static void addLanguage(Language language) {
        for (Language existing : LANGUAGES) {
            if (existing.getRegisteredName().equals(language.getRegisteredName())) {
                try {
                    int added = 0;
                    int updated = 0;
                    Set<String> sampleAddedKeys = new LinkedHashSet<>();
                    Set<String> sampleUpdatedKeys = new LinkedHashSet<>();
                    for (String key : language.properties.stringPropertyNames()) {
                        String newValue = language.properties.getProperty(key);

                        if (existing.properties.containsKey(key)) {
                            updated++;
                            if (sampleUpdatedKeys.size() < 5) {
                                sampleUpdatedKeys.add(key);
                            }
                        } else {
                            added++;
                            if (sampleAddedKeys.size() < 5) {
                                sampleAddedKeys.add(key);
                            }
                        }
                        existing.properties.setProperty(key, newValue);
                    }

                    String logDetail = buildMergeLogDetails(added, updated, sampleAddedKeys, sampleUpdatedKeys);

                    logger.info("【语言合并报告】\n" +
                                    "▌合并目标：{} ({})\n" +
                                    "▌变更统计：新增 {} 条 / 更新 {} 条\n" +
                                    "▌当前总量：{} 条\n" +
                                    "▌关键示例：\n{}",
                            existing.getLanguageName(),
                            existing.getRegisteredName(),
                            added,
                            updated,
                            existing.properties.size(),
                            logDetail);

                    return;
                } catch (Exception e) {
                    logger.error("语言合并异常！注册名：{} - {}",
                            existing.getRegisteredName(),
                            e.getClass().getSimpleName(),
                            e);
                }
                return;
            }
        }

        LANGUAGES.add(language);
        logger.info("【新增语言】{} ({}) 初始加载 {} 条",
                language.getLanguageName(),
                language.getRegisteredName(),
                language.properties.size());
    }

    private static String buildMergeLogDetails(int added, int updated,
                                               Set<String> sampleAdded, Set<String> sampleUpdated) {
        StringBuilder sb = new StringBuilder();

        if (added > 0) {
            sb.append("✦ 新增条目：\n");
            sampleAdded.forEach(k -> sb.append("   ▸ ").append(k).append("\n"));
            if (added > 5) {
                sb.append("   ...(共").append(added).append("条)\n");
            }
        }

        if (updated > 0) {
            sb.append("✦ 更新条目：\n");
            sampleUpdated.forEach(k -> sb.append("   ▸ ").append(k).append("\n"));
            if (updated > 5) {
                sb.append("   ...(共").append(updated).append("条)\n");
            }
        }

        return sb.toString().isEmpty() ? "无内容变更" : sb.toString();
    }

    /**
     * 加载语言
     * @param languageName 语言注册名
     */
    public static void loadLanguage(String languageName) {
        loadedLanguages = LanguageManager.getLanguage(languageName);
        saveCurrentLanguageToFile();
    }

    /**
     * 将当前加载的语言保存到配置文件中
     */
    private static void saveCurrentLanguageToFile() {
        Properties properties = new Properties();
        properties.setProperty("loadedLanguage", loadedLanguages.getRegisteredName());

        try (OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(SAVED_LANGUAGE_FILE), StandardCharsets.UTF_8)) {
            properties.store(writer, "Current Loaded Language");
        } catch (IOException e) {
            System.err.println("Failed to save current language to file: " + SAVED_LANGUAGE_FILE);
            e.printStackTrace();
        }
    }

    /**
     * 从配置文件中加载保存的语言
     */
    public static void loadSavedLanguage() {
        Properties properties = new Properties();
        try (InputStreamReader reader = new InputStreamReader(new FileInputStream(SAVED_LANGUAGE_FILE), StandardCharsets.UTF_8)) {
            properties.load(reader);
            String loadedLanguageName = properties.getProperty("loadedLanguage");
            if (loadedLanguageName != null) {
                loadedLanguages = LanguageManager.getLanguage(loadedLanguageName);
            }
        } catch (IOException e) {
            System.err.println("Failed to load saved language from file: " + SAVED_LANGUAGE_FILE);
            e.printStackTrace();
        }
    }

    /**
     * 获取已加载的语言
     * @return 已加载的语言
     */
    public static Language getLoadedLanguages() {
        return loadedLanguages;
    }

    /**
     * 获取语言
     * @param languageName 语言注册名,或者语言名称
     * @return 语言对象
     */
    public static Language getLanguage(String languageName) {
        for (Language language : LANGUAGES) {
            if (language.getRegisteredName().equals(languageName)) {
                return language;
            }
        }

        for (Language language : LANGUAGES) {
            if (language.getLanguageName().equals(languageName)) {
                return language;
            }
        }
        return null;
    }

    /**
     * 获取所有语言
     * @return 所有语言
     */
    public static List<Language> getLanguages() {
        return LANGUAGES;
    }

    public static class Language {
        private final String languageName;
        private final String registeredName;
        private final String languageFile;
        protected final Properties properties;

        public Language(String languageName,
                        String registeredName,
                        String languageFileName) {
            this.languageName = languageName;
            this.registeredName = registeredName;
            if (languageFileName == null) {
                this.languageFile = LANGUAGE_PATH + "\\" + registeredName + ".properties";
            } else {
                this.languageFile = LANGUAGE_PATH + "\\" + languageFileName + ".properties";
            }
            this.properties = new Properties();
            loadLanguageFile(languageFile);
        }

        /**
         * 加载语言文件
         */
        public void loadLanguageFile(String languageFile) {
            try (InputStreamReader reader = new InputStreamReader(new FileInputStream(languageFile),
                    StandardCharsets.UTF_8)) {
                properties.load(reader);
            } catch (IOException e) {
                System.err.println("Failed to load language file: " + this.languageFile);
                e.printStackTrace();
            }
        }

        /**
         * 获取指定键的文本
         * @param key 键
         * @return 对应的文本，如果键不存在则返回 null
         */
        public String getText(String key) {
            if (!properties.containsKey(key)) {
                return key;
            }
            return properties.getProperty(key);
        }

        /**
         * 添加文本
         */
        public void addText(String key, String value) {
            properties.setProperty(key, value);
        }

        public String getLanguageName() {
            return languageName;
        }

        public String getRegisteredName() {
            return registeredName;
        }

        public File getLanguageFile() {
            return new File(languageFile);
        }
    }
}
