package com.yutou.jianr_mg.Tools;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

import com.alibaba.fastjson.JSON;
import com.kaopiz.kprogresshud.KProgressHUD;
import com.yutou.jianr_mg.Application;
import com.yutou.jianr_mg.Data.AppData;
import com.yutou.jianr_mg.Data.MGamePackname;
import com.yutou.jianr_mg.Data.TMod;
import com.yutou.jianr_mg.Data.TModfile;
import com.yutou.jianr_mg.Databases.ModDatabase;
import com.yutou.jianr_mg.Interfaces.DownloadInterface;
import com.yutou.jianr_mg.Interfaces.HttpInterface;
import com.yutou.jianr_mg.Interfaces.ModInterface;
import com.yutou.jianr_mg.Network.HttpApi;
import com.yutou.jianr_mg.Network.HttpUtils;
import com.yutou.jianr_mg.services.DownloadService;
import com.yutou.jianr_mg.services.MagicBoxService;

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

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import Interfaces.MagicBoxInterface;
import me.drakeet.materialdialog.MaterialDialog;


/**
 * Created by 58381 on 2018/2/2.
 */

public class ModUtils {
    private static final int MOD_INSTALL = 1;
    public static final int MOD_BACKUP = 2;
    private static final int MOD_UNINSTALL = 3;

    private static final String TAG = "ModUtils";
    private static ModUtils modUtils;
    private ModDatabase database;
    private Context context;
    private Handler handler;
    private List<TModfile> modfiles;
    private KProgressHUD hud;
    private TMod mod;

    public static ModUtils init(Context context) {
        System.out.println("调用魔改管理器");
        try {
            if (modUtils == null) {
                modUtils = new ModUtils();
                modUtils.database = ModDatabase.init();
            }
            modUtils.setContext(context);
        }catch (Exception e){
            e.printStackTrace();
        }

        return modUtils;
    }

    private void setContext(Context context) {
        this.context = context;
        handler.post(()->{
            hud = Utils.showLoading(context, "安装中", "请稍后");
        });

    }

    private ModUtils() {
        handler = new Handler(Looper.getMainLooper());
    }

    public void setMod(TMod mod) {
        this.mod = mod;
        getModDownloadInfo();
    }

    public List<TModfile> getModfiles() {
        return modfiles;
    }

    private void setModfiles(List<TModfile> modfiles) {
        this.modfiles = modfiles;
    }

    public void installMod(TMod mod, ModInterface modInterface) {
        this.mod = mod;
        if (modfiles != null && modfiles.size() > 0 && !mod.getId().equals(modfiles.get(0).getMid())) {
            modfiles.clear();
            getModDownloadInfo();
        }
        if (modInterface == null) {
            modInterface = (flag, type) -> {

            };
        }
        install(modInterface);
    }

    private void install(ModInterface modInterface) {
        if (modfiles == null) {
            KProgressHUD hud = Utils.showLoading(context, "加载中", "请稍后");
            hud.show();
            getModDownloadInfo();
            handler.postDelayed(() -> {
                hud.dismiss();
                install(modInterface);
            }, 1000);
            return;
        }
        if(database.getModVersion(mod)<mod.getModversion()){
            downloadMod();
            return;
        }
        if (changeMod(mod, modfiles) && !isInstallMod(mod)) {
            install(mod, modInterface);
        } else if (isInstallMod(mod)) {
            MaterialDialog dialog = new MaterialDialog(context);
            dialog.setTitle("安装?还原?");
            dialog.setMessage("检测到已经安装了本mod，是继续安装到其他客户端还是还原呢？");
            dialog.setNegativeButton("还原", view -> {
                reBackMod(mod, modInterface);
                dialog.dismiss();
            });
            dialog.setPositiveButton("安装", view -> {
                install(mod, modInterface);
                dialog.dismiss();
            });
            dialog.show();
        } else {
            boolean flag_a=getModPath(mod,"",true).listFiles().length > 0;
            boolean flag_b=!changeMod(mod, modfiles);
            if (flag_a && flag_b) {
                final MaterialDialog dialog = new MaterialDialog(context);
                dialog.setTitle("mod已损失");
                dialog.setMessage("当前mod文件有缺失，是否重新下载？");
                dialog.setPositiveButton("确定", view -> {
                    downloadMod();
                    dialog.dismiss();
                });
                dialog.setNegativeButton("算了", view -> dialog.dismiss());
                dialog.show();
            } else {
                downloadMod();
            }
        }
    }
    private MGamePackname packname;
    private void install(final TMod mod, final ModInterface modInterface) {
        List<String> clientList = new ArrayList<>();
        for (MGamePackname packname : AppData.packnames) {
            clientList.add(packname.getZhname() + "(" + packname.getPackname() + ")");
        }
        final MaterialDialog dialog = new MaterialDialog(context);
        dialog.setTitle("选择安装客户端");
        ListView listView = new ListView(context);
        listView.setAdapter(new ArrayAdapter<>(context, android.R.layout.simple_list_item_1, clientList));
        listView.setOnItemClickListener((adapterView, view, i, l) -> {
            packname = AppData.packnames.get(i);
            hud.show();
            boolean isRoot = false;
            ModUtils.this.i=0;
            srcs.clear();
            paths.clear();
            for (TModfile modfile : modfiles) {
                File file = getModPath(mod, modfile.getFilename(), false);
                if (packname.getZhname().contains("[ROOT]")) {
                    if (!RootUtils.su()) {
                        hud.dismiss();
                        final MaterialDialog dialog1 = new MaterialDialog(context);
                        dialog1.setTitle("错误");
                        dialog1.setMessage("未获取到ROOT权限\n提示：魔改专用端可免ROOT使用魔改，以及更多功能\t提示2：如果您确实有ROOT权限，请前往安全中心手动赋予盒子权限");
                        dialog1.setPositiveButton("确定", view1 -> dialog1.dismiss());
                        dialog1.setNegativeButton("下载魔改专用客户端", view12 -> dialog1.dismiss());
                        dialog1.show();
                        modInterface.onAction(false, MOD_INSTALL);
                        return;
                    }
                    isRoot = true;
                    backupOrRoot(file, "/data/data/" + packname.getPackname() + modfile.getInstallpathid(), packname.getPackname(), mod);
                    rootInstall(file, "/data/data/" + packname.getPackname() + modfile.getInstallpathid());
                } else {
                    isRoot = false;
                    notRootInstall(file,  modfile.getInstallpathid());
                }
            }
            if(srcs.size()>0) {
                boolean finalIsRoot = isRoot;
                File file=new File(Utils.getAppPath()+"/"+modfiles.get(0).getMid()+"/backup/"+packname.getPackname());
                if(!file.exists()) {
                    file.mkdirs();
                }
                notRootInstallStart(new ModInterface() {
                    @Override
                    public void onAction(boolean flag, int type) {
                        hud.dismiss();
                        dialog.dismiss();
                        Utils.toast(context, "安装成功,重启游戏生效");
                        modInterface.onAction(true, MOD_INSTALL);
                        packname.setRoot(finalIsRoot);
                        database.addInstallMod(mod, packname);
                    }
                },file.listFiles().length==0);
            }else {
                hud.dismiss();
                dialog.dismiss();
                Utils.toast(context, "安装成功,重启游戏生效");
                modInterface.onAction(true, MOD_INSTALL);
                packname.setRoot(isRoot);
                database.addInstallMod(mod, packname);
            }
        });
        dialog.setContentView(listView);
        dialog.setPositiveButton("放弃", view -> {
            modInterface.onAction(false, MOD_INSTALL);
            dialog.dismiss();
        });
        dialog.show();
    }
    private List<File> srcs=new ArrayList<>();
    private List<String> paths=new ArrayList<>();
    private int i=0;
    public void notRootInstall(File src, String path) {
        if (src.exists()) {
            try{
                srcs.add(src);
                paths.add(path);

            }catch (Exception e){
                e.printStackTrace();
            }
         //   Utils.copyFile(src.getAbsolutePath(), path, true);
        } else {
            Log.i(TAG, "找不到文件：" + src.getAbsolutePath());
        }
    }
    public void notRootInstallStart(ModInterface modInterface,boolean isBackup){
        try{
            if(i==srcs.size()){
                MagicBoxService.init().clearOrder();
                modInterface.onAction(true,0);
                return;
            }
            JSONObject order=new JSONObject();
            order.put("action","copy");
            if(isBackup) {
                order.put("args", new String[]{"files:" + paths.get(i).replace("/files/","")+srcs.get(i).getName(),
                        srcs.get(i).getAbsolutePath().replace(srcs.get(i).getName(), "backup/" + packname.getPackname() + "/" + srcs.get(i).getName())});
            }else{
                order.put("args",new String[]{srcs.get(i).getAbsolutePath(),"files:" + paths.get(i).replace("/files/","")+srcs.get(i).getName()});
            }
           MagicBoxService service= MagicBoxService.init();
            if(service==null){
                Utils.toast(Application.application,"没有安装专用客户端");
                modInterface.onAction(false,0);
                return;
            }
            service.setOrder(order, data -> { //先备份
                try {
                    if(!isBackup){//如果不需要备份则按照安装逻辑进行
                        i++;
                        MagicBoxService.init().clearOrder();
                        notRootInstallStart(modInterface,false);
                        return;
                    }
                    order.put("action","copy");
                    order.put("args",new String[]{srcs.get(i).getAbsolutePath(),"files:" + paths.get(i).replace("/files/","")+srcs.get(i).getName()});
                    i++;
                    MagicBoxService.init().setOrder(order, data2 -> {//再安装
                        MagicBoxService.init().clearOrder();
                        notRootInstallStart(modInterface,true);
                    });
                }catch (Exception e){
                    e.printStackTrace();
                    modInterface.onAction(false,0);
                }
            });


        }catch (Exception e){
            e.printStackTrace();
            modInterface.onAction(false,0);
        }
    }

    private void rootInstall(File src, String path) {

        RootUtils root = RootUtils.init(context);
        if (RootUtils.su()) {
            File tmpFile = new File("/data/data/" + context.getPackageName() + "/mods/");
            if (!tmpFile.getParentFile().exists())
                tmpFile.getParentFile().mkdirs();
            if (tmpFile.exists())
                tmpFile.delete();
            Utils.copyFile(src.getAbsolutePath(), tmpFile.getAbsolutePath(), true);
            root.exec("mkdir -p " + path);
            root.exec("cp -f " + tmpFile.getAbsolutePath() + "/" + src.getName() + " " + path);
            root.exec("chmod 777 " + path + src.getName());
        }
    }

    public void reBackMod(TMod tMod, final ModInterface modInterface) {
        final MaterialDialog dialog = new MaterialDialog(context);
        dialog.setTitle("将还原 " + tMod.getTitle());
        final List<MGamePackname> clientList = database.getInstallClients(tMod);
        List<String> titles = new ArrayList<>();
        for (MGamePackname packname : clientList) {
            titles.add("[" + (packname.isRoot() ? "ROOT" : "免ROOT") + "]" + packname.getZhname());
        }
        ListView listView = new ListView(context);
        listView.setAdapter(new ArrayAdapter<>(context, android.R.layout.simple_list_item_1, titles));
        listView.setOnItemClickListener((adapterView, view, i, l) -> {
            MGamePackname packageName=clientList.get(i);
            if (packageName.isRoot()) {
                RootUtils root = RootUtils.init(context);
                for (TModfile modfile : modfiles) {
                    if (getModPath(mod, "backup/" + packageName.getPackname() + "/" + modfile.getFilename(), false).exists()) {
                        root.exec("cp -f " + getModInstallPath(mod) + "backup/" +packageName.getPackname() + "/" + modfile.getFilename() + " " + "/data/data/" + packageName.getPackname() + modfile.getInstallpathid());
                        root.exec("chmod 777 " + "/data/data/" + packageName.getPackname() + modfile.getInstallpathid());
                    } else {
                        root.exec("rm -f " + "/data/data/" + packageName.getPackname() + modfile.getInstallpathid() + modfile.getFilename());
                    }
                }
                if (modInterface != null)
                    modInterface.onAction(true, MOD_UNINSTALL);
                dialog.dismiss();
                Utils.toast(context, "还原成功,重启游戏生效");
                database.backInstaMod(tMod, clientList.get(i).getPackname());
            } else {
                ModUtils.this.i=0;
                srcs.clear();
                paths.clear();
                for (TModfile modfile : modfiles) {
                    File file=new File(Utils.getAppPath()+"/"+modfile.getMid()+"/backup/"+packageName.getPackname()+"/"+modfile.getFilename());
                    String path=modfile.getInstallpathid();
                    notRootInstall(file,path);
                }
                notRootInstallStart((flag, type) -> {
                    if (modInterface != null)
                        modInterface.onAction(true, MOD_UNINSTALL);
                    dialog.dismiss();
                    Utils.toast(context, "还原成功,重启游戏生效");
                    database.backInstaMod(tMod, clientList.get(i).getPackname());
                },false);
            }

        });
        dialog.setContentView(listView);
        dialog.setNegativeButton("放弃", view -> {
            if (modInterface != null)
                modInterface.onAction(false, MOD_UNINSTALL);
            dialog.dismiss();
            ;
        });
        dialog.show();

    }

    private void backupOrRoot(File srcFile, String srcPath, String backupClient, TMod mod) {
        RootUtils root = RootUtils.init(context);
        if (RootUtils.su()) {
            File backup = getModPath(mod, "backup/" + backupClient, true);
            File file = new File(backup.getAbsolutePath() + "/" + srcFile.getName());
            if (file.exists()) {
                return;
            }
            Utils.toast(null, file.getAbsolutePath());
            File tmpFile = new File("/data/data/" + context.getPackageName() + "/mods/" + srcFile.getName());
            if (tmpFile.exists())
                tmpFile.delete();
            tmpFile.getParentFile().mkdirs();
            root.exec("mkdir -p " + srcPath);
            root.exec("chmod 777 " + srcPath + srcFile.getName());
            root.exec("cp -f " + srcPath + srcFile.getName() + " " + file.getAbsolutePath());
            root.println("cp -f " + tmpFile.getAbsolutePath() + " " + file.getAbsolutePath());
        }else{
            handler.post(() -> Utils.toast(context,"没有ROOT权限，无法进行操作"));
        }
    }

    private void downloadMod() {
        database.downloadMod(mod);
        Toast.makeText(context, "开始下载", Toast.LENGTH_LONG).show();
        Intent intent = new Intent(context.getApplicationContext(), DownloadService.class);
        intent.setPackage(context.getPackageName());
        boolean isBindService = context.getApplicationContext().bindService(intent, new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
                DownloadService.ServiceBinder binder = (DownloadService.ServiceBinder) iBinder;
                DownloadService service = binder.getService(new DownloadInterface() {
                    @Override
                    public void getDownloadList(int size) {

                    }

                    @Override
                    public void getDownloadFile(TModfile modfile) {

                    }

                    @Override
                    public void getDownloadFileSize(int size) {

                    }

                    @Override
                    public void getCurrent(int current) {

                    }

                    @Override
                    public void over() {

                    }

                    @Override
                    public void start() {

                    }
                });
                service.start(modfiles);

            }

            @Override
            public void onServiceDisconnected(ComponentName componentName) {
                Log.i("下载服务", "绑定失败：" + componentName);
            }
        }, Context.BIND_AUTO_CREATE);
        Log.i("绑定下载：", isBindService + "");
    }

    private void getModDownloadInfo() {
        modfiles = null;
        try {
            JSONObject json = new JSONObject();
            json.put("mid", mod.getId());
            json.put("uid", AppData.user.getId());
            HttpUtils.post(HttpApi.HOME_URL + HttpApi.MOD_DOWNLOAD, json, new HttpInterface() {
                @Override
                public void httpGetData(String string, int code) {
                    try {
                        JSONObject json = new JSONObject(string);
                        if (json.getInt("code") == 100) {
                            modfiles = JSON.parseArray(json.getJSONArray("data").toString(), TModfile.class);
                            for (int i = 0; i < modfiles.size(); i++) {
                                modfiles.get(i).setMod(mod);
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void httpError(Exception e) {

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

    public static String getModInstallPath(TMod mod) {
        return Utils.getAppPath() + "/" + mod.getId() + "/";
    }

    public static boolean isInstallMod(TMod mod) {
        ModDatabase database = ModDatabase.init();
        return database.isInstallMod(mod);
    }

    public static boolean changeMod(TMod mod, List<TModfile> modfiles) {
        for (TModfile modfile : modfiles) {
            if (!new File(Utils.getAppPath() + "/" + mod.getId() + "/" + modfile.getFilename()).exists()) {
                Log.i(TAG, "mod不完整:" + Utils.getAppPath() + "/" + mod.getId() + "/" + modfile.getFilename());
                Log.i(TAG, JSON.toJSONString(modfile));
                return false;
            }
        }
        return true;
    }

    public static File getModPath(TMod mod) {
        return getModPath(mod, "", false);
    }

    public static File getModPath(TMod mod, String name, boolean isCreate) {
        File path = new File(Utils.getAppPath() + "/" + mod.getId() + "/" + name);
        if (isCreate && !path.exists()) {
            path.mkdirs();
        }
        return path;
    }
}
