package com.gh.gamecenter.adapter;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.os.Environment;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.RelativeLayout;
import android.widget.TextView;

import androidx.collection.ArrayMap;
import androidx.core.content.ContextCompat;

import com.gh.gamecenter.common.utils.BitmapUtils;
import com.gh.gamecenter.core.utils.MtaHelper;
import com.gh.common.util.PackageInstaller;
import com.gh.common.util.PackageUtils;
import com.gh.gamecenter.core.utils.TimeUtils;
import com.gh.gamecenter.R;
import com.gh.gamecenter.adapter.viewholder.KcSelectGameViewHolder;
import com.gh.gamecenter.databinding.KcGameSelectItemBinding;
import com.gh.gamecenter.entity.InstallGameEntity;
import com.gh.gamecenter.common.retrofit.Response;
import com.lightgame.adapter.BaseRecyclerAdapter;
import com.lightgame.utils.RuntimeUtils;

import java.io.File;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;

/**
 * Created by khy on 2017/1/24.
 */
public class CleanApkAdapter extends BaseRecyclerAdapter<KcSelectGameViewHolder> {

    private static int INSTALLED = 0; // 表示已经安装
    private static int UNINSTALLED = 1; // 表示未安装

    private CheckBox mApkSelectAll;
    private TextView mApkDeleteBtn;

    private OnScanListener mScanListener;

    private List<String> mApkPath;
    private List<InstallGameEntity> mApkList;
    private ArrayMap<Integer, Boolean> mSelectPosition;

    private boolean mIsStopScan;
    private boolean mIsScanOver;
    private boolean mIsChooseApk;

    public CleanApkAdapter(Context context, OnScanListener listener, TextView apkDeleteBtn, CheckBox apkSelectAll, boolean isChooseApk) {
        super(context);
        mApkDeleteBtn = apkDeleteBtn;
        mApkSelectAll = apkSelectAll;
        mIsChooseApk = isChooseApk;

        mScanListener = listener;

        mApkList = new ArrayList<>();
        mSelectPosition = new ArrayMap<>();
        mApkPath = new ArrayList<>();
        mIsStopScan = false;
        mIsScanOver = false;

        init();
    }

    private void init() {
        Observable.create(emitter -> {
                    // 扫描和获取apk数据 分步操作 尽量避免 StackoverflowError
                    FindAllAPKPath(Environment.getExternalStorageDirectory());
                    LoadApkData();
                    emitter.onComplete();
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Response<Object>() {
                    @Override
                    public void onComplete() {
                        super.onComplete();
                        mIsScanOver = true;
                        mScanListener.onScanOver();
                        if (mApkList.size() == 0) {
                            mScanListener.noData();
                        }
                        notifyItemRangeChanged(0, getItemCount());
                    }
                });
    }

    /**
     * 根据apk文件路径检查可用的apk和获取apk数据
     */
    private void LoadApkData() {
        for (String apk_path : mApkPath) {
            InstallGameEntity apkEntity = new InstallGameEntity();
            PackageManager pm = mContext.getApplicationContext().getPackageManager();
            PackageInfo packageInfo = pm.getPackageArchiveInfo(apk_path, 0);
            if (packageInfo == null) continue;

            ApplicationInfo appInfo = packageInfo.applicationInfo;


            /**获取apk的图标 */
            appInfo.sourceDir = apk_path;
            appInfo.publicSourceDir = apk_path;
            Drawable apk_icon = appInfo.loadIcon(pm);
            Bitmap originalBitmap = BitmapUtils.drawableToBitmap(apk_icon, true);
            apkEntity.setGameBm(BitmapUtils.compressBitmap(originalBitmap, 100));
            /** apk的绝对路劲 */
            apkEntity.setGamePath(apk_path);
            /** apk的版本名称 String */
            String versionName = packageInfo.versionName;
            apkEntity.setGameVersion(versionName);

            String apkName = packageInfo.applicationInfo.loadLabel(pm).toString();
            apkEntity.setGameName(apkName);

            File file = new File(apk_path);
            apkEntity.setGameSize(file.length());
            apkEntity.setLastUpdateTime(file.lastModified());
            apkEntity.setPackageName(PackageUtils.getPackageNameByPath(mContext, apk_path));
            apkEntity.setVersionCode(packageInfo.versionCode);
            if (apkEntity.getGamePath() != null && apkEntity.getGamePath().length() > 0) {
                int dot = apkEntity.getGamePath().lastIndexOf('.');
                if ((dot > -1) && (dot < apkEntity.getGamePath().length() - 1)) {
                    apkEntity.setFormat(apkEntity.getGamePath().substring(dot + 1));
                }
            }

            /**安装处理类型*/
            /** 得到包名 */
            String packageName = packageInfo.packageName;
            int type = doType(packageName);
            apkEntity.setInstallStatus(type);

            mApkList.add(apkEntity);
            mSelectPosition.put((mApkList.size() - 1), false);

            RuntimeUtils.getInstance().runOnUiThread(() -> notifyItemChanged((mApkList.size() - 1)));
        }
    }

    /**
     * 扫描内存卡 获取apk文件路径
     *
     * @param file 文件路径
     */
    public void FindAllAPKPath(File file) {

        if (mIsStopScan) {
            return;
        }
        if (file.isFile()) {
//            Utils.log("===== 是文件" + file.getAbsolutePath().toString());
            String name_s = file.getName();
            String apk_path;
            if (name_s.toLowerCase().endsWith(".apk")) {
                apk_path = file.getAbsolutePath();// apk文件的绝对路劲
                mApkPath.add(apk_path);
            }
        } else {
//            Utils.log("===== 是文件夹" + file.getAbsolutePath().toString());
            File[] files = file.listFiles();
            if (files != null && files.length > 0) {
                for (File file_str : files) {
                    FindAllAPKPath(file_str);
                }
            }
        }
    }

    private int doType(String packageName) {
        List<PackageInfo> pakageinfos = PackageUtils.getInstalledPackages(mContext, 0);
        for (PackageInfo pi : pakageinfos) {
            if ((pi.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
                String pi_packageName = pi.packageName;
                //如果这个包名在系统已经安装过的应用中存在
                if (packageName.endsWith(pi_packageName)) {
                    return INSTALLED;
                }
            }
        }
        return UNINSTALLED;
    }


    @Override
    public KcSelectGameViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return new KcSelectGameViewHolder(KcGameSelectItemBinding.inflate(mLayoutInflater, parent, false));
    }

    @Override
    public void onBindViewHolder(final KcSelectGameViewHolder holder, int position) {
        final InstallGameEntity gameEntity = mApkList.get(position);

        double size = (((float) gameEntity.getGameSize() / 1024) / 1024);
        DecimalFormat df = new DecimalFormat("#.00");
        String sizeName = df.format(size) + "MB";

        holder.binding.selectGameCbRl.setVisibility(View.VISIBLE);
        holder.binding.selectGameBtn.setVisibility(View.VISIBLE);
        if (mSelectPosition.get(position)) {
            holder.binding.selectGameBtn.setChecked(true);
        } else {
            holder.binding.selectGameBtn.setChecked(false);
        }

        holder.binding.selectGameNameAndsize.setText(gameEntity.getGameName());

        holder.binding.selectGameThumb.setImageBitmap(gameEntity.getGameBm());

        if (!mIsChooseApk) {
            if (gameEntity.getInstallStatus() == INSTALLED) {
                holder.binding.selectGameSize.setText(R.string.installed);
                holder.binding.selectGameSize.setTextColor(ContextCompat.getColor(mContext, R.color.theme_font));
            } else {
                holder.binding.selectGameSize.setText(R.string.installed_not);
                holder.binding.selectGameSize.setTextColor(ContextCompat.getColor(mContext, R.color.theme_red));
            }
            holder.binding.selectGameDes.setText(mContext.getString(R.string.clean_apk_version, gameEntity.getGameVersion(), sizeName));
            holder.binding.selectGameDes.setTextColor(ContextCompat.getColor(mContext, R.color.content));
        } else {
            holder.binding.selectGameSize.setVisibility(View.GONE);
            RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) holder.binding.selectGameDes.getLayoutParams();
            params.bottomMargin = 0;
            params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
            holder.binding.selectGameDes.setLayoutParams(params);
            String des = TimeUtils.getFormatTime(gameEntity.getLastUpdateTime(), "yyyy-MM-dd HH:mm") + " " + sizeName;
            holder.binding.selectGameDes.setText(des);
        }

        if (mIsScanOver) {
            holder.binding.selectGameBtn.setEnabled(true);
        } else {
            holder.binding.selectGameBtn.setEnabled(false);
        }

        holder.binding.selectGameCbRl.setOnClickListener(v -> {
            if (!mIsChooseApk) {
                if (mSelectPosition.get(holder.getAdapterPosition())) {
                    checkBoxControl(false, holder.getAdapterPosition());
                    holder.binding.selectGameBtn.setChecked(false);
                } else {
                    checkBoxControl(true, holder.getAdapterPosition());
                    holder.binding.selectGameBtn.setChecked(true);
                }
            } else {
                singleChoose(position);
            }
        });

        holder.binding.selectGameBtn.setOnClickListener(v -> {
            if (!mIsChooseApk) {
                if (mSelectPosition.get(holder.getAdapterPosition())) {
                    checkBoxControl(false, holder.getAdapterPosition());
                    holder.binding.selectGameBtn.setChecked(false);
                    MtaHelper.onEvent("我的光环_设置", "安装包清理", "取消选中");
                } else {
                    checkBoxControl(true, holder.getAdapterPosition());
                    holder.binding.selectGameBtn.setChecked(true);
                    MtaHelper.onEvent("我的光环_设置", "安装包清理", "选中");
                }
            } else {
                singleChoose(position);
            }
        });

        holder.itemView.setOnClickListener(v -> {
            if (mIsChooseApk) {
                singleChoose(position);
            } else {
                if (mIsScanOver) {
                    mContext.startActivity(PackageInstaller.getInstallIntent(mContext, gameEntity.getGamePath()));
                }
            }
        });

    }

    public void checkBoxControl(boolean isChecked, int position) {
        if (isChecked) {
            mSelectPosition.put(position, true);
        } else {
            mSelectPosition.put(position, false);
        }

        long gameSize = 0;
        int i = 0;

        if (mApkList.size() == 0) return;
        for (Integer integer : mSelectPosition.keySet()) {
            if (mSelectPosition.get(integer)) {
                gameSize = gameSize + mApkList.get(integer).getGameSize();
                i++;
            }
        }

        if (i == mApkList.size()) {
            mApkSelectAll.setChecked(true);
        } else {
            mApkSelectAll.setChecked(false);
        }

        if (gameSize == 0) {
            mApkDeleteBtn.setText("一键删除");
        } else {
            double size = (((float) gameSize / 1024) / 1024);
            DecimalFormat df = new DecimalFormat("0.00");
            String sizeName = df.format(size) + "MB";
            mApkDeleteBtn.setText(mContext.getString(R.string.clean_apk_deleteall, i, sizeName));
        }
    }

    public void singleChoose(int position) {
        for (Integer integer : mSelectPosition.keySet()) {
            mSelectPosition.put(integer, false);
        }
        mSelectPosition.put(position, true);
        notifyDataSetChanged();
    }

    @Override
    public int getItemCount() {
        return mApkList.size();
    }

    public List<InstallGameEntity> getApkList() {
        return mApkList;
    }

    public ArrayMap<Integer, Boolean> getSelectPosition() {
        return mSelectPosition;
    }

    public void setSelectPosition(ArrayMap<Integer, Boolean> selectPosition) {
        this.mSelectPosition = selectPosition;
    }

    public void isStopScan() {
        this.mIsStopScan = true;
    }

    public void deleteApk(int position) {
        mApkList.remove(position);

        Iterator<Map.Entry<Integer, Boolean>> iterator = mSelectPosition.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<Integer, Boolean> entry = iterator.next();
            Integer key = entry.getKey();

            if (key == position) {
                iterator.remove();
            }
        }

        ArrayMap<Integer, Boolean> newMap = new ArrayMap<>(mSelectPosition);
        for (Integer integer : newMap.keySet()) {
            if (integer > position) {
                int newPosition = integer - 1;
                mSelectPosition.put(newPosition, mSelectPosition.get(integer));
            }
        }

        if (mSelectPosition.size() > mApkList.size()) {
            mSelectPosition.removeAt(mSelectPosition.size() - 1);
        }

        notifyItemRemoved(position);
    }

    public interface OnScanListener {
        void onScanOver();

        void noData();
    }

}
