/*
 * @Descripttion: 下载APK
 * @version: DownloadApk
 * @Author: wy
 * @Date: 2020-07-30 15:54:40
 * @LastEditors: wangyang 1147192855@qq.com
 * @LastEditTime: 2022-08-02 15:12:21
 */
import 'dart:io';

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:making_school_asignment_app/common/utils/utils.dart';
import 'package:path_provider/path_provider.dart';
import 'package:app_installer/app_installer.dart';
import 'package:url_launcher/url_launcher.dart';

import 'UpgradePermission.dart';
import 'model/UpdateAppEvent.dart';
import 'upgradeLogic.dart';

class DownloadApk {
  /// 下载安卓更新包
  static Future<File?> _downloadAndroid(
      context, UpdateAppEvent event, UpgradeLogic logic) async {
    /// 创建存储文件
    Directory? storageDir = await getExternalStorageDirectory();
    final storagePath = storageDir?.path ?? '/';
    String version = event.version.replaceAll(".", "-");
    File file = new File('$storagePath/${event.appName}v$version.apk');
    if (await file.exists()) await file.delete();
    if (!file.existsSync()) file.createSync();
    try {
      /// 发起下载请求
      Response response = await Dio().get(
        event.link,
        onReceiveProgress: (num received, num total) {
          showDownloadProgress(context, received, total, logic);
        },
        options: Options(
          responseType: ResponseType.bytes,
          followRedirects: false,
        ),
      );
      file.writeAsBytesSync(response.data);
      return file;
    } catch (e) {
      print(e);
      // toPrint(val: e);
    }
    return null;
  }

  // 安装apk
  static Future<bool> installApk(
      context, UpdateAppEvent event, UpgradeLogic logic) async {
    try {
      logic.loadingApk.value = true;
      File? _apkFile = await _downloadAndroid(context, event, logic);
      if (_apkFile == null) return false;
      String _apkFilePath = _apkFile.path;
      if (_apkFilePath.isEmpty) {
        debugPrint('make sure the apk file is set');
        return false;
      }

      await showDialog<bool>(
        context: context,
        builder: (BuildContext context) {
          return AlertDialog(
            title: const Text("未知应用安装权限提示",
                style: TextStyle(
                  fontWeight: FontWeight.bold,
                )),
            content: const Text("请注意：更新时若出现需要同意“安装未知应用权限”，请同意！！！"),
            actions: [
              MaterialButton(
                color: Theme.of(context).primaryColor,
                child: const Text("我已知晓",
                    style: TextStyle(
                        color: Colors.white, fontWeight: FontWeight.bold)),
                onPressed: () => Navigator.of(context).pop(),
              ),
            ],
          );
        },
      );
      await AppInstaller.installApk(_apkFilePath); // 安装APK
      // 如果2秒还没有进入安装引导页面  一律视为更新失败，弹出其他方式更新
      Utils.getInstance().setTimeOut(1, () async {
        try {
          // 其他方式下载
          // await SystemNavigator.pop(); // 退出APP
          var options = ['应用市场更新APP', '浏览器下载并安装APP'];
          var uri =
              Uri.parse('market://details?id=${event.packageName}'); // 应用市场URI
          if (!await canLaunchUrl(uri))
            options.removeAt(0); // 如果不能打开应用市场 就屏蔽掉 这个安装方式
          String? option = await UpgradePermission.showCustomModalBottomSheet(
              context, options);
          if (option == '应用市场更新APP') await launchUrl(uri);
          if (option == '浏览器下载并安装APP') await launchUrl(Uri.parse(event.link));
        } catch (_) {}
      });

      print('安装执行完成了..............0.0');
    } catch (e) {
      print('安装进入报错....');
      print(e);
    } finally {
      logic.loadingApk.value = false;
    }

    return false;
  }

  /// 展示下载进度
  static void showDownloadProgress(
      context, num received, num total, UpgradeLogic logic) {
    if (total != -1) {
      double progress = double.parse((received / total).toStringAsFixed(2));
      // debugPrint('下载进度$progress');
      logic.downloadRatio.value = progress;
    }
  }
}

class RestartWidget extends StatefulWidget {
  final Widget child;

  const RestartWidget({super.key, required this.child});

  static restartApp(BuildContext context) {
    final _RestartWidgetState? state =
        context.findAncestorStateOfType<_RestartWidgetState>();
    state?.restartApp();
  }

  @override
  State<RestartWidget> createState() => _RestartWidgetState();
}

class _RestartWidgetState extends State<RestartWidget> {
  Key key = UniqueKey();

  void restartApp() {
    setState(() {
      key = UniqueKey();
    });
  }

  @override
  Widget build(BuildContext context) {
    return KeyedSubtree(
      key: key,
      child: widget.child,
    );
  }
}
