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

import 'package:flutter/services.dart';

class TrackingAuthorizationStatus {
  static const notDetermined = 0;
  static const restricted = 1;
  static const denied = 2;
  static const authorized = 3;
  static const unknown = 4;

  static String toSummary(int status) {
    switch (status) {
      case notDetermined:
        return "notDetermined";
      case restricted:
        return "restricted";
      case denied:
        return "denied";
      case authorized:
        return "authorized";
      default:
        return "unknown";
    }
  }
}

class GuruPlatformData {
  static const perform = MethodChannel("app.guru.guru_platform_data");

  static const _getAdsLimitTracking = "get_ads_limit_tracking";
  static const _requestTrackingAuthorization = "requestTrackingAuthorization";
  static const _showMediationDebugger = "show_mediation_debugger";
  static const _getTrackingAuthorizationStatus = "getTrackingAuthorizationStatus";
  static const _getObservatoryUri = "get_observatory_uri";
  static const _isCutoutScreen = "is_cutout_screen";
  static const _jumpToAppPrivacySettings = "jumpToAppPrivacySettings";
  static const _isAppInstalled = "is_app_installed";

  static const _getBrightness = "get_brightness";
  static const _setBrightness = "set_brightness";
  static const _resetBrightness = "reset_brightness";
  static const _isKeptScreenOn = "is_kept_screen_on";
  static const _keepScreenOn = "keep_screen_on";
  static const _getPurposeConsents = "get_purpose_consents";

  static Future<String?> getAdsLimitTracking() {
    return perform.invokeMethod<String>(_getAdsLimitTracking);
  }

  static Future showMediationDebugger() {
    return perform.invokeMethod(_showMediationDebugger);
  }

  static Future<int> requestTrackingAuthorization() async {
    if (Platform.isIOS) {
      return (await perform.invokeMethod<int>(_requestTrackingAuthorization)) ??
          TrackingAuthorizationStatus.unknown;
    } else {
      return TrackingAuthorizationStatus.authorized;
    }
  }

  static Future<int> getTrackingAuthorizationStatus() async {
    if (Platform.isIOS) {
      return (await perform.invokeMethod<int>(_getTrackingAuthorizationStatus)) ??
          TrackingAuthorizationStatus.unknown;
    } else {
      return TrackingAuthorizationStatus.authorized;
    }
  }

  static Future<String?> getObservatoryUri() async {
    return perform.invokeMethod<String>(_getObservatoryUri);
  }

  static Future<bool?> isCutoutScreen() async {
    if (Platform.isAndroid) {
      return perform.invokeMethod<bool>(_isCutoutScreen);
    } else {
      return false;
    }
  }

  static Future<bool> isAppInstalled(String packageName) async {
    if (Platform.isAndroid) {
      return (await perform.invokeMethod<bool>(_isAppInstalled, {"package_name": packageName})) ??
          false;
    } else {
      return false;
    }
  }

  static Future<bool> jumpToAppPrivacySettings() async {
    if (Platform.isIOS) {
      return await perform.invokeMethod<bool>(_jumpToAppPrivacySettings) ?? false;
    } else {
      return true;
    }
  }

  static Future<double> getBrightness() async {
    return await perform.invokeMethod<double>(_getBrightness) ?? 1.0;
  }

  static Future<bool> setBrightness(double brightness) async {
    return await perform
            .invokeMethod<bool>(_setBrightness, {"brightness": brightness.clamp(0.0, 1.0)}) ??
        false;
  }

  static Future<bool> keepScreenOn(bool on) async {
    return await perform.invokeMethod<bool>(_keepScreenOn, {"on": on}) ?? false;
  }

  static Future<bool> isKeptScreenOn() async {
    return await perform.invokeMethod<bool>(_isKeptScreenOn) ?? false;
  }

  ///
  /// Returns local timezone from the native layer.
  ///
  static Future<String> getLocalTimezone() async {
    final String? localTimezone = await perform.invokeMethod("getLocalTimezone");
    if (localTimezone == null) {
      throw ArgumentError("Invalid return from platform getLocalTimezone()");
    }
    return localTimezone;
  }

  ///
  /// Gets the list of available timezones from the native layer.
  ///
  static Future<List<String>> getAvailableTimezones() async {
    final List<String>? availableTimezones =
        await perform.invokeListMethod<String>("getAvailableTimezones");
    if (availableTimezones == null) {
      throw ArgumentError("Invalid return from platform getAvailableTimezones()");
    }
    return availableTimezones;
  }

  static Future<String> getPurposeConsents() async {
    return await perform.invokeMethod<String>(_getPurposeConsents) ?? "";
  }
}
