package cn.garymb.ygomobile;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Point;
import android.text.TextUtils;
import android.util.Log;
import android.view.WindowManager;

import org.json.JSONArray;

import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;

import cn.garymb.ygomobile.lite.R;
import cn.garymb.ygomobile.ui.preference.PreferenceFragmentPlus;
import cn.garymb.ygomobile.utils.DeckUtil;
import cn.garymb.ygomobile.utils.IOUtils;

import static cn.garymb.ygomobile.Constants.CORE_DECK_PATH;
import static cn.garymb.ygomobile.Constants.CORE_EXPANSIONS;
import static cn.garymb.ygomobile.Constants.CORE_PACK_PATH;
import static cn.garymb.ygomobile.Constants.CORE_REPLAY_PATH;
import static cn.garymb.ygomobile.Constants.CORE_SYSTEM_PATH;
import static cn.garymb.ygomobile.Constants.DEF_PREF_FONT_SIZE;
import static cn.garymb.ygomobile.Constants.DEF_PREF_KEEP_SCALE;
import static cn.garymb.ygomobile.Constants.DEF_PREF_NOTCH_HEIGHT;
import static cn.garymb.ygomobile.Constants.DEF_PREF_ONLY_GAME;
import static cn.garymb.ygomobile.Constants.DEF_PREF_READ_EX;
import static cn.garymb.ygomobile.Constants.PREF_DEF_IMMERSIVE_MODE;
import static cn.garymb.ygomobile.Constants.PREF_DEF_SENSOR_REFRESH;
import static cn.garymb.ygomobile.Constants.PREF_FONT_SIZE;
import static cn.garymb.ygomobile.Constants.PREF_IMMERSIVE_MODE;
import static cn.garymb.ygomobile.Constants.PREF_KEEP_SCALE;
import static cn.garymb.ygomobile.Constants.PREF_LOCK_SCREEN;
import static cn.garymb.ygomobile.Constants.PREF_NOTCH_HEIGHT;
import static cn.garymb.ygomobile.Constants.PREF_ONLY_GAME;
import static cn.garymb.ygomobile.Constants.PREF_READ_EX;
import static cn.garymb.ygomobile.Constants.PREF_SENSOR_REFRESH;
import static cn.garymb.ygomobile.Constants.WINDBOT_DECK_PATH;
import static cn.garymb.ygomobile.Constants.WINDBOT_PATH;
import static cn.garymb.ygomobile.Constants.YDK_FILE_EX;

public class AppsSettings {
    private static final String PREF_VERSION = "app_version";
    private static AppsSettings sAppsSettings;
    private final Point mScreenSize = new Point();
    private final Point mRealScreenSize = new Point();
    private Context context;
    private PreferenceFragmentPlus.SharedPreferencesPlus mSharedPreferences;
    private float mDensity;

    private AppsSettings(Context context) {
        this.context = context;
        mSharedPreferences = PreferenceFragmentPlus.SharedPreferencesPlus.create(context, context.getPackageName() + ".settings");
        mSharedPreferences.setAutoSave(true);
        Log.e("YGOMobileLog", "初始化类地址:  " + System.identityHashCode(this));
        update(context);
    }

    public static void init(Context context) {
        if (sAppsSettings == null) {
            sAppsSettings = new AppsSettings(context);
        }
    }

    public static AppsSettings get() {
        return sAppsSettings;
    }

    public File getSystemConfig() {
        return new File(getResourcePath(), CORE_SYSTEM_PATH);
    }

    public void update(Context context) {
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        //应用尺寸
        wm.getDefaultDisplay().getSize(mScreenSize);
        //屏幕尺寸
        wm.getDefaultDisplay().getRealSize(mRealScreenSize);
        mDensity = context.getResources().getDisplayMetrics().density;
    }

    public int getAppVersion() {
        return mSharedPreferences.getInt(PREF_VERSION, 0);
    }

    public void setAppVersion(int ver) {
        mSharedPreferences.putInt(PREF_VERSION, ver);
    }

    public PreferenceFragmentPlus.SharedPreferencesPlus getSharedPreferences() {
        return mSharedPreferences;
    }

    public float getSmallerSize() {
        float w = getScreenWidth();
        float h = getScreenHeight();
        return h < w ? h : w;
    }

    public boolean isDialogDelete() {
        return true;// mSharedPreferences.getBoolean(PREF_DECK_DELETE_DILAOG, PREF_DEF_DECK_DELETE_DILAOG);
    }

    public int getNotchHeight() {
        return mSharedPreferences.getInt(PREF_NOTCH_HEIGHT, DEF_PREF_NOTCH_HEIGHT);
    }

    public void setNotchHeight(int height) {
        mSharedPreferences.putInt(PREF_NOTCH_HEIGHT, height);
    }

    public int getFontSize() {
        return mSharedPreferences.getInt(PREF_FONT_SIZE, DEF_PREF_FONT_SIZE);
    }

    public boolean isOnlyGame() {
        return mSharedPreferences.getBoolean(PREF_ONLY_GAME, DEF_PREF_ONLY_GAME);
    }

    /***
     * 是否使用额外卡库
     */
    public boolean isReadExpansions() {
        return mSharedPreferences.getBoolean(PREF_READ_EX, DEF_PREF_READ_EX);
    }

    public float getXScale(int w, int h) {
        if (isKeepScale()) {
            float sx = getScreenHeight() / w;
            float sy = getScreenWidth() / h;
            return Math.min(sx, sy);
        }
        return getScreenHeight() / w;
    }

    public float getYScale(int w, int h) {
        if (isKeepScale()) {
            //固定比例，取最小值
            float sx = getScreenHeight() / w;
            float sy = getScreenWidth() / h;
            return Math.min(sx, sy);
        }
        return getScreenWidth() / h;
    }

    public boolean isKeepScale() {
        return mSharedPreferences.getBoolean(PREF_KEEP_SCALE, DEF_PREF_KEEP_SCALE);
    }

    public float getScreenWidth() {
        int w, h;
        if (isImmerSiveMode()) {
            w = mRealScreenSize.x;
            h = mRealScreenSize.y;
        } else {
            w = mScreenSize.x;
            h = mScreenSize.y;
        }
        return Math.min(w, h);
    }

    public float getScreenHeight() {
        int w, h;
        if (isImmerSiveMode()) {
            w = mRealScreenSize.x;
            h = mRealScreenSize.y;
        } else {
            w = mScreenSize.x;
            h = mScreenSize.y;
        }
        int ret = Math.max(w, h);
        if (isImmerSiveMode()) {
            //刘海高度
            ret -= getNotchHeight();
        }
        return ret;
    }

    /**
     * 游戏配置
     */
    public NativeInitOptions getNativeInitOptions() {
        NativeInitOptions options = new NativeInitOptions();
        options.mWorkPath = getResourcePath();
        makeCdbList(options.mDbList);
        makeZipList(options.mArchiveList);
        options.mCardQuality = getCardQuality();
        options.mIsFontAntiAliasEnabled = isFontAntiAlias();
        options.mIsPendulumScaleEnabled = isPendulumScale();
        options.mOpenglVersion = getOpenglVersion();
        if (Constants.DEBUG) {
            Log.i("Irrlicht", "option=" + options);
        }
        return options;
    }

    public File getDataBaseFile() {
        return new File(getDataBasePath(), Constants.DATABASE_NAME);
    }

    private void makeCdbList(List<String> pathList) {
        if (isReadExpansions()) {
            File expansionsDir = getExpansionsPath();
            if (expansionsDir.exists()) {
                File[] cdbs = expansionsDir.listFiles(file -> {
                    return file.isFile() && file.getName().toLowerCase(Locale.US).endsWith(".cdb");
                });
                if (cdbs != null) {
                    try {
                        Arrays.sort(cdbs, (file, t1) -> {
                            return file.getName().compareTo(t1.getName());
                        });
                    } catch (Exception e) {
                        //
                    }
                    for (File file : cdbs) {
                        //if (CardManager.checkDataBase(file)) {
                        //合法数据库才会加载
                        pathList.add(file.getAbsolutePath());
                        //}
                    }
                }
            }
        }
        pathList.add(getDataBaseFile().getAbsolutePath());
    }

    public File getExpansionsPath() {
        return new File(getResourcePath(), CORE_EXPANSIONS);
    }

    private void makeZipList(List<String> pathList) {
        if (isReadExpansions()) {
            File expansionsDir = getExpansionsPath();
            if (expansionsDir.exists()) {
                File[] zips = expansionsDir.listFiles(new FileFilter() {
                    @Override
                    public boolean accept(File file) {
                        return file.isFile() && file.getName().toLowerCase(Locale.US).endsWith(".zip");
                    }
                });
                if (zips != null) {
                    for (File file : zips) {
                        pathList.add(file.getAbsolutePath());
                    }
                }
                File[] ypks = expansionsDir.listFiles(new FileFilter() {
                    @Override
                    public boolean accept(File file) {
                        return file.isFile() && file.getName().toLowerCase(Locale.US).endsWith(".ypk");
                    }
                });
                if (ypks != null) {
                    for (File file : ypks) {
                        pathList.add(file.getAbsolutePath());
                    }
                }
            }
        }
        pathList.add(new File(getResourcePath(), Constants.CORE_PICS_ZIP).getAbsolutePath());
        pathList.add(new File(getResourcePath(), Constants.CORE_SCRIPTS_ZIP).getAbsolutePath());
    }

    /***
     * 决斗助手
     */
    public boolean isServiceDuelAssistant() {
        return mSharedPreferences.getBoolean(Constants.PREF_START_SERVICEDUELASSISTANT, Constants.PREF_DEF_START_SERVICEDUELASSISTANT);
    }

    public void setServiceDuelAssistant(boolean serviceDuelAssiatant) {
        mSharedPreferences.putBoolean(Constants.PREF_START_SERVICEDUELASSISTANT, serviceDuelAssiatant);
    }

    /***
     * 摇摆数字
     */
    public boolean isPendulumScale() {
        return mSharedPreferences.getBoolean(Constants.PREF_PENDULUM_SCALE, Constants.PREF_DEF_PENDULUM_SCALE);
    }

    /***
     * 摇摆数字
     */
    public void setPendulumScale(boolean pendulumScale) {
        mSharedPreferences.putBoolean(Constants.PREF_PENDULUM_SCALE, pendulumScale);
    }

    /***
     * opengl版本
     */
    public int getOpenglVersion() {
        try {
            return Integer.valueOf(mSharedPreferences.getString(Constants.PREF_OPENGL_VERSION, "" + Constants.PREF_DEF_OPENGL_VERSION));
        } catch (Exception e) {
            return Constants.PREF_DEF_OPENGL_VERSION;
        }
    }

    /***
     * opengl版本
     */
    public void setOpenglVersion(int openglVersion) {
        mSharedPreferences.putString(Constants.PREF_OPENGL_VERSION, "" + openglVersion);
    }

    /***
     * 字体抗锯齿
     */
    public boolean isFontAntiAlias() {
        return mSharedPreferences.getBoolean(Constants.PREF_FONT_ANTIALIAS, Constants.PREF_DEF_FONT_ANTIALIAS);
    }

    /***
     * 字体抗锯齿
     */
    public void setFontAntiAlias(boolean fontAntiAlias) {
        mSharedPreferences.putBoolean(Constants.PREF_FONT_ANTIALIAS, fontAntiAlias);
    }

    /***
     * 图片质量
     */
    public int getCardQuality() {
        try {
            return Integer.valueOf(mSharedPreferences.getString(Constants.PREF_IMAGE_QUALITY, "" + Constants.PREF_DEF_IMAGE_QUALITY));
        } catch (Exception e) {
            return Constants.PREF_DEF_IMAGE_QUALITY;
        }
    }

    /***
     * 图片质量
     */
    public void setCardQuality(int quality) {
        mSharedPreferences.putString(Constants.PREF_IMAGE_QUALITY, "" + quality);
    }


    /**
     * 根据卡密获取卡图的路径
     *
     * @param code 卡密
     * @return
     */
    public String getCardImagePath(int code) {
        return new File(getCardImagePath(), code + ".jpg").getAbsolutePath();
    }

    /***
     * 图片文件夹
     */
    public String getCardImagePath() {
        return new File(getResourcePath(), Constants.CORE_IMAGE_PATH).getAbsolutePath();
    }

    /***
     * log文件夹
     */
    public String getMobileLogPath() {
        return new File(getResourcePath(), Constants.MOBILE_LOG).getAbsolutePath();
    }

    /***
     * 卡组分享图片文件夹
     */
    public String getDeckSharePath() {
        return new File(getResourcePath(), Constants.MOBILE_DECK_SHARE).getAbsolutePath();
    }

    /***
     * 当前数据库文件夹
     */
    public String getDataBasePath() {
        if (isUseExtraCards()) {
            return getResourcePath();
        } else {
            //返回游戏根目录，即ygocore文件夹
            return getResourcePath();
            // return getDataBaseDefault();
        }
    }

    public boolean isLockSreenOrientation() {
        return mSharedPreferences.getBoolean(PREF_LOCK_SCREEN, Constants.PREF_DEF_LOCK_SCREEN);
    }

    public void setLockSreenOrientation(boolean lockSreenOrientation) {
        mSharedPreferences.putBoolean(PREF_LOCK_SCREEN, lockSreenOrientation);
    }

    /***
     * 内置数据库文件夹
     */
    @SuppressLint("WrongConstant")
    public String getDataBaseDefault() {
        return context.getDir("game", Context.MODE_MULTI_PROCESS).getPath();
    }

    /***
     * 是否优先使用外置数据
     */
    public boolean isUseExtraCards() {
        return mSharedPreferences.getBoolean(Constants.PREF_USE_EXTRA_CARD_CARDS, Constants.PREF_DEF_USE_EXTRA_CARD_CARDS);
    }

    /***
     * 设置是否优先使用外置数据
     */
    public void setUseExtraCards(boolean useExtraCards) {
        mSharedPreferences.putBoolean(Constants.PREF_USE_EXTRA_CARD_CARDS, useExtraCards);
    }

    public String getSoundPath() {
        return new File(getResourcePath(), Constants.CORE_SOUND_PATH).getAbsolutePath();
    }

    public String getCoreSkinPath() {
        return new File(getResourcePath(), Constants.CORE_SKIN_PATH).getAbsolutePath();
    }

    /***
     * 字体路径
     */
    public String getFontPath() {
        return mSharedPreferences.getString(Constants.PREF_GAME_FONT, getFontDefault());
    }

    /***
     * 字体路径
     */
    public void setFontPath(String font) {
        mSharedPreferences.putString(Constants.PREF_GAME_FONT, font);
    }

    /**
     * 默认字体
     */
    private String getFontDefault() {
        return new File(getFontDirPath(), Constants.DEFAULT_FONT_NAME).getAbsolutePath();
    }

    /***
     * 字体目录
     */
    public String getFontDirPath() {
        return new File(getResourcePath(), Constants.FONT_DIRECTORY).getAbsolutePath();
    }

    /***
     * 游戏根目录
     */
    public String getResourcePath() {
        String defPath;
        defPath = new File(String.valueOf(context.getExternalFilesDir(Constants.PREF_DEF_GAME_DIR))).getAbsolutePath();
        return mSharedPreferences.getString(Constants.PREF_GAME_PATH, defPath);
    }

    public void setResourcePath(String path) {
        if (TextUtils.equals(path, getResourcePath())) return;
        mSharedPreferences.putString(Constants.PREF_GAME_PATH, path);
    }

    /**
     * @return 录像文件夹
     */
    public String getReplayDir() {
        return new File(getResourcePath(), CORE_REPLAY_PATH).getAbsolutePath();
    }

    //获取卡组文件夹
    public String getDeckDir() {
        return new File(getResourcePath(), CORE_DECK_PATH).getAbsolutePath();
    }

    //获取ai卡组文件夹
    public String getAiDeckDir() {
        return new File(getResourcePath(), WINDBOT_PATH + "/Decks").getAbsolutePath();
    }

    //获取新卡卡包文件夹
    public String getPackDeckDir() {
        return new File(getResourcePath(), "pack").getAbsolutePath();
    }

    //获取临时存放卡组的目录
    public String getCacheDeckDir() {
        return context.getExternalFilesDir("cacheDeck").getAbsolutePath();
    }

    //获取残局文件夹
    public String getSingleDir() {
        return new File(getResourcePath(), Constants.CORE_SINGLE_PATH).getAbsolutePath();
    }

    /**
     * 隐藏底部导航栏
     */
    public boolean isImmerSiveMode() {
        return mSharedPreferences.getBoolean(PREF_IMMERSIVE_MODE, PREF_DEF_IMMERSIVE_MODE);
    }

    public boolean isSensorRefresh() {
        return mSharedPreferences.getBoolean(PREF_SENSOR_REFRESH, PREF_DEF_SENSOR_REFRESH);
    }

    public String getCurLastDeck() {
        return mSharedPreferences.getString(Constants.PREF_DEF_LAST_YDK, null);
    }

    //获得最后卡组绝对路径
    public String getLastDeckPath() {
        String path;
        if (TextUtils.equals(context.getString(R.string.category_pack), getLastCategory())) {
            path = getResourcePath() + "/" + CORE_PACK_PATH + "/" + getLastDeckName() + YDK_FILE_EX;
        } else if (TextUtils.equals(context.getString(R.string.category_windbot_deck), getLastCategory())) {
            path = getResourcePath() + "/" + WINDBOT_PATH + "/" + WINDBOT_DECK_PATH + "/" + getLastDeckName() + YDK_FILE_EX;
        } else if (TextUtils.equals(context.getString(R.string.category_Uncategorized), getLastCategory())) {
            path = getResourcePath() + "/" + CORE_DECK_PATH + "/" + getLastDeckName() + YDK_FILE_EX;
        } else {
            path = getResourcePath() + "/" + CORE_DECK_PATH + "/" + getLastCategory() + "/" + getLastDeckName() + YDK_FILE_EX;
        }
        Log.e("Appsettings", "拼接最后路径" + path);
        return path;
    }

    //保存最后卡组绝对路径、分类、卡组名
    public void setLastDeckPath(String path) {
        Log.e("Appsettings", "设置最后路径" + path);
        if (TextUtils.equals(path, getLastDeckPath())) {
            //一样
            return;
        }
        //保存最后分类名
        mSharedPreferences.putString(Constants.PREF_LAST_CATEGORY, DeckUtil.getDeckTypeName(path));
        //保存最后卡组名
        File lastDeck = new File(path);
        String lastDeckName = IOUtils.tirmName(lastDeck.getName(), YDK_FILE_EX);
        mSharedPreferences.putString(Constants.PREF_LAST_YDK, lastDeckName);
    }

    //获得最后分类名
    public String getLastCategory() {
        return mSharedPreferences.getString(Constants.PREF_LAST_CATEGORY, Constants.PREF_DEF_LAST_CATEGORY);
    }

    //获得最后卡组名
    public String getLastDeckName() {
        return mSharedPreferences.getString(Constants.PREF_LAST_YDK, Constants.PREF_DEF_LAST_YDK);
    }

    public void saveIntSettings(String key, int value) {
        mSharedPreferences.putInt(Constants.PREF_START + key, value);
    }

    public int getIntSettings(String key, int def) {
        int v = mSharedPreferences.getInt(Constants.PREF_START + key, def);
        if (v == def) {
            Log.d("kk", "default " + key + "=" + getVersionString(v));
        }
        return v;
    }
    /* public int resetGameVersion() {
   *   int version = GameConfig.getVersion();
   *    if (getIntSettings(Constants.PREF_GAME_VERSION, 0) == 0) {
   *        //用户没设置过版本号
   *        return version;
   *    }
   *    saveIntSettings(Constants.PREF_GAME_VERSION, GameConfig.getVersion());
   *    return version;
   * }
   *
   *  public int getGameVersion() {
   *     return getIntSettings(Constants.PREF_GAME_VERSION, GameConfig.getVersion());
   *}
   *
   * public void setGameVersion(int v) {
   *    saveIntSettings(Constants.PREF_GAME_VERSION, v);
    }*/

    public String getVersionString(int value) {
        int last = (value & 0xf);
        int m = ((value >> 4) & 0xff);
        int b = ((value >> 12) & 0xff);
        return String.format("%X.%03X.%X", b, m, last);
    }

   /* public int getVersionValue(String str) {
        str = str.trim().toLowerCase(Locale.US);
        int v = -1;
        if(str.contains(".")){
            String[] vas = str.split("\\.");
            if(vas.length<3){
                return -1;
            }
            try {
                int last = Integer.parseInt(vas[2]);
                int m = Integer.parseInt(vas[1])<<4;
                int b = Integer.parseInt(vas[0])<<12;
                v = last+m+b;
            }catch (Exception e){

            }
        }else{
            try {
                if (str.startsWith("0x")) {
                    str = str.substring(2);
                }
                v = Integer.parseInt(str, 16);
            } catch (Exception e) {
            }
        }
        return v;
    }*/

    public void saveSettings(String key, String value) {
        if ("lastdeck".equals(key)) {
            Log.e("AppSettings", value);
            mSharedPreferences.putString(Constants.PREF_LAST_YDK, value);
        } else if ("lastcategory".equals(key)) {
            Log.e("AppSettings", value);
            mSharedPreferences.putString(Constants.PREF_LAST_CATEGORY, value);
        } else {
            mSharedPreferences.putString(Constants.PREF_START + key, value);
        }
    }

    public String getSettings(String key) {
        String val;
        if ("lastdeck".equals(key)) {
            val = getLastDeckName();
            return val;
        } else if ("lastcategory".equals(key)) {
            val = getLastCategory();
            return val;
        }
        return mSharedPreferences.getString(Constants.PREF_START + key, null);
    }

    public List<String> getLastRoomList() {
        List<String> names = new ArrayList<>();
        String json = mSharedPreferences.getString(Constants.PREF_LAST_ROOM_LIST, null);
        if (!TextUtils.isEmpty(json)) {
            try {
                JSONArray array = new JSONArray(json);
                int count = array.length();
                for (int i = 0; i < count; i++) {
                    names.add(array.optString(i));
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
//        Log.i("kk", "read:" + names);
        return names;
    }

    public void setLastRoomList(List<String> _names) {
        JSONArray array = new JSONArray();
        if (_names != null) {
            int count = _names.size();
            int max = Math.min(count, Constants.LAST_ROOM_MAX);
            for (int i = 0; i < max; i++) {
                array.put(_names.get(i));
            }
        }
//        Log.i("kk", "saveTemp:" + array);
        mSharedPreferences.putString(Constants.PREF_LAST_ROOM_LIST, array.toString());
    }
}
