package com.key.coolkeyboard.tool;

import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.StateListDrawable;
import android.os.Build;
import android.provider.Settings;
import android.util.Log;
import android.util.TypedValue;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.anythink.core.api.ATAdInfo;
import com.anythink.core.api.AdError;
import com.anythink.interstitial.api.ATInterstitial;
import com.anythink.interstitial.api.ATInterstitialListener;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.Target;
import com.key.coolkeyboard.CoolKeyboardSkin;
import com.key.coolkeyboard.R;
import com.key.coolkeyboard.callback.DownloadCallback;
import com.key.coolkeyboard.callback.UnzipCallback;
import com.key.coolkeyboard.data.Mydata;
import com.key.coolkeyboard.data.Otherdata;

import net.sf.sevenzipjbinding.ArchiveFormat;
import net.sf.sevenzipjbinding.IInArchive;
import net.sf.sevenzipjbinding.SevenZip;
import net.sf.sevenzipjbinding.impl.RandomAccessFileInStream;
import net.sf.sevenzipjbinding.impl.RandomAccessFileOutStream;
import net.sf.sevenzipjbinding.simple.ISimpleInArchiveItem;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Mytool {

    private static InputMethodManager methodManager = (InputMethodManager) CoolKeyboardSkin.app.getSystemService(Context.INPUT_METHOD_SERVICE);
    private static ExecutorService executorService;








    public static void runIO(Runnable task) {
        getExecutorService().execute(task);
    }

    private static ExecutorService getExecutorService() {
        if (executorService == null) {
            executorService = Executors.newSingleThreadExecutor();
        }
        return executorService;
    }

    public static StateListDrawable getStatus(Drawable draw, Drawable drawPress) {
        StateListDrawable stateListDrawable = new StateListDrawable();
        stateListDrawable.addState(new int[android.R.attr.state_pressed], draw);
        stateListDrawable.addState(new int[0], drawPress);
        return stateListDrawable;

    }

    public static float spToPpx(Float values, Context context) {
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, values, context.getResources().getDisplayMetrics());
    }

    public static String fileToString(File file) throws IOException {
        FileInputStream fileInputStream = new FileInputStream(file);
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fileInputStream));
        StringBuilder stringBuilder = new StringBuilder();
        String lin = "";
        while ((lin = bufferedReader.readLine()) != null) {
            stringBuilder.append(lin);
        }
        bufferedReader.close();
        String con = stringBuilder.toString();
        return con;
    }

    public static void unZip(Context context, String urlpath, File resource, UnzipCallback callback) throws IOException {

        if (!resource.exists()) {
            Toast.makeText(context, context.getString(R.string.text_download_failed), Toast.LENGTH_SHORT).show();
        } else {
            String itemFilePath = "";
            RandomAccessFile accessFile = new RandomAccessFile(resource, "r");
            RandomAccessFileInStream inStream = new RandomAccessFileInStream(accessFile);
            IInArchive iInArchive = SevenZip.openInArchive(ArchiveFormat.SEVEN_ZIP, inStream);

            ISimpleInArchiveItem[] archiveItems = iInArchive.getSimpleInterface().getArchiveItems();
            for (int d = 0; d < archiveItems.length; d++) {
                ISimpleInArchiveItem simple = archiveItems[d];
                File file = new File(urlpath, simple.getPath());
                if (!simple.isFolder()) {
                    RandomAccessFileOutStream outStream = new RandomAccessFileOutStream(new RandomAccessFile(file, "rw"));
                    simple.extractSlow(outStream);
                    itemFilePath = file.getPath();

                } else {
                    boolean mkdirs = file.mkdirs();
                }
            }
            inStream.close();
            iInArchive.close();
            int res = itemFilePath.indexOf("res");
            String substring = itemFilePath.substring(0, res + 3);
            callback.onUnzipCall(true, substring);
        }

    }

    public static void donwnZip(Context context, String url, DownloadCallback callback) {
        Glide.with(context)
                .asFile()
                .load(url)
                .listener(new RequestListener<File>() {
                    @Override
                    public boolean onLoadFailed(@Nullable GlideException e, @Nullable Object model, @NonNull Target<File> target, boolean isFirstResource) {
                        try {
                            callback.onDownloadCall(false, null);
                        } catch (FileNotFoundException ex) {
                            throw new RuntimeException(ex);
                        } catch (IOException ex) {
                            throw new RuntimeException(ex);
                        }
                        return false;
                    }

                    @Override
                    public boolean onResourceReady(@NonNull File resource, @NonNull Object model, Target<File> target, @NonNull DataSource dataSource, boolean isFirstResource) {
                        try {
                            callback.onDownloadCall(true, resource);
                        } catch (FileNotFoundException e) {
                            throw new RuntimeException(e);
                        } catch (IOException e) {
                            throw new RuntimeException(e);
                        }
                        return false;
                    }
                }).preload();
    }

    public static boolean isStep2() {
        String string = Settings.Secure.getString(CoolKeyboardSkin.app.getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
        return string.startsWith(CoolKeyboardSkin.app.getPackageName());
    }

    public static boolean isStep1() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            return methodManager.getEnabledInputMethodList().stream()
                    .anyMatch(inputMethodInfo -> inputMethodInfo.getId().startsWith(CoolKeyboardSkin.app.getPackageName()));
        } else {
            InputMethodManager inputMethodManager = (InputMethodManager) CoolKeyboardSkin.app.getSystemService(Context.INPUT_METHOD_SERVICE);
            List<InputMethodInfo> inputMethodList = inputMethodManager.getEnabledInputMethodList();
            if (inputMethodList != null) {
                for (InputMethodInfo inputMethodInfo : inputMethodList) {
                    if (inputMethodInfo.getId().startsWith(CoolKeyboardSkin.app.getPackageName())) {
                        return true;
                    }
                }
            }
            return false;
        }
    }

    public static int dp2Px(int dp) {
        float scale = CoolKeyboardSkin.getContext().getResources().getDisplayMetrics().density;
        return (int) (dp * scale + 0.5f);
    }

    private static JSONArray loadJSONFromAsset(String filename) {
        String json;
        try {
            AssetManager assetManager = CoolKeyboardSkin.getContext().getAssets();
            InputStream inputStream = assetManager.open(filename);
            int size = inputStream.available();
            byte[] buffer = new byte[size];
            inputStream.read(buffer);
            inputStream.close();
            json = new String(buffer, StandardCharsets.UTF_8);
            return new JSONArray(json);
        } catch (IOException | JSONException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static List<Mydata> parseJsonToList(String filename) {
        List<Mydata> dataList = new ArrayList<>();
        try {
            JSONArray jsonObject = loadJSONFromAsset(filename);
            for (int a = 0; a < jsonObject.length(); a++) {
                JSONObject list = jsonObject.getJSONObject(a);
                Mydata myData = new Mydata();
                List<Otherdata> otherdataList = new ArrayList<>();
                myData.setName(list.getString("className"));
                JSONArray classArray = list.getJSONArray("list");
                for (int i = 0; i < classArray.length(); i++) {
                    JSONObject item = classArray.getJSONObject(i);
                    Otherdata otherdata = new Otherdata();
                    otherdata.setDownloaded(false);
                    otherdata.setIslike(false);
                    otherdata.setClassName(myData.getName());
                    otherdata.setPreview(item.getString("preview"));
                    otherdata.setThumb(item.getString("thumb"));
                    otherdata.setTitle(item.getString("title"));
                    otherdata.setZipUrl(item.getString("zipUrl"));
                    otherdataList.add(otherdata);
                }
                myData.setList(otherdataList);
                dataList.add(myData);
            }

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

        return dataList;
    }


}
