package org.cfpa.i18nupdatemod.resourcepack;

import static org.cfpa.i18nupdatemod.I18nUpdateMod.logger;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.Set;

import org.cfpa.i18nupdatemod.I18nConfig;
import org.cfpa.i18nupdatemod.I18nUtils;
import org.cfpa.i18nupdatemod.download.DownloadInfoHelper;
import org.cfpa.i18nupdatemod.git.ResourcePackRepository;

import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.text.SimpleDateFormat;

import net.minecraft.client.Minecraft;

public class ResourcePackBuilder {
    private File rootPath;
    private File assetFolder;
    private Set<String> modidSet;

    public ResourcePackBuilder() {
        Set<String> modidSet = net.minecraftforge.fml.common.Loader.instance().getIndexedModList().keySet();
        rootPath = new File(Minecraft.getMinecraft().getResourcePackRepository().getDirResourcepacks().toString(),
                I18nConfig.download.i18nLangPackName);
        assetFolder = new File(rootPath, "assets");
        this.modidSet = modidSet;
    }

    public Set<String> getAssetDomains() {
        return AssetMap.instance().getAssetDomains(modidSet);
    }

    public boolean checkUpdate() {
        // TODO 检查资源包是否合法
        if (!(rootPath.exists() || assetFolder.exists())) {
            this.copyResourcePack();
            return true;
        }
        // 超过更新检查时间间隔
        if (longTimeNoUpdate()) {
            return true;
        }
        // 部分asset文件缺失,可能增加了mod
        for (String domain : getAssetDomains()) {
            File assetFolder = getAssetFolder(domain);
            if (!assetFolder.exists()) {
                return true;
            }
        }
        return false;
    }

    private File getAssetFolder(String domain) {
        return new File(assetFolder, domain);
    }

    private boolean longTimeNoUpdate() {
        File f = new File(rootPath, "pack.mcmeta");
        try {
            return (System.currentTimeMillis() - f.lastModified()) > (I18nConfig.download.maxDay * 24 * 3600 * 1000);
        } catch (Throwable e) {
            logger.error("检查文件日期失败", e);
            return true;
        }
    }

    private void copyResourcePack() {
        assetFolder.mkdirs();
        // PNG 图标
        File icon = new File(rootPath, "pack.png");
        if (!icon.exists()) {
            ClassLoader classLoader = this.getClass().getClassLoader();
            InputStream in = classLoader.getResourceAsStream("assets/i18nmod/icon/pack.png");

            try {
                Files.copy(in, icon.toPath(), StandardCopyOption.REPLACE_EXISTING);
            } catch (IOException e) {
                logger.error("Error while copying icon file:", e);
            }
        }
        // pack.mcmeta
        writePackMeta();
    }

    private void writePackMeta() {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateTime = df.format(new Date());
        // 这里给pack.mcmeta加了行注释,测试没问题,但理论上如果是json文件不能加注释
        dateTime = "# 修改时间:" + dateTime;
        File info = new File(rootPath, "pack.mcmeta");
        String meta = "{\n" + "  \"pack\": {\n" + "    \"pack_format\": 3,\n"
                + "    \"description\": \"I18n Update Mod 汉化包\"\n" + "  }\n" + "}\n";
        try {
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(info), StandardCharsets.UTF_8));
            writer.write(dateTime + "\n" + meta);
            writer.flush();
            writer.close();
        } catch (IOException e) {
            logger.error("Error while trying to write pack.mcmeta: ", e);
        }
    }

    public void touch() {
        // 写pack.mcmeta文件,作为更新时间标记
        writePackMeta();
    }

    public void updateAllNeededFilesFromRepo(ResourcePackRepository repo) {
        // TODO 只复制需要更新的文件,可以考虑给copyDir方法加filter
        for (String domain : this.getAssetDomains()) {
            try {
                copyAssetsFromRepo(domain, repo);
            } catch (IOException e) {
                logger.error("Error while updating language file: ", e);
                DownloadInfoHelper.info.add("模组 " + domain + " 的语言文件加载失败,请考虑反馈此问题。");
            }
        }
    }

    private void copyAssetsFromRepo(String domain, ResourcePackRepository repo) throws IOException {
        File from = new File(repo.getLocalPath(), ResourcePackRepository.getSubPathOfAsset(domain));
        File to = new File(this.assetFolder, domain);
        if (from.exists()) {
            I18nUtils.copyDir(from.toPath(), to.toPath());
        } else {
            to.mkdirs();
        }
    }

}