import 'package:get/get.dart';
import 'package:logger/Logger.dart';
import 'package:sigap/src/cores/services/supabase_service.dart';
import 'package:sigap/src/features/auth/data/models/permissions_model.dart';
import 'package:sigap/src/features/personalization/data/models/models/roles_model.dart';
import 'package:sigap/src/utils/exceptions/exceptions.dart';
import 'package:supabase_flutter/supabase_flutter.dart';

class RolesRepository extends GetxController {
  static RolesRepository get instance => Get.find();

  final _supabase = SupabaseService.instance.client;
  // final Logger() = Get.find<Logger>();

  // Get all roles
  Future<List<RoleModel>> getAllRoles() async {
    try {
      final roles = await _supabase
          .from('roles')
          .select('*, permissions(*)')
          .order('name');

      return (roles as List).map((role) => RoleModel.fromJson(role)).toList();
    } on PostgrestException catch (error) {
      Logger().e('PostgrestException in getAllRoles: ${error.message}');
      throw TExceptions.fromCode(error.code ?? 'unknown-error');
    } catch (e) {
      Logger().e('Exception in getAllRoles: $e');
      throw 'Failed to fetch roles: ${e.toString()}';
    }
  }

  // Get role by ID
  Future<RoleModel> getRoleById(String roleId) async {
    try {
      final role =
          await _supabase
              .from('roles')
              .select('*, permissions(*)')
              .eq('id', roleId)
              .single();

      return RoleModel.fromJson(role);
    } on PostgrestException catch (error) {
      Logger().e('PostgrestException in getRoleById: ${error.message}');
      throw TExceptions.fromCode(error.code ?? 'unknown-error');
    } catch (e) {
      Logger().e('Exception in getRoleById: $e');
      throw 'Failed to fetch role data: ${e.toString()}';
    }
  }

  // Get role by name
  Future<RoleModel> getRoleByName(String roleName) async {
    try {
      final role =
          await _supabase
              .from('roles')
              .select('*, permissions(*)')
              .eq('name', roleName)
              .single();

      return RoleModel.fromJson(role);
    } on PostgrestException catch (error) {
      Logger().e('PostgrestException in getRoleByName: ${error.message}');
      throw TExceptions.fromCode(error.code ?? 'unknown-error');
    } catch (e) {
      Logger().e('Exception in getRoleByName: $e');
      throw 'Failed to fetch role data: ${e.toString()}';
    }
  }

  // Create a new role
  Future<RoleModel> createRole({
    required String name,
    String? description,
    String? icon,
  }) async {
    try {
      final data = {'name': name, 'description': description, 'icon': icon};

      final createdRole =
          await _supabase.from('roles').insert(data).select().single();

      return RoleModel.fromJson(createdRole);
    } on PostgrestException catch (error) {
      Logger().e('PostgrestException in createRole: ${error.message}');
      throw TExceptions.fromCode(error.code ?? 'unknown-error');
    } catch (e) {
      Logger().e('Exception in createRole: $e');
      throw 'Failed to create role: ${e.toString()}';
    }
  }

  // Update a role
  Future<RoleModel> updateRole(RoleModel role) async {
    try {
      final updatedRole =
          await _supabase
              .from('roles')
              .update(role.toJson())
              .eq('id', role.id)
              .select()
              .single();

      return RoleModel.fromJson(updatedRole);
    } on PostgrestException catch (error) {
      Logger().e('PostgrestException in updateRole: ${error.message}');
      throw TExceptions.fromCode(error.code ?? 'unknown-error');
    } catch (e) {
      Logger().e('Exception in updateRole: $e');
      throw 'Failed to update role: ${e.toString()}';
    }
  }

  // Get permissions for a role
  Future<List<PermissionModel>> getRolePermissions(String roleId) async {
    try {
      final permissions = await _supabase
          .from('permissions')
          .select('*, resource(*), role(*)')
          .eq('role_id', roleId);

      return (permissions as List)
          .map((permission) => PermissionModel.fromJson(permission))
          .toList();
    } on PostgrestException catch (error) {
      Logger().e('PostgrestException in getRolePermissions: ${error.message}');
      throw TExceptions.fromCode(error.code ?? 'unknown-error');
    } catch (e) {
      Logger().e('Exception in getRolePermissions: $e');
      throw 'Failed to fetch role permissions: ${e.toString()}';
    }
  }
}
