part of utils;

abstract class Access {
  /// 图片权限
  /// [showExplanation] 是否在申请权限前显示说明对话框
  /// [purpose] 权限使用目的说明
  /// [context] 上下文，用于显示对话框
  static Future<bool> photos({
    bool showExplanation = false,
    String purpose = '',
    BuildContext? context,
  }) async {
    if (Platform.isAndroid) return true;
    return _requestPermission(
      permission: Permission.photos,
      permissionName: '相册权限',
      showExplanation: showExplanation,
      purpose: purpose,
      context: context,
      allowLimited: true,
    );
  }

  /// 相机权限
  /// [showExplanation] 是否在申请权限前显示说明对话框
  /// [purpose] 权限使用目的说明
  /// [context] 上下文，用于显示对话框
  static Future<bool> camera({
    bool showExplanation = false,
    String purpose = '',
    BuildContext? context,
  }) async {
    return _requestPermission(
      permission: Permission.camera,
      permissionName: '相机权限',
      showExplanation: showExplanation,
      purpose: purpose,
      context: context,
    );
  }

  /// 获取麦克风权限
  static Future<bool> microphone({
    bool showExplanation = false,
    String purpose = '',
    BuildContext? context,
  }) async {
    return _requestPermission(
      permission: Permission.microphone,
      permissionName: '麦克风权限',
      showExplanation: showExplanation,
      purpose: purpose,
      context: context,
    );
  }

  static Future<bool> _requestPermission({
    required Permission permission,
    required String permissionName,
    required bool showExplanation,
    required String purpose,
    required BuildContext? context,
    bool allowLimited = false,
  }) async {
    final status = await permission.status;
    if (_isGranted(status, allowLimited: allowLimited)) {
      return true;
    }

    if (showExplanation && context != null && purpose.isNotEmpty) {
      final bool? shouldRequest = await _showPermissionExplanationDialog(
        context: context,
        permissionName: permissionName,
        purpose: purpose,
      );
      if (shouldRequest != true) {
        return false;
      }
    }

    final result = await permission.request();
    final granted = _isGranted(result, allowLimited: allowLimited);
    if (!granted &&
        context != null &&
        context.mounted &&
        result.isPermanentlyDenied) {
      _showSettingDialog(context, '获取$permissionName');
    }
    return granted;
  }

  static bool _isGranted(PermissionStatus status, {bool allowLimited = false}) {
    return status == PermissionStatus.granted ||
        (allowLimited && status == PermissionStatus.limited);
  }

  /// 显示权限使用目的说明对话框
  /// 对话框不会自动消失，需要用户主动确认
  static Future<bool?> _showPermissionExplanationDialog({
    required BuildContext context,
    required String permissionName,
    required String purpose,
  }) async {
    return await showDialog<bool>(
      context: context,
      barrierDismissible: false, // 不允许点击外部关闭
      builder: (BuildContext dialogContext) {
        return WillPopScope(
          onWillPop: () async => false, // 不允许返回键关闭
          child: AlertDialog(
            insetPadding: EdgeInsets.symmetric(horizontal: 40.w),
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(12.w),
            ),
            title: Text(
              '权限申请说明',
              style: TextStyle(
                fontSize: 18.w,
                color: Colours.c3,
                fontWeight: Fonts.boldSemi,
              ),
              textAlign: TextAlign.center,
            ),
            content: Column(
              mainAxisSize: MainAxisSize.min,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  '权限名称：',
                  style: TextStyle(
                    fontSize: 15.w,
                    color: Colours.c3,
                    fontWeight: Fonts.medium,
                  ),
                ),
                SizedBox(height: 5.w),
                Text(
                  permissionName,
                  style: TextStyle(
                    fontSize: 15.w,
                    color: Colours.c6,
                  ),
                ),
                SizedBox(height: 15.w),
                Text(
                  '使用目的：',
                  style: TextStyle(
                    fontSize: 15.w,
                    color: Colours.c3,
                    fontWeight: Fonts.medium,
                  ),
                ),
                SizedBox(height: 5.w),
                Text(
                  purpose,
                  style: TextStyle(
                    fontSize: 15.w,
                    color: Colours.c6,
                    height: 1.5,
                  ),
                ),
              ],
            ),
            actions: <Widget>[
              Row(
                children: [
                  Expanded(
                    child: TextButton(
                      onPressed: () {
                        Navigator.of(dialogContext).pop(false);
                      },
                      child: Text(
                        '取消',
                        style: TextStyle(
                          fontSize: 16.w,
                          color: Colours.c6,
                          fontWeight: Fonts.medium,
                        ),
                      ),
                    ),
                  ),
                  Container(
                    width: 1,
                    height: 40.w,
                    color: Colours.cLine,
                  ),
                  Expanded(
                    child: TextButton(
                      onPressed: () {
                        Navigator.of(dialogContext).pop(true);
                      },
                      child: Text(
                        '确定',
                        style: TextStyle(
                          fontSize: 16.w,
                          color: Colours.cAB1941,
                          fontWeight: Fonts.boldSemi,
                        ),
                      ),
                    ),
                  ),
                ],
              ),
            ],
          ),
        );
      },
    );
  }

  static void _showSettingDialog(BuildContext context, String content) {
    showDialog(
      context: context,
      builder: (BuildContext dialogContext) {
        return WillPopScope(
          onWillPop: () => Future.value(true),
          child: AlertDialog(
            insetPadding: EdgeInsets.zero,
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(8.0.w),
            ),
            actionsPadding: EdgeInsets.zero,
            title: Container(
              alignment: Alignment.center,
              child: Text(
                '权限申请',
                style: TextStyle(
                    fontSize: 20.w,
                    color: Colours.c3,
                    fontWeight: Fonts.boldSemi),
              ),
            ),
            actions: <Widget>[
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Column(
                    mainAxisAlignment: MainAxisAlignment.start,
                    children: [
                      Padding(
                        padding: EdgeInsets.only(top: 5.5.w),
                        child: Text(
                          content,
                          style: TextStyle(
                              fontSize: 15.w,
                              color: Colours.c9,
                              fontWeight: Fonts.medium),
                        ),
                      ),
                      SizedBox(height: 22.w),
                      Container(
                        height: 1,
                        width: 216.5.w,
                        color: Colours.cLine,
                      ),
                      Row(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: [
                          Padding(
                            padding: EdgeInsets.only(right: 28.w),
                            child: GestureDetector(
                              onTap: () => Navigator.of(dialogContext).pop(),
                              child: Container(
                                width: 85.w,
                                color: Colours.cFF,
                                alignment: Alignment.center,
                                child: const Text(
                                  '取消',
                                  style: TextStyle(
                                      color: Colours.c6,
                                      fontSize: 15,
                                      fontWeight: Fonts.medium),
                                ),
                              ),
                            ),
                          ),
                          Container(
                            height: 39.5.w,
                            width: 1,
                            color: Colours.cLine,
                          ),
                          Padding(
                            padding: EdgeInsets.only(left: 28.w),
                            child: GestureDetector(
                              onTap: () {
                                Navigator.of(dialogContext).pop();
                                setting();
                              },
                              child: Container(
                                width: 85.w,
                                color: Colours.cFF,
                                alignment: Alignment.center,
                                child: const Text(
                                  '设置',
                                  style: TextStyle(
                                      color: Colours.cAB1941,
                                      fontSize: 15,
                                      fontWeight: Fonts.boldSemi),
                                ),
                              ),
                            ),
                          ),
                        ],
                      ),
                    ],
                  ),
                ],
              ),
            ],
          ),
        );
      },
    );
  }

  /// 打开设置
  static Future<void> setting() async => await openAppSettings();
}
