package com.ygtx.emcs.update;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Resources.NotFoundException;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.StrictMode;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;

import androidx.annotation.RequiresApi;
import androidx.core.content.FileProvider;

import com.ygtx.emcs.R;
import com.ygtx.emcs.util.ProjectUtils;
import com.ygtx.emcs.util.StringUtils;
import com.ygtx.emcs.util.ToastUtils;
import com.ygtx.emcs.util.VersionUtils;

import org.apache.log4j.Logger;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.List;

public class UpdateManager {

	private static final String TAG = "UpdateManager";
	private static String FILE_NAME = "ygtx_wms.apk";
	/* 下载中 */
	private static final int DOWNLOAD = 1;
	/* 下载结束 */
	private static final int DOWNLOAD_FINISH = 2;
	/* 下载结束 */
	private static final int ERROR = 3;
	/* 保存解析的XML信息 */
	HashMap<String, String> mHashMap;
	/* 下载保存路径 */
	private String mSavePath;
	/* 记录进度条数量 */
	private int progress;
	/* 是否取消更新 */
	private boolean cancelUpdate = false;

	private Context mContext;

	// 下载文件大小
	private String fileSize;
	// 已下载文件大小
	private String tmpFileSize;

	/* 更新进度条 */
	private ProgressBar mProgress;
	private TextView mProgressText;
	private AlertDialog mDownloadDialog;
	private Dialog mShowDialog;
	public static Logger mylog =Logger.getLogger(UpdateManager.class);
	public String next_version;

	/* 通知栏 */
	private NotificationManager updateNotificationManager = null;
	private Notification updateNotification = null;

	/* 通知栏跳转Intent */
	private Intent updateIntent = null;
	private PendingIntent updatePendingIntent = null;

	private final Handler mHandler = new Handler(Looper.myLooper()) {
		@SuppressLint("HandlerLeak")
		@RequiresApi(api = Build.VERSION_CODES.O)
		public void handleMessage(Message msg) {
			switch (msg.what) {
				// 正在下载
				case DOWNLOAD:
					// 设置进度条位置
					if(mProgress!=null){
						mProgress.setProgress(progress);
						mProgressText.setText(tmpFileSize + "/" + fileSize);
					}
					break;
				case DOWNLOAD_FINISH:
					// 安装文件
//					install();
					ToastUtils.showToastL(mContext, "下载完成，开始安装");
					installApk();
					break;
				case ERROR:
					// 构造对话框
					ToastUtils.showToast(mContext,"文件下载失败: "+ msg.obj.toString());
//					try {
//						checkUpdate();
//					}catch (Exception ex){
//						ex.printStackTrace();
//					}
					break;
				default:
					break;
			}
		}
	};

	public UpdateManager(Context context) {
		this.mContext = context;
	}

	public UpdateManager(Context context, HashMap<String,String> mHashMap) {
		this.mContext = context;
		this.mHashMap = mHashMap;
	}

	/**
	 * 检测软件更新
	 *
	 * @throws Exception
	 * @throws NotFoundException
	 */
//	@RequiresApi(api = Build.VERSION_CODES.O)
	public void checkUpdate(Context context) throws Exception {
		if (isUpdate()) {
			if(!StringUtils.isEmpty(next_version)){
				ToastUtils.showToastL(mContext, "更新到版本"+next_version);
			}
			ProjectUtils.init(context);
			showDownloadDialog();
//			downloadApk();
		}
	}

	/**
	 * 检查软件是否有更新版本
	 *
	 * @return
	 * @throws Exception
	 */
	@SuppressLint("NewApi")
	public boolean isUpdate() throws Exception {
		// 获取当前软件版本
		try {
			int versionCode = VersionUtils.getVersionCode(mContext);
			UpdateXmlService service = new UpdateXmlService();
			String path = ProjectUtils.getProjectURL() + "/version.xml";
			URL url = new URL(path);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setReadTimeout(5 * 1000);
			conn.setConnectTimeout(3000);
			conn.setRequestMethod("GET");
			StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
					.permitAll().build();
			StrictMode.setThreadPolicy(policy);
			InputStream inStream = conn.getInputStream();
			mHashMap = service.parseXml(inStream);
			if (null != mHashMap) {
				int serviceCode = Integer.valueOf(mHashMap.get("version"));
				// 版本判断
				if (serviceCode > versionCode) {
					next_version = mHashMap.get("version_name");
					return true;
				}
			}
			return false;
		} catch (SocketTimeoutException ex){
//			ToastUtils.showToast(mContext, "连接超过");
			mylog.error("连接超过:", ex);
		} catch (Exception e) {
			Log.e(TAG, "meth:isUpdate");
			throw e;
		}
		return false;
	}


	/**
	 * 显示软件下载对话框
	 */
	public void showDownloadDialog() {
		// 构造软件下载对话框
		Builder builder = new Builder(mContext);
		builder.setTitle(R.string.soft_update);
		// 给下载对话框增加进度条
		final LayoutInflater inflater = LayoutInflater.from(mContext);
		View v = inflater.inflate(R.layout.softupdate_progress, null);
		mProgress = (ProgressBar) v.findViewById(R.id.update_progress);
		mProgressText = (TextView) v.findViewById(R.id.update_progress_text);
		builder.setView(v);
		// 取消更新
		builder.setNegativeButton(R.string.soft_update_cancel,(dialog,which)-> {
			cancelUpdate = true;
			dialog.dismiss();
		});
		builder.setPositiveButton(R.string.sure,null);
		mDownloadDialog = builder.create();
		mDownloadDialog.setCancelable(false);
		mDownloadDialog.setCanceledOnTouchOutside(false);
		mDownloadDialog.show();
		mDownloadDialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
			public void onClick(View v){
				downloadApk();
				v.setVisibility(View.GONE);
			}
		});
	}

	/**
	 * 下载apk文件
	 */
	private void downloadApk() {
		// 启动新线程下载软件
		new downloadApkThread().start();
	}

	/**
	 * 下载文件线程
	 */
	private class downloadApkThread extends Thread {
		@Override
		public void run() {
			try {
				// 判断SD卡是否存在，并且是否具有读写权限
				if (Environment.getExternalStorageState().equals(
						Environment.MEDIA_MOUNTED)) {
					// 获得存储卡的路径
//					File path = Environment.getExternalStorageDirectory();
				//	mSavePath = mContext.getExternalCacheDir().getAbsolutePath();

					URL url = new URL(ProjectUtils.getProjectURL()
							+ mHashMap.get("url") + "/" + mHashMap.get("name"));
					FILE_NAME = mHashMap.get("name");
					mSavePath= ProjectUtils.APK;
//					URL url = new URL(ip + "/shares/android/"
//							+ mHashMap.get("url")+"/"+mHashMap.get("name"));
					// 创建连接
					HttpURLConnection conn = (HttpURLConnection) url
							.openConnection();
					conn.setRequestProperty("Accept-Encoding", "identity");
					conn.connect();
					// 获取文件大小
					int length = conn.getContentLength();
					// 显示文件大小格式：2个小数点显示
					DecimalFormat df = new DecimalFormat("0.00");
					fileSize = df.format((float) length / 1024 / 1024)
							+ "MB";
					// 创建输入流
					InputStream is = conn.getInputStream();

					File file = new File(mSavePath);
					// 判断文件目录是否存在
					if (!file.exists()) {
						file.mkdir();
					}else {
						try {
							for (File f : file.listFiles()) {
								f.delete();
							}
						}catch (Exception e){
							e.printStackTrace();
						}
					}
					File apkFile = new File(mSavePath, FILE_NAME);
					FileOutputStream fos = new FileOutputStream(apkFile);
					int count = 0;
					// 缓存
					byte buf[] = new byte[1024];
					// 写入到文件中
					do {
						int numread = is.read(buf);
						count += numread;
						// 计算进度条位置
						tmpFileSize = df.format((float) count / 1024 / 1024)
								+ "MB";
						progress = (int) (((float) count / length) * 100);
						// 更新进度
						mHandler.sendEmptyMessage(DOWNLOAD);
						if (numread <= 0) {
							// 下载完成
							mHandler.sendEmptyMessage(DOWNLOAD_FINISH);
							break;
						}
						// 写入文件
						fos.write(buf, 0, numread);
					} while (!cancelUpdate);// 点击取消就停止下载.
					fos.close();
					is.close();
				}

			} catch (Exception e) {
				e.printStackTrace();
				mylog.error("文件下载失败：", e);
				Message msg = new Message();
				msg.what = ERROR;
				msg.obj = e.getMessage();
				mHandler.sendMessage(msg);
			}
			// 取消下载对话框显示
			mDownloadDialog.dismiss();
		}
	};

	/**
	 * 安装APK文件
	 */
	private void installApk() {
		File apkfile = null;
		for (int i = 0;i<5;i++) {
			apkfile = new File(mSavePath, FILE_NAME);
			if (!apkfile.exists()) {
				try {
					Thread.sleep(1000);
				}catch (Exception e){
					e.printStackTrace();
				}
			}else{
				break;
			}
		}
		if (!apkfile.exists()) {
			ToastUtils.showToast(mContext,"文件不存在");
			return;
		}
//		openAssignFolder(mSavePath);
		// 通过Intent安装APK文件
		Intent install = new Intent(Intent.ACTION_VIEW);
		install.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
			String applicationId = mContext.getPackageName();
			install.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
			Uri apkUri = FileProvider.getUriForFile(mContext, applicationId + ".fileprovider", apkfile);//在AndroidManifest中的android:authorities值
			install.setDataAndType(apkUri, "application/vnd.android.package-archive");
			// 查询所有符合 intent 跳转目标应用类型的应用，注意此方法必须放置在 setDataAndType 方法之后
			List<ResolveInfo> resolveLists = mContext.getPackageManager().queryIntentActivities(install, PackageManager.MATCH_DEFAULT_ONLY);
			// 然后全部授权
			for (ResolveInfo resolveInfo : resolveLists){
				String packageName = resolveInfo.activityInfo.packageName;
				mContext.grantUriPermission(packageName, apkUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
			}
		} else {
			install.setDataAndType(Uri.fromFile(apkfile), "application/vnd.android.package-archive");
		}
		mContext.startActivity(install);
	}

	/* 卸载apk */
	public static void uninstallApk(Context context, String packageName) {
		Uri uri = Uri.parse("package:" + packageName);
		Intent intent = new Intent(Intent.ACTION_DELETE, uri);
		context.startActivity(intent);
	}

	public void install(){
		File apkfile = null;
		try {
			for (int i = 0; i < 5; i++) {
				apkfile = new File(mSavePath, FILE_NAME);
				if (!apkfile.exists()) {
					try {
						Thread.sleep(1000);
					} catch (Exception e) {
						e.printStackTrace();
					}
				} else {
					break;
				}
			}
			if (!apkfile.exists()) {
				ToastUtils.showToast(mContext, "文件不存在");
				return;
			}
			Intent install = new Intent(Intent.ACTION_VIEW);
			install.setDataAndType(Uri.parse(apkfile.getAbsolutePath()), "application/vnd.android.package-archive");
			install.putExtra("IMPLUS_INSTALL", "SILENT_INSTALL");
			mContext.startActivity(install);
		}catch (Exception ex){
			ex.printStackTrace();
			ToastUtils.showToast(mContext, "更新失败");
		}
	}
}