import 'dart:async';

import 'package:get/get.dart';
import 'package:guru_platform_data/guru_platform_data.dart';
import 'package:guru_utils/controller/lifecycle_controller.dart';
import 'package:guru_utils/log/log.dart';
import 'package:guru_utils/settings/settings.dart';
import 'package:system_clock/system_clock.dart';

mixin KeepScreenOnAware on LifecycleController {
  static bool isKeepScreenOn = false;

  static Timer? checkKeepScreenTimer;

  static int keepingAt = 0;

  static int sustainedDuration = 0;

  String get screenName => runtimeType.toString();

  static bool _scheduleTimer(int duration) {
    final interval = SystemClock.elapsedRealtime().inMilliseconds - keepingAt;
    final remaining = duration - interval;
    Log.i("schedule timer interval: $interval, remaining: $remaining");
    if (remaining < 1000) {
      checkKeepScreenTimer?.cancel();
      checkKeepScreenTimer = null;
      // 如果这里的 Duration 是大于等于 0 的，表示已经超时或是配置了关闭
      if (duration < 0) {
        Log.i("Always keepScreenOn, no need to set a timer");
        return true;
      }
      _restoreKeepScreenStatus();
      return false;
    } else {
      Log.i("schedule new timer remaining: $remaining");
      checkKeepScreenTimer = Timer(Duration(milliseconds: remaining), () {
        _scheduleTimer(duration);
      });
      return true;
    }
  }

  // true: 表示已经成功注册了屏幕长亮的定时器
  // false: 在注册定时器时，发现已经没有必要注册了，因为已经超过了屏幕长亮的时间
  static bool keepAlive() {
    final duration = Settings.get().keepOnScreenDuration.get();
    if ((sustainedDuration == duration) && (duration < 0 || checkKeepScreenTimer != null)) {
      Log.i("already registerKeepingTimer same timer:$sustainedDuration, ignore!");
      return true;
    }

    final result = _scheduleTimer(duration);
    if (result) {
      sustainedDuration = duration;
    }
    return result;
  }

  void _keepScreenOn() async {
    keep(info: "_keepScreenOn $isKeepScreenOn");
    final keeping = keepAlive();
    if (!keeping) {
      Log.i("_keepScreenOn failed! already over duration: $sustainedDuration");
      return;
    }
    if (!isKeepScreenOn) {
      isKeepScreenOn = await GuruPlatformData.keepScreenOn(true);
    }
  }

  static void _restoreKeepScreenStatus() async {
    if (isKeepScreenOn) {
      await GuruPlatformData.keepScreenOn(false);
      isKeepScreenOn = false;
    }
    Log.d("_restoreKeepScreenStatus $isKeepScreenOn");
  }

  void initKeepScreenOn() {
    keep(info: "initKeepScreenOn");
  }

  void keep({String? info}) {
    final elapsed = SystemClock.elapsedRealtime().inMilliseconds;
    Log.i("[$screenName] KEEP${info != null ? "($info)" : ""} interval: ${elapsed - keepingAt}");
    keepingAt = elapsed;
  }

  @override
  void onResumed() {
    super.onResumed();
    _keepScreenOn();
  }

  @override
  void onPaused() {
    if (Get.isDialogOpen != true) {
      _restoreKeepScreenStatus();
    }
    super.onPaused();
  }

  @override
  void dispose() {
    super.dispose();
  }
}
