package eu.mhsl.minenet.minigames.lang;

import eu.mhsl.minenet.minigames.Resource;
import net.minestom.server.entity.Player;

import java.io.File;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;

public class Languages {
    private static Languages instance;
    private static final Logger logger = Logger.getLogger("translation");


    private final Map<String, Lang> languages = new HashMap<>();

    public static final String defaultLanguage = "de_de";
    public static Languages getInstance() {
        if(instance == null) instance = new Languages();
        return instance;
    }

    private Languages() {
        readAll();
    }

    public Lang getLanguage(Player p) {
        return getLanguage(p.getSettings().locale().toString()); // TODO funktioniert die locale noch?
    }
    public Lang getLanguage(String mapId) {
        return languages.computeIfAbsent(mapId.toLowerCase(), unused -> languages.computeIfAbsent(defaultLanguage, (key) -> new DummyLang()));
    }

    private void readAll() {
        File locales = new File(Resource.LOCALES.getPath().toString());
        File[] files = Arrays.stream(locales.listFiles(File::canRead)).filter(file -> file.getName().endsWith("map.csv")).toArray(File[]::new);

        if(files.length == 0) {
            logger.warning("Failed to find any Language-files!");
            return;
        }

        for(File locale : files) {
            try {
                logger.info("reading translation " + locale.getName());

                Map<Integer, Lang> langColumn = new HashMap<>();
                String namespace = "";
                boolean computedFileHeader = false;

                for(String line : Files.readAllLines(locale.toPath())) {
                    //line = line.replaceAll("[^\\p{L}\\s,#_+.:;]+", "");
                    line = line.replaceAll("[^a-zA-Z0-9äöüÄÖÜ ,:;#_+]", "");
                    String[] columns = line.split(";");

                    if(columns.length < 1) continue;

                    if(columns[0].endsWith("map")) {
                        // file header
                        computedFileHeader = true;
                        int index = -1;
                        for(String langId : columns) {
                            index++;
                            if(langId.endsWith("map")) continue;

                            languages.computeIfAbsent(langId, Lang::new);
                            Lang lang = languages.get(langId);
                            langColumn.put(index, lang);
                            languages.put(langId, lang);
                        }

                    } else if(columns[0].startsWith("ns:")) {
                        if(!computedFileHeader) throw new IllegalStateException("Cannot compute namespace data before file-header was red!");
                        namespace = columns[0].split(":")[1];

                    } else {

                        // file contents
                        if(!computedFileHeader) throw new IllegalStateException("Cannot compute translation data before file-header was red!");
                        int index = 0;
                        String mapId = "";
                        for(String translation : columns) {
                            if(index == 0) {
                                // store map name
                                mapId = translation;
                            } else {
                                // add map name and value
                                langColumn.get(index).addEntry(namespace + mapId, translation);
                            }

                            index++;
                        }

                    }
                }

            } catch (Exception e) {
                logger.warning("Exception while parsing lang-files: " + e.getMessage());
                e.printStackTrace();
            }

        }
    }
}
