package com.zivilon.cinder_loe.entity;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import com.zivilon.cinder_loe.CinderLoE;

import cpw.mods.fml.common.ModContainer;

public class SpeechBankModifier {

    public static List<String> loadSpeechLines(String speechBankName) {
        String speechPath = "assets/cinder_loe/speech/" + speechBankName + ".txt";
        List<String> lines = new ArrayList<>();
        ZipFile zip = null;

        try {
            ModContainer modContainer = CinderLoE.getModContainer();
            zip = new ZipFile(modContainer.getSource());

            Enumeration<? extends ZipEntry> entries = zip.entries();
            while (entries.hasMoreElements()) {
                ZipEntry entry = entries.nextElement();
                if (entry.getName()
                    .startsWith(speechPath)
                    && entry.getName()
                        .endsWith(".txt")) {
                    InputStream inputStream = zip.getInputStream(entry);
                    BufferedReader reader = new BufferedReader(
                        new InputStreamReader(inputStream, StandardCharsets.UTF_8));

                    String line;
                    while ((line = reader.readLine()) != null) {
                        lines.add(line);
                    }
                    reader.close();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (zip != null) {
                try {
                    zip.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return lines;
    }

    public static Map<String, List<String>> loadSpeechBanks() {
        Map<String, List<String>> speechBanks = new HashMap<>();
        speechBanks.put("renegade/man/hostile", loadSpeechLines("renegade/man/hostile"));
        speechBanks.put("renegade/drunkard/neutral", loadSpeechLines("renegade/drunkard/neutral"));
        speechBanks.put("limwaith/moredain/friendly", loadSpeechLines("limwaith/moredain/friendly"));
        speechBanks.put("limwaith/moredain/hired", loadSpeechLines("limwaith/moredain/hired"));
        speechBanks.put("limwaith/moredain/hostile", loadSpeechLines("limwaith/moredain/hostile"));
        speechBanks.put("limwaith/chieftain/friendly", loadSpeechLines("limwaith/chieftain/friendly"));
        speechBanks.put("limwaith/chieftain/neutral", loadSpeechLines("limwaith/chieftain/neutral"));
        speechBanks.put("limwaith/shaman/friendly", loadSpeechLines("limwaith/shaman/friendly"));
        speechBanks.put("limwaith/shaman/neutral", loadSpeechLines("limwaith/shaman/neutral"));
        speechBanks.put("limwaith/shaman/hostile", loadSpeechLines("limwaith/shaman/hostile"));
        speechBanks.put("arnorSoldier/captain/friendly", loadSpeechLines("arnorSoldier/captain/friendly"));
        speechBanks.put("arnorSoldier/captain/neutral", loadSpeechLines("arnorSoldier/captain/neutral"));
        speechBanks.put("arnorSoldier/soldier/friendly", loadSpeechLines("arnorSoldier/soldier/friendly"));
        speechBanks.put("arnorSoldier/soldier/hired", loadSpeechLines("arnorSoldier/soldier/hired"));
        speechBanks.put("arnorSoldier/soldier/hostile", loadSpeechLines("arnorSoldier/soldier/hostile"));
        speechBanks.put("corruptSpeak/all/neutral", loadSpeechLines("corruptSpeak/all/neutral"));
        speechBanks.put("corruptSpeak/all/hostile", loadSpeechLines("corruptSpeak/all/hostile"));
        speechBanks.put("corruptSpeak/all/skeleton", loadSpeechLines("corruptSpeak/all/skeleton"));
        speechBanks.put("monkey/say", loadSpeechLines("monkey/say"));
        return speechBanks;
    }


    public static void insertSpeechBanks() {
        Map<String, List<String>> speechBanks = loadSpeechBanks();

        try {
            Class<?> lotrSpeechClass = Class.forName("lotr.common.entity.npc.LOTRSpeech");
            Class<?> speechBankClass = Class.forName("lotr.common.entity.npc.LOTRSpeech$SpeechBank");

            Constructor<?> speechBankConstructor = speechBankClass.getDeclaredConstructor(String.class, boolean.class, List.class);
            speechBankConstructor.setAccessible(true);

            Field allSpeechBanksField = lotrSpeechClass.getDeclaredField("allSpeechBanks");
            allSpeechBanksField.setAccessible(true);

            Map<String, Object> allSpeechBanks = (Map<String, Object>) allSpeechBanksField.get(null);

            for (Map.Entry<String, List<String>> entry : speechBanks.entrySet()) {
                Object speechBank = speechBankConstructor.newInstance(entry.getKey(), true, entry.getValue());
                allSpeechBanks.put(entry.getKey(), speechBank);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
