import 'dart:io';

import 'package:app_installer/app_installer.dart';
import 'package:dio/dio.dart';
import 'package:eitc_erm_dental_flutter/exts.dart';
import 'package:eitc_erm_dental_flutter/funcs.dart';
import 'package:eitc_erm_dental_flutter/widget/custom_divider.dart';
import 'package:eitc_erm_dental_flutter/widget/main_button.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:path_provider/path_provider.dart';
import 'package:percent_indicator/percent_indicator.dart' as pi;
import 'package:permission_handler/permission_handler.dart';

import '../global.dart';
import '../http/http.dart';

///app更新弹窗
class AppUpdateDialog extends StatefulWidget {
  final String version;
  final String content;
  final String url;
  final bool isForce;

  const AppUpdateDialog(
      {super.key,
      required this.version,
      required this.content,
      required this.url,
      required this.isForce});

  @override
  State<AppUpdateDialog> createState() => _AppUpdateDialogState();
}

class _AppUpdateDialogState extends State<AppUpdateDialog> {
  _State state = _State.waiting;
  double _downloadProgress = 0.0;
  CancelToken? _downloadCancelToken;
  String _filePath = "";

  @override
  Widget build(BuildContext context) {
    return PopScope(
        //强制更新或下载时不允许返回关闭
        canPop: !widget.isForce && state != _State.downloading,
        child: Dialog(
          shape:
              RoundedRectangleBorder(borderRadius: BorderRadius.circular(15.r)),
          child: Padding(
            padding: EdgeInsets.all(20.r),
            child:
                state == _State.waiting ? _getUpdateContent() : _getDownload(),
          ),
        ));
  }

  ///获取更新内容
  Widget _getUpdateContent() {
    return Column(
      mainAxisSize: MainAxisSize.min,
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text(
          getS().hasNewVersion,
          style: context.titleMedium,
        ),
        Text("V${widget.version}"),
        SizedBox(
          height: 10.h,
        ),
        Text(widget.content),
        SizedBox(
          height: 10.h,
        ),
        Center(
          child: Row(
            mainAxisSize: MainAxisSize.min,
            children: [
              Visibility(
                visible: !widget.isForce,
                child: Row(
                  children: [
                    MainButton(
                      text: getS().nextTime,
                      onPressed: _cancelUpdate,
                      isOutlined: true,
                    ),
                    SizedBox(
                      width: 15.w,
                    )
                  ],
                ),
              ),
              MainButton(text: getS().updateNow, onPressed: _startUpdate)
            ],
          ),
        )
      ],
    );
  }

  ///获取下载内容
  Widget _getDownload() {
    String title = switch (state) {
      _State.downloading => getS().downloading,
      _State.waiting => "",
      _State.downloadError => getS().downloadFailed,
      _State.downloadSuccess => getS().downloadComplete,
    };

    return Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        Text(
          title,
          style: context.titleMedium,
        ),
        SizedBox(
          height: 10.h,
        ),
        pi.LinearPercentIndicator(
          percent: _downloadProgress,
          lineHeight: 15.h,
          progressColor: context.primaryColor,
          barRadius: Radius.circular(15.h),
          center: Text(
            "${(_downloadProgress * 100.0).round()}%",
            style: TextStyle(fontSize: 12.sp, color: Colors.white),
          ),
        ),
        SizedBox(
          height: 10.h,
        ),
        _getDownloadFuncButton(),
      ],
    );
  }

  ///获取下载功能按钮
  Widget _getDownloadFuncButton() {
    //如果是下载中且强制更新,就没有按钮
    if (state == _State.downloading && widget.isForce) {
      return SizedBox();
    }

    String text = switch (state) {
      _State.downloading => getS().cancel,
      _State.waiting => "",
      _State.downloadError => getS().close,
      _State.downloadSuccess => getS().install,
    };
    return Column(
      children: [
        const CustomDivider(),
        MainButton(text: text, onPressed: _onDownloadButtonFunc)
      ],
    );
  }

  ///取消更新
  void _cancelUpdate() {
    Navigator.pop(context);
  }

  ///开始更新
  void _startUpdate() async {
    PackageInfo packageInfo = await PackageInfo.fromPlatform();
    if (Platform.isIOS) {
      logd("app更新,ios打开appstore,appid=$iosAppId");
      AppInstaller.goStore(packageInfo.packageName, iosAppId);
    } else {
      //地址可能不是具体文件,所以不能根据后缀来判断
      if (widget.url.isEmpty) {
        logd("app更新,android的url为空,打开appstore,appid=${packageInfo.packageName}");
        AppInstaller.goStore(packageInfo.packageName, iosAppId);
      } else {
        logd("app更新,开始下载,url=${widget.url}");
        _startDownload(widget.url);
      }
    }
  }

  ///开始下载
  void _startDownload(String url) async {
    if (!url.endsWith(".apk")) {
      setState(() {
        state = _State.downloadError;
      });
    }

    List<Directory>? list = await getExternalCacheDirectories();
    if (list == null || list.isEmpty) {
      setState(() {
        state = _State.downloadError;
      });
      return;
    }
    _downloadCancelToken = CancelToken();
    Directory dir = Directory("${list.first.path}/update");
    if (!await dir.exists()) {
      try {
        dir = await dir.create();
      } catch (e) {
        loge("创建文件夹失败", error: e);
        setState(() {
          state = _State.downloadError;
        });
        return;
      }
    }

    String fileName = url.substring(url.lastIndexOf("/") + 1);
    if (fileName.isEmpty) {
      setState(() {
        state = _State.downloadError;
      });
      return;
    }
    _filePath = "${dir.path}/$fileName";
    logd("app更新,下载保存路径=$_filePath");
    try {
      File file = File(_filePath);
      if (await file.exists()) {
        await file.delete();
      }
    } catch (e) {
      loge("app更新,删除旧apk文件失败", error: e);
    }

    Http.instance.download(url, _filePath, cancelToken: _downloadCancelToken,
        onReceiveProgress: (downloaded, total) {
      setState(() {
        _downloadProgress = downloaded.toDouble() / total.toDouble();
        logd(
            "app更新,下载进度=$_downloadProgress,downloaded=$downloaded,total=$total");
        if (_downloadProgress >= 1) {
          _onDownloadComplete();
        }
      });
    });

    setState(() {
      state = _State.downloading;
    });
  }

  ///下载完毕
  void _onDownloadComplete() {
    if (state != _State.downloading) {
      return;
    }
    state = _State.downloadSuccess;
    logd("app更新,下载完毕");
    _installApk();
  }

  ///下载按钮功能
  void _onDownloadButtonFunc() {
    ///正在下载
    if (state == _State.downloading) {
      //取消下载
      _downloadCancelToken?.cancel();
      //关闭弹窗
      _cancelUpdate();
    }
    //下载失败
    else if (state == _State.downloadError) {
      //强制更新就退出程序
      if (widget.isForce) {
        exitApp();
      }
      //否则关闭弹窗
      else {
        _cancelUpdate();
      }
    }
    //下载成功
    else if (state == _State.downloadSuccess) {
      _installApk();
    }
  }

  ///安装apk
  void _installApk() async {
    if (!await Permission.requestInstallPackages.isGranted) {
      logd("app更新,没有安装apk权限,进行申请");
      if (!await Permission.requestInstallPackages.request().isGranted) {
        logd("app更新,申请安装apk权限被拒绝,终止安装");
        return;
      }
    }
    logd("app更新,安装apk,path=$_filePath");
    AppInstaller.installApk(_filePath);
  }
}

enum _State { waiting, downloading, downloadError, downloadSuccess }
