import 'dart:async';
import 'dart:io';

///https://blog.csdn.net/zcylyzhi4/article/details/108002879
///1、导入相关包
import 'dart:isolate';
import 'dart:ui';

import 'package:app_installer/app_installer.dart';
import 'package:flutter/material.dart';
import 'package:flutter_downloader/flutter_downloader.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:hyzp_ybqx/components/dioFun.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:progress_dialog/progress_dialog.dart';

import '../../../components/commonFun.dart';

///版本更新类
class MyUpdatedNew {
  MyUpdatedNew(
      {this.ver,
      this.date,
      this.theContext,
      this.bStartUpdated = false,
      this.bShowNoNewVersion = false}) {
    initState();
  }

  String ver = '1.0.0';
  String date = '';
  BuildContext theContext;
  bool bStartUpdated;
  bool bShowNoNewVersion;

  //2、声明变量
  int _stampAppCompile = -1;
  String _dateNewver = '';
  Map _mapVer = {};
  String serviceVersionCode = '';
  String appId = '';
  ProgressDialog pr;
  String apkName = '';
  String appPath = '';
  ReceivePort _port = ReceivePort();

  void initState() {
    // 0、初始化FlutterDownLoader。版本更新初始化，放在这里会报错，初始化失败
    // WidgetsFlutterBinding.ensureInitialized();
    if (!bFlutterDownloader_initialize) {
      FlutterDownloader.initialize(debug: true).then((value) {
        registerCallback(first: true);
      });
    } else {
      registerCallback();
    }
  }

  registerCallback({bool first = false}) {
    //3、在initState中初始化
    if (!first) {
      // 解决2次进入报错无法下载的问题-OK
      // 如果以前注册过必须先移除，否则报错无法下载：DownloadWorker( 4745): Update too frequently!!!!, this should be dropped
      IsolateNameServer.removePortNameMapping('downloader_send_port');
      // FlutterDownloader.cancelAll();
      // FlutterDownloader.remove(taskId: null);
    }
    IsolateNameServer.registerPortWithName(_port.sendPort, 'downloader_send_port');
    _port.listen(_updateDownLoadInfo);
    FlutterDownloader.registerCallback(_downLoadCallback);
    getNewverUrl().then((value) {
      _mapVer = value;
      print('_mapVer = ${_mapVer}');
      //I/flutter (12498): _mapVer = {id: 1, ver: 1.0.0, miaos: 版本说明,
      // downurl: http://www.sctastech.com/download/hyzp_20210425.apk, updatetime: 1620632231}

      print('oldVer = ${ver}');
      //_mapVer['ver'] = '1.3.1';
      print('newVer = ${_mapVer['ver']}');
      // I/flutter ( 1872): oldVer = 1.3.0
      // I/flutter ( 1872): newVer = 1.3.1

      if (first) {
        bFlutterDownloader_initialize = true;
      }

      startUpdated();
    });
  }

  ///开始更新过程
  Future startUpdated() async {
    // 如果是android，则执行热更新
    if (Platform.isAndroid) {
      verCompare(newVer: _mapVer['ver'], oldVer: ver).then((value) {
        if (value) {
          print('value = $value');
          //_getNewVersionAPP(context);
          //appId = res.data['id'];
          //_checkVersionCode();
          bNewVer = true; //发现新版本
          if (bStartUpdated) {
            serviceVersionCode = _mapVer['ver'];
            _showNewVersionAppDialog();
          }
        } else if (bShowNoNewVersion) {
          // 没有发现新版本
          _showNoNewVersionAppDialog();
        }
      });
    } else if (Platform.isIOS) {
      // TODO: iOS更新
    }
  }

  /// 没有发现新版本
  Future<void> _showNoNewVersionAppDialog() async {
    return showDialog<void>(
        context: theContext,
        barrierDismissible: false,
        builder: (BuildContext context) {
          return AlertDialog(
            title: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[Text("没有发现新版本")],
            ),
            content: Container(
              //padding: EdgeInsets.only(bottom: ScreenUtil().setHeight(18)),
              height: ScreenUtil().setHeight(230),
              decoration: BoxDecoration(
                border: Border.all(color: Colors.blueAccent, width: 1.0),
                borderRadius: BorderRadius.circular(5),
              ),
              alignment: Alignment.center,
              child: RichText(
                textAlign: TextAlign.center,
                text: TextSpan(children: [
                  TextSpan(text: 'NewVer: ', style: TextStyle(fontSize: 17, color: Colors.black)),
                  TextSpan(
                      text: '暂无新版本',
                      style: TextStyle(
                          fontSize: 17, color: Colors.black, fontWeight: FontWeight.bold)),
                ]),
              ),
            ),
            actions: <Widget>[
              new FlatButton(
                child: new Text('确定'),
                onPressed: () {
                  Navigator.of(context).pop();
                },
              ),
            ],
          );
        });
  }

  /// 版本更新提示对话框
  Future<void> _showNewVersionAppDialog() async {
    String content1 = "注意：";
    String content2 = "新版本下载成功后，将弹出“安装未知应用程序”界面，请";
    String content3 = "授权“允许此来源”";
    String content4 = "；然后";
    String content5 = "稍等几秒钟";
    String content6 = "，再";
    String content7 = "点击“返回”按钮(一般位于左上角)";
    String content8 = "，按照提示即可完成升级过程。若";
    String content9 = "升级过程意外中断";
    String content10 = "，可重启App再次升级即可。";

    return showDialog<void>(
        context: theContext,
        barrierDismissible: false,
        builder: (BuildContext context) {
          return AlertDialog(
            insetPadding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 24.0),
            buttonPadding: EdgeInsets.only(bottom: 15, right: 20),
            title: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[Text("发现新版本")],
            ),
            content: Container(
              padding: EdgeInsets.only(
                  left: ScreenUtil().setHeight(25), right: ScreenUtil().setHeight(10)),
              height: ScreenUtil().setHeight(620),
              decoration: BoxDecoration(
                border: Border.all(color: Colors.blueAccent, width: 1.0),
                borderRadius: BorderRadius.circular(5),
              ),
              alignment: Alignment.center,
              child: Column(
                children: [
                  RichText(
                    textAlign: TextAlign.center,
                    text: TextSpan(children: [
                      TextSpan(
                          text: '\nNewVer: ',
                          style: TextStyle(fontSize: 17, color: Colors.redAccent)),
                      TextSpan(
                          text: serviceVersionCode,
                          style: TextStyle(
                              fontSize: 17, color: Colors.redAccent, fontWeight: FontWeight.bold)),
                    ]),
                  ),
                  RichText(
                    textAlign: TextAlign.justify,
                    text: TextSpan(children: [
                      getTextSpan('\n' + content1, color: Colors.blueAccent),
                      getTextSpan(content2),
                      getTextSpan(content3, color: Colors.redAccent),
                      getTextSpan(content4),
                      getTextSpan(content5, color: Colors.redAccent),
                      getTextSpan(content6),
                      getTextSpan(content7, color: Colors.redAccent),
                      getTextSpan(content8),
                      getTextSpan(content9, color: Colors.blueAccent),
                      getTextSpan(content10),
                    ]),
                  ),
                ],
              ),
            ),
            actions: <Widget>[
              new FlatButton(
                child: new Text('立即更新'),
                onPressed: () {
                  /// 执行更新操作
                  Navigator.pop(context);
                  _executeDownload(context);
                },
              ),
              new FlatButton(
                child: new Text('下次再说'),
                onPressed: () {
                  Navigator.of(context).pop();
                },
              ),
            ],
          );
        });
  }

  TextSpan getTextSpan(String _text, {Color color = Colors.black, double fontSize = 15}) {
    return TextSpan(text: _text, style: TextStyle(fontSize: fontSize, color: color));
  }

  /// 下载最新apk包
  Future<void> _executeDownload(BuildContext context) async {
    pr = new ProgressDialog(
      context,
      type: ProgressDialogType.Download,
      isDismissible: true,
      showLogs: true,
    );
    pr.style(message: '准备下载...');
    if (!pr.isShowing()) {
      pr.show();
    }

    final path = await _apkLocalPath;
    apkName = getFileName(_mapVer['downurl']);
    await FlutterDownloader.enqueue(
        //url: 'http://update.rwworks.com:8088/appManager/monitor/app/appload/' + appId + '',
        url: _mapVer['downurl'],
        savedDir: path,
        fileName: apkName,
        showNotification: true,
        openFileFromNotification: true);
  }

  /// 下载进度回调函数
  static void _downLoadCallback(String id, DownloadTaskStatus status, int progress) {
    final SendPort send = IsolateNameServer.lookupPortByName('downloader_send_port');
    send.send([id, status, progress]);
  }

  /// 更新下载进度框
  _updateDownLoadInfo(dynamic data) {
    DownloadTaskStatus status = data[1];
    int progress = data[2];
    if (status == DownloadTaskStatus.running) {
      pr.update(progress: double.parse(progress.toString()), message: "下载中，请稍后…");
    }
    if (status == DownloadTaskStatus.failed) {
      if (pr.isShowing()) {
        pr.hide();
      }
    }

    if (status == DownloadTaskStatus.complete) {
      if (pr.isShowing()) {
        pr.hide();
      }
      _installApk();
    }
  }

  /// 安装apk
  Future<Null> _installApk() async {
    // await OpenFile.open(appPath + '/' + apkName);
    // app_installer: 0.5.0          # Flutter 2.1，修复 Android 11 上允许权限后应用重启的问题，https://pub.dev/packages/app_installer
    Map<Permission, PermissionStatus> permissionStatuses = await [
      Permission.storage,
    ].request();

    if (permissionStatuses[Permission.storage] == PermissionStatus.granted) {
      await AppInstaller.installApk(appPath + '/' + apkName);
    } else {
      print('Permission request fail!');
    }
  }

  /// 获取apk存储位置
  Future<String> get _apkLocalPath async {
    final directory = await getExternalStorageDirectory();
    String path = directory.path + Platform.pathSeparator + 'Download';
    ;
    final savedDir = Directory(path);
    bool hasExisted = await savedDir.exists();
    if (!hasExisted) {
      await savedDir.create();
    }
    appPath = path;

    // this.setState(() {
    //   appPath = path;
    // });

    return path;
  }

  //4、判断，自动更新
  // 版本比较
  //R:\FlutterProject\FlutterProject33\hyzp_ybqx\lib\pages\MyMsics\05_updated\MyUpdatedNew.dart line 343
  Future verCompare({String newVer, String oldVer}) async {
    //解决newVer中不包含字符“+”号报错失败问题
    if (newVer.indexOf('+') > -1) {
      //解决App.Car_Ver.Getver接口返回值变化后，1.3.11+20210729字符串转换为数字报错问题
      print('newVer = $newVer');
      newVer = newVer.substring(0, newVer.indexOf('+')); // substring是含头不含尾
      print('newVer2 = $newVer');
    }

    List listNewVer = await tran2int(newVer.split('.'));
    List listOldVer = await tran2int(oldVer.split('.'));

    int len = listNewVer.length;
    for (int i = 0; i < len; i++) {
      if (listNewVer[i] > listOldVer[i]) {
        return true;
      }
      if (listNewVer[i] < listOldVer[i]) {
        return false;
      }
    }
    return false;
  }

  Future tran2int(List _list) async {
    List listRet = [];
    int len = _list.length;
    for (int i = 0; i < len; i++) {
      listRet.add(int.parse(_list[i].trim()));
    }
    return listRet;
  }

  ///https://blog.csdn.net/zcylyzhi4/article/details/108002879
//5、自动更新代码
  /// 执行版本更新的网络请求

  /// 检查当前版本是否为最新，若不是，则更新
// void _checkVersionCode() {
//   PackageInfo.fromPlatform().then((PackageInfo packageInfo) {
//     var currentVersionCode = packageInfo.version;
//     if (double.parse(serviceVersionCode.substring(0, 3)) >
//         double.parse(currentVersionCode.substring(0, 3))) {
//       _showNewVersionAppDialog();
//     }
//   });
// }
}
