package cn.liujson.appupdatedemo;

import android.app.AlertDialog;
import android.app.PendingIntent;
import android.app.TaskStackBuilder;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.IdRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

import com.rxjava.rxlife.RxLife;

import app.update.rxhttp.RxHttp;
import cn.liujson.app.update.AppUpdateManager;
import cn.liujson.app.update.listener.OnProgressListener;
import cn.liujson.app.update.listener.OnProgressWrapperListener;
import cn.liujson.app.update.service.ApkDownloadService;
import cn.liujson.appupdatedemo.bean.ApkUpdateInfoDetailResult;
import cn.liujson.appupdatedemo.bean.ApkUpdateInfoResult;
import io.reactivex.android.schedulers.AndroidSchedulers;

/**
 * @author liujson
 * @date 2020/8/6.
 */
public class AppUpdateFragment extends Fragment implements AppUpdateView, View.OnClickListener {

    private static final String TAG = "AppUpdateFragment";

    private View rootView;

    private TextView tvInfo;
    private ProgressBar mProgressBar;
    private TextView tvRate;
    private Button btnCheckUpdate;

    private String checkUrl;
    private String destPath;



    private ApkDownloadService.ApkDownloadBinder apkDownloadBinder;

    /**
     * "/sdcard/test/testUpdate.apk"
     * "http://192.168.1.181:8090/static/app/app-release.apk"
     *
     * @param checkUrl 检查接口url
     * @param destPath 保存apk的路径
     * @return
     */
    public static AppUpdateFragment newInstance(String checkUrl,String destPath){
        Bundle bundle = new Bundle();
        bundle.putString("checkUrl",checkUrl);
        bundle.putString("destPath",destPath);
        AppUpdateFragment appUpdateFragment = new AppUpdateFragment();
        appUpdateFragment.setArguments(bundle);
        return appUpdateFragment;
    }


    private OnProgressListener mOnProgressListener = new OnProgressWrapperListener() {
        @Override
        public void onProgress(int progress, int maxProgress) {
            mProgressBar.setProgress((int) progress);
            tvRate.setText(progress + "%");
        }
    };

    private ServiceConnection mServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            apkDownloadBinder = (ApkDownloadService.ApkDownloadBinder) service;
            apkDownloadBinder.addOnProgressListener(mOnProgressListener);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            apkDownloadBinder.removeOnProgressListener(mOnProgressListener);
        }
    };

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Bundle arguments = getArguments();
        checkUrl = arguments.getString("checkUrl");
        destPath = arguments.getString("destPath");
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        rootView = inflater.inflate(R.layout.fragment_app_update,container,false);
        tvInfo = findViewById(R.id.tv_info);
        mProgressBar = findViewById(R.id.m_progress_bar);
        tvRate = findViewById(R.id.tv_rate);

        btnCheckUpdate = findViewById(R.id.btn_check_update);

        btnCheckUpdate.setOnClickListener(this);

        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("包名:").append(getContext().getPackageName()).append('\n')
                .append("版本名：").append(AppUpdateManager.Utils.getAppVersionName(getContext())).append('\n')
                .append("版本：").append(AppUpdateManager.Utils.getAppVersionCode(getContext())).append('\n');
        tvInfo.setText(stringBuffer.toString());
        ApkDownloadService.bindService(getContext(), mServiceConnection);
        return rootView;
    }


    @SuppressWarnings("UnclearExpression")
    public final <T extends View> T findViewById(@IdRes int resId){
        return rootView==null?null:(T)rootView.findViewById(resId);
    }

    @Override
    public void onAppCheckUpdateFail(Throwable throwable) {
        Toast.makeText(getContext(), "检查更新失败，请检查您的网络连接", Toast.LENGTH_LONG).show();
    }

    @Override
    public void onAppNotRequiredUpdate() {
        Toast.makeText(getContext(), "当前为最新版本", Toast.LENGTH_LONG).show();
    }

    @Override
    public void onAppNeedUpdate(final ApkUpdateInfoDetailResult detailResult) {
        new AlertDialog.Builder(getContext())
                .setTitle("温馨提示")
                .setMessage("系统检测到有新版本(" + detailResult.getVersionName() + "),是否立即更新?")
                .setPositiveButton("立即更新", (d, i) -> {
                    appUpdateNow(detailResult.getSourceUrl());
                })
                .setNegativeButton("取消", null)
                .show();
    }

    private void appUpdateNow(String sourceUrl) {
        if(TextUtils.isEmpty(sourceUrl)){
            Toast.makeText(getContext(), "应用资源路径为空，下载失败", Toast.LENGTH_LONG).show();
            return;
        }
        mProgressBar.setProgress(0);
        // Create an Intent for the activity you want to start
        Intent resultIntent = new Intent(getContext(), MainActivity.class);
        // Create the TaskStackBuilder and add the intent, which inflates the back stack
        TaskStackBuilder stackBuilder = TaskStackBuilder.create(getContext());
        stackBuilder.addNextIntentWithParentStack(resultIntent);
        // Get the PendingIntent containing the entire back stack
        PendingIntent resultPendingIntent =
                stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
        AppUpdateManager appUpdateManager = new AppUpdateManager.Builder()
                .destPath(destPath)
                .onProgressListener(mOnProgressListener)
                .notifyIntent(resultPendingIntent)
                .sourceUrl(sourceUrl).build();

        appUpdateManager.download(getContext());
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.btn_check_update:
                checkClick(v);
                break;
            default:
                break;
        }

    }

    /**
     * 检查更新
     *
     * @param view
     */
    public void checkClick(View view) {
        if(!AppUpdateManager.Utils.checkInstallUnknownAppSources(getContext())){
            return;
        }
        if(TextUtils.isEmpty(checkUrl)){
            Toast.makeText(getContext(), "检查路径不能为空", Toast.LENGTH_LONG).show();
            return;
        }
        if(TextUtils.isEmpty(destPath)){
            Toast.makeText(getContext(), "下载路径不能为空", Toast.LENGTH_LONG).show();
            return;
        }
        final View btn = view;
        btn.setEnabled(false);
        RxHttp.get(checkUrl)
                .asClass(ApkUpdateInfoResult.class)
                .observeOn(AndroidSchedulers.mainThread())
                .as(RxLife.as(this))
                .subscribe(data -> {
                    btn.setEnabled(true);
                    Log.d(TAG, data.toString());
                    //判断是否需要更新
                    ApkUpdateInfoDetailResult apkUpdateInfoDetailResult = data.getData();
                    if (data.getCode() != 0 || apkUpdateInfoDetailResult == null) {
                        onAppCheckUpdateFail(new RuntimeException("检查更新失败或返回数据为空"));
                        return;
                    }
                    if (AppUpdateManager.Utils.isNeedUpdate(getContext(), apkUpdateInfoDetailResult.getVersion())) {
                        //需要更新
                        onAppNeedUpdate(apkUpdateInfoDetailResult);
                    } else {
                        //不需要更新
                        onAppNotRequiredUpdate();
                    }
                }, throwable -> {
                    btn.setEnabled(true);
                    Log.d(TAG, "throwable: " + throwable.getMessage());
                    onAppCheckUpdateFail(throwable);
                });
    }
}
