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/resources_model.dart';
import 'package:sigap/src/utils/exceptions/exceptions.dart';
import 'package:supabase_flutter/supabase_flutter.dart';

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

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

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

      return (resources as List)
          .map((resource) => ResourceModel.fromJson(resource))
          .toList();
    } on PostgrestException catch (error) {
      _logger.e('PostgrestException in getAllResources: ${error.message}');
      throw TExceptions.fromCode(error.code ?? 'unknown-error');
    } catch (e) {
      _logger.e('Exception in getAllResources: $e');
      throw 'Failed to fetch resources: ${e.toString()}';
    }
  }

  // Get resource by ID
  Future<ResourceModel> getResourceById(String resourceId) async {
    try {
      final resource =
          await _supabase
              .from('resources')
              .select('*, permissions(*)')
              .eq('id', resourceId)
              .single();

      return ResourceModel.fromJson(resource);
    } on PostgrestException catch (error) {
      _logger.e('PostgrestException in getResourceById: ${error.message}');
      throw TExceptions.fromCode(error.code ?? 'unknown-error');
    } catch (e) {
      _logger.e('Exception in getResourceById: $e');
      throw 'Failed to fetch resource: ${e.toString()}';
    }
  }

  // Get resources by type
  Future<List<ResourceModel>> getResourcesByType(String type) async {
    try {
      final resources = await _supabase
          .from('resources')
          .select('*, permissions(*)')
          .eq('type', type)
          .order('name');

      return (resources as List)
          .map((resource) => ResourceModel.fromJson(resource))
          .toList();
    } on PostgrestException catch (error) {
      _logger.e('PostgrestException in getResourcesByType: ${error.message}');
      throw TExceptions.fromCode(error.code ?? 'unknown-error');
    } catch (e) {
      _logger.e('Exception in getResourcesByType: $e');
      throw 'Failed to fetch resources by type: ${e.toString()}';
    }
  }

  // Create a new resource
  Future<ResourceModel> createResource(ResourceModel resource) async {
    try {
      final createdResource =
          await _supabase
              .from('resources')
              .insert(resource.toJson())
              .select()
              .single();

      return ResourceModel.fromJson(createdResource);
    } on PostgrestException catch (error) {
      _logger.e('PostgrestException in createResource: ${error.message}');
      throw TExceptions.fromCode(error.code ?? 'unknown-error');
    } catch (e) {
      _logger.e('Exception in createResource: $e');
      throw 'Failed to create resource: ${e.toString()}';
    }
  }

  // Update a resource
  Future<ResourceModel> updateResource(ResourceModel resource) async {
    try {
      final updatedResource =
          await _supabase
              .from('resources')
              .update(resource.toJson())
              .eq('id', resource.id)
              .select()
              .single();

      return ResourceModel.fromJson(updatedResource);
    } on PostgrestException catch (error) {
      _logger.e('PostgrestException in updateResource: ${error.message}');
      throw TExceptions.fromCode(error.code ?? 'unknown-error');
    } catch (e) {
      _logger.e('Exception in updateResource: $e');
      throw 'Failed to update resource: ${e.toString()}';
    }
  }

  // Delete a resource
  Future<void> deleteResource(String resourceId) async {
    try {
      await _supabase.from('resources').delete().eq('id', resourceId);
    } on PostgrestException catch (error) {
      _logger.e('PostgrestException in deleteResource: ${error.message}');
      throw TExceptions.fromCode(error.code ?? 'unknown-error');
    } catch (e) {
      _logger.e('Exception in deleteResource: $e');
      throw 'Failed to delete resource: ${e.toString()}';
    }
  }
}
