import 'dart:async';
import 'dart:convert';
import 'package:get/get.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:on_field_work/helpers/services/app_logger.dart';
import 'package:on_field_work/helpers/services/permission_service.dart';
import 'package:on_field_work/model/user_permission.dart';
import 'package:on_field_work/model/employees/employee_info.dart';
import 'package:on_field_work/model/projects_model.dart';

class PermissionController extends GetxController {
  var permissions = <UserPermission>[].obs;
  var employeeInfo = Rxn<EmployeeInfo>();
  var projectsInfo = <ProjectInfo>[].obs;
  Timer? _refreshTimer;
  var isLoading = true.obs;

  /// ← NEW: reactive flag to signal permissions are loaded
  var permissionsLoaded = false.obs;

  @override
  void onInit() {
    super.onInit();
    _initialize();
  }

  Future<void> _initialize() async {
    final token = await _getAuthToken();
    if (token?.isNotEmpty ?? false) {
      await loadData(token!);
      _startAutoRefresh();
    } else {
      logSafe("Token is null or empty. Skipping API load and auto-refresh.",
          level: LogLevel.warning);
    }
  }

  Future<String?> _getAuthToken() async {
    try {
      final prefs = await SharedPreferences.getInstance();
      final token = prefs.getString('jwt_token');
      logSafe("Auth token retrieved: $token", level: LogLevel.debug);
      return token;
    } catch (e, stacktrace) {
      logSafe("Error retrieving auth token",
          level: LogLevel.error, error: e, stackTrace: stacktrace);
      return null;
    }
  }

  Future<void> loadData(String token) async {
    try {
      isLoading.value = true;
      final userData = await PermissionService.fetchAllUserData(token);
      _updateState(userData);
      await _storeData();
      logSafe("Data loaded and state updated successfully.");

      // ← NEW: mark permissions as loaded
      permissionsLoaded.value = true;

    } catch (e, stacktrace) {
      logSafe("Error loading data from API",
          level: LogLevel.error, error: e, stackTrace: stacktrace);
    } finally {
      isLoading.value = false;
    }
  }

  void _updateState(Map<String, dynamic> userData) {
    try {
      permissions.assignAll(userData['permissions']);
      employeeInfo.value = userData['employeeInfo'];
      projectsInfo.assignAll(userData['projects']);
      logSafe("State updated with user data.");
    } catch (e, stacktrace) {
      logSafe("Error updating state",
          level: LogLevel.error, error: e, stackTrace: stacktrace);
    }
  }

  Future<void> _storeData() async {
    try {
      final prefs = await SharedPreferences.getInstance();

      await prefs.setString(
        'user_permissions',
        jsonEncode(permissions.map((e) => e.toJson()).toList()),
      );

      if (employeeInfo.value != null) {
        await prefs.setString(
          'employee_info',
          jsonEncode(employeeInfo.value!.toJson()),
        );
      }

      if (projectsInfo.isNotEmpty) {
        await prefs.setString(
          'projects_info',
          jsonEncode(projectsInfo.map((e) => e.toJson()).toList()),
        );
      }

      logSafe("User data successfully stored in SharedPreferences.");
    } catch (e, stacktrace) {
      logSafe("Error storing data",
          level: LogLevel.error, error: e, stackTrace: stacktrace);
    }
  }

  void _startAutoRefresh() {
    _refreshTimer = Timer.periodic(const Duration(minutes: 30), (timer) async {
      logSafe("Auto-refresh triggered.");
      final token = await _getAuthToken();
      if (token?.isNotEmpty ?? false) {
        await loadData(token!);
      } else {
        logSafe("Token missing during auto-refresh. Skipping.",
            level: LogLevel.warning);
      }
    });
  }

  bool hasPermission(String permissionId) {
    final hasPerm = permissions.any((p) => p.id == permissionId);
    return hasPerm;
  }

  bool isUserAssignedToProject(String projectId) {
    final assigned = projectsInfo.any((project) => project.id == projectId);
    logSafe("Checking project assignment for $projectId: $assigned",
        level: LogLevel.debug);
    return assigned;
  }

  List<String> get allowedPermissionIds {
    final ids = permissions.map((p) => p.id).toList();
    logSafe("[PermissionController] Allowed Permission IDs: $ids",
        level: LogLevel.debug);
    return ids;
  }

  bool hasAnyPermission(List<String> ids) {
    logSafe("[PermissionController] Checking if any of these are allowed: $ids",
        level: LogLevel.debug);
    final allowed = allowedPermissionIds;
    final result = ids.any((id) => allowed.contains(id));
    logSafe("[PermissionController] Permission match result: $result",
        level: LogLevel.debug);
    return result;
  }

  @override
  void onClose() {
    _refreshTimer?.cancel();
    logSafe("PermissionController disposed and auto-refresh timer cancelled.");
    super.onClose();
  }
}
