import 'dart:async';
import 'dart:io';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:jailbreak_root_detection/jailbreak_root_detection.dart';
import 'package:package_info_plus/package_info_plus.dart';
import '../../main.dart';
import '../../print.dart';

class DeviceHelper {
  static Future<String> getDeviceFingerprint() async {
    final DeviceInfoPlugin deviceInfoPlugin = DeviceInfoPlugin();
    var deviceData;

    try {
      if (Platform.isAndroid) {
        // Fetch Android-specific device information
        AndroidDeviceInfo androidInfo = await deviceInfoPlugin.androidInfo;
        deviceData = androidInfo.toMap(); // Convert to a map for easier access
        // Log.print('deviceData: ${jsonEncode(deviceData)}');
      } else if (Platform.isIOS) {
        // Fetch iOS-specific device information
        IosDeviceInfo iosInfo = await deviceInfoPlugin.iosInfo;
        deviceData = iosInfo.toMap(); // Convert to a map for easier access
      } else if (Platform.isMacOS) {
        // Fetch macOS-specific device information
        MacOsDeviceInfo macInfo = await deviceInfoPlugin.macOsInfo;
        deviceData = macInfo.toMap();
      } else {
        throw UnsupportedError('Unsupported platform');
      }

      String deviceId = 'unknown';
      if (Platform.isAndroid) {
        deviceId = deviceData['fingerprint'] ?? 'unknown';
      } else if (Platform.isIOS) {
        deviceId = deviceData['identifierForVendor'] ?? 'unknown';
      } else if (Platform.isMacOS) {
        deviceId = deviceData['systemGUID'] ?? 'unknown';
      }

      final String deviceModel = deviceData['model'] ?? 'unknown';

      final String fingerprint = '${deviceId}_$deviceModel';
      print(fingerprint);
      return (fingerprint);
    } catch (e) {
      throw Exception('Failed to generate device fingerprint');
    }
  }
}

class SecurityHelper {
  /// Performs security checks and handles potential risks
  static Future<void> performSecurityChecks() async {
    bool isNotTrust = false;
    bool isJailBroken = false;
    bool isRealDevice = true;
    bool isOnExternalStorage = false;
    bool checkForIssues = false;
    bool isDevMode = false;
    bool isTampered = false;
    String bundleId = "";

    try {
      isNotTrust = await JailbreakRootDetection.instance.isNotTrust;
      isJailBroken = await JailbreakRootDetection.instance.isJailBroken;
      isRealDevice = await JailbreakRootDetection.instance.isRealDevice;
      isOnExternalStorage =
          await JailbreakRootDetection.instance.isOnExternalStorage;

      List<JailbreakIssue> issues =
          await JailbreakRootDetection.instance.checkForIssues;
      checkForIssues = issues.isNotEmpty;

      isDevMode = await JailbreakRootDetection.instance.isDevMode;

      PackageInfo packageInfo = await PackageInfo.fromPlatform();
      bundleId = packageInfo.packageName;
      if (bundleId.isNotEmpty) {
        isTampered = await JailbreakRootDetection.instance.isTampered(bundleId);
      }
    } catch (e) {
      Log.print("Error during security checks: $e");
    }

    await box.write('isNotTrust', isNotTrust);
    await box.write('isTampered', isTampered);
    await box.write('isJailBroken', isJailBroken);

    if (isJailBroken || isRealDevice == false || isTampered) {
      _showSecurityWarning();
    }
  }

  static Future<void> clearAllData() async {
    await box.erase();
    exit(0);
  }

  static void _showSecurityWarning() {
    final secondsRemaining = RxInt(10);

    Get.dialog(
      CupertinoAlertDialog(
        title: Text("Security Warning".tr),
        content: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Obx(() => Text(
                  "Potential security risks detected. The application will close in @seconds seconds."
                      .trParams({
                    'seconds': secondsRemaining.value.toString(),
                  }),
                )),
            SizedBox(height: 24),
            Obx(() => SizedBox(
                width: double.infinity,
                child: CupertinoActivityIndicator(
                  radius: 15,
                  animating: true,
                ))),
            SizedBox(height: 8),
            Obx(() => ClipRRect(
                  borderRadius: BorderRadius.circular(8),
                  child: LinearProgressIndicator(
                    value: secondsRemaining.value / 10,
                    backgroundColor: Colors.grey.shade300,
                    valueColor: AlwaysStoppedAnimation<Color>(
                        CupertinoColors.systemRed),
                    minHeight: 8,
                  ),
                )),
          ],
        ),
      ),
      barrierDismissible: false,
    );

    Timer.periodic(Duration(seconds: 1), (timer) {
      secondsRemaining.value--;
      if (secondsRemaining.value <= 0) {
        timer.cancel();
        _clearDataAndExit();
      }
    });
  }

  static Future<void> _clearDataAndExit() async {
    await box.erase();
    exit(0);
  }
}
