package com.assimilate.alltrans.model;

import android.content.Context;
import android.net.Uri;
import android.text.TextUtils;

import androidx.annotation.NonNull;

import com.assimilate.alltrans.R;
import com.assimilate.alltrans.common.Logger;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

public class LanguagesConstants {
    private static boolean instanced = false;
    private volatile static LanguagesConstants languagesConstant;
    private final Gson gson = new Gson();

    private final ArrayList<Language> languages;

    private LanguagesConstants() {
        synchronized (LanguagesConstants.class) {
            if (instanced) {
                throw new RuntimeException("Instance multiple LanguagesConstants.");
            } else {
                languages = new ArrayList<>();
                instanced = true;
            }

            if (languagesConstant != null) {
                throw new RuntimeException("looper error(LanguagesConstants instanced).");
            }
        }
    }

    public static LanguagesConstants getInstance() {
        if (null == languagesConstant) {
            synchronized (LanguagesConstants.class) {
                if (null == languagesConstant) {
                    languagesConstant = new LanguagesConstants();
                }
            }
        }
        return languagesConstant;
    }

    public ArrayList<Language> getList(@NonNull final Context context) {
        if (languages.isEmpty()) {
            getLanguages(context);
        }
        return languages;
    }

    // 根据语言代码获取 Language 对象
    public Language getLanguageByLanguageCode(@NonNull String languageCode, @NonNull Context context) {
        ArrayList<Language> languages = getList(context);

        if (languageCode.equals("zh")) {
            languageCode = "zh_CN";
        }

        for (Language lang : languages) {
            if (lang.getLanguageCode().equalsIgnoreCase(languageCode)) {
                return lang;
            }
        }

        // 返回一个默认的Language对象，避免返回null
        return getDefaultLanguage();
    }

    // 新增一个方法来获取默认的Language对象
    private Language getDefaultLanguage() {
        // 返回一个你希望的默认语言对象
        return new Language("English", "en","en");
    }

    // 获取 languageCode
    public String getLanguageCodeByLanguage(@NonNull String language, @NonNull Context context) {
        Language lang = getLanguageObjectByLanguage(language, context);
        return lang != null ? lang.getLanguageCode() : "en";
    }

    // 获取 speechCode
    public String getSpeechCodeByLanguage(@NonNull String language, @NonNull Context context) {
        Language lang = getLanguageObjectByLanguage(language, context);
        return lang != null ? lang.getSpeechCode() : "en";
    }

    // 获取 Language 对象
    private Language getLanguageObjectByLanguage(@NonNull String language, @NonNull Context context) {
        ArrayList<Language> languages = getList(context);
        for (Language lang : languages) {
            if (lang.getLanguage().equalsIgnoreCase(language)) {
                return lang;
            }
        }
        return null;
    }

    private void getLanguages(final Context context) {
        InputStream inputStream = null;
        InputStreamReader inputStreamReader = null;
        BufferedReader bufferedReader = null;
        try {
            // step1. 获得语言文件的输入流
            inputStream = context.getResources().openRawResource(R.raw.languages);
            inputStreamReader = new InputStreamReader(inputStream);
            bufferedReader = new BufferedReader(inputStreamReader);

            // step2. 读取json文件信息
            final StringBuilder builder = new StringBuilder();
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                builder.append(line);
            }

            // step3. 将json文本转换成Java对象
            final String result = builder.toString();
            if (!TextUtils.isEmpty(result)) {
                Type listType = new TypeToken<List<Language>>() {
                }.getType();

                List<Language> temp = gson.fromJson(result, listType);
                if (null != temp && !temp.isEmpty()) {
                    languages.clear();
                    for (Language iLanguage : temp) {
                        iLanguage.mFlagUrl = getLanguageFlag(context, iLanguage.getLanguageCode());
                    }
                    languages.addAll(temp);
                }
            }

        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (null != bufferedReader) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if (null != inputStreamReader) {
                try {
                    inputStreamReader.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if (null != inputStream) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            Logger.d("log", "Load languages from configuration successfully.");
        }
    }

    private String getLanguageFlag(final Context context, final String languageCode) {
        final String folderName = Objects.requireNonNull(R.class.getPackage()).getName();
        if (TextUtils.isEmpty(languageCode) || TextUtils.isEmpty(folderName)) {
            return null;
        } else {
            int drawableResourceId = context.getResources().getIdentifier("z_" + languageCode, "mipmap", context.getPackageName());
            if (0 != drawableResourceId) {
                return Uri.parse("android.resource://" + folderName + "/" + drawableResourceId).toString();
            } else {
                return null;
            }
        }
    }
}
