import 'package:get/get.dart';
import 'package:logger/web.dart';
import 'package:sigap/src/cores/services/supabase_service.dart';
import 'package:sigap/src/features/daily-ops/data/models/models/units_model.dart';
import 'package:sigap/src/utils/exceptions/exceptions.dart';
import 'package:supabase_flutter/supabase_flutter.dart';

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

  final _supabase = SupabaseService.instance.client;

  // Get all units
  Future<List<UnitModel>> getAllUnits() async {
    try {
      final units = await _supabase.from('units').select().order('name');

      if (units.isEmpty) {
        return [];
      }

      Logger().i('Fetched ${units.length} units from database');

      return units.map((unit) => UnitModel.fromJson(unit)).toList();
    } on PostgrestException catch (error) {
      throw TExceptions.fromCode(error.code ?? 'unknown_error');
    } catch (e) {
      throw TExceptions('Failed to fetch units: ${e.toString()}');
    }
  }

  // Get unit by ID
  Future<UnitModel> getUnitById(String codeUnit) async {
    try {
      final unit =
          await _supabase
              .from('units')
              .select('*, officers(*), patrol_units(*), unit_statistics(*)')
              .eq('code_unit', codeUnit)
              .single();

      return UnitModel.fromJson(unit);
    } on PostgrestException catch (error) {
      throw TExceptions.fromCode(error.code ?? 'unknown_error');
    } catch (e) {
      throw TExceptions('Failed to fetch unit data: ${e.toString()}');
    }
  }

  // Get units by type
  Future<List<UnitModel>> getUnitsByType(UnitType type) async {
    try {
      final units = await _supabase
          .from('units')
          .select()
          .eq('type', type.name)
          .order('name');

      return units.map((unit) => UnitModel.fromJson(unit)).toList();
    } on PostgrestException catch (error) {
      throw TExceptions.fromCode(error.code ?? 'unknown_error');
    } catch (e) {
      throw TExceptions('Failed to fetch units by type: ${e.toString()}');
    }
  }

  // Get units by city
  Future<List<UnitModel>> getUnitsByCity(String cityId) async {
    try {
      final units = await _supabase
          .from('units')
          .select()
          .eq('city_id', cityId)
          .order('name');

      return units.map((unit) => UnitModel.fromJson(unit)).toList();
    } on PostgrestException catch (error) {
      throw TExceptions.fromCode(error.code ?? 'unknown_error');
    } catch (e) {
      throw TExceptions('Failed to fetch units by city: ${e.toString()}');
    }
  }

  // Get units near a location
  Future<List<UnitModel>> getUnitsNearLocation(
    double latitude,
    double longitude,
    double radiusInKm,
  ) async {
    try {
      // Use PostGIS to find units within a radius
      final units = await _supabase.rpc(
        'get_units_near_location',
        params: {'lat': latitude, 'lng': longitude, 'radius_km': radiusInKm},
      );

      return units.map((unit) => UnitModel.fromJson(unit)).toList();
    } on PostgrestException catch (error) {
      throw TExceptions.fromCode(error.code ?? 'unknown_error');
    } catch (e) {
      throw TExceptions('Failed to fetch nearby units: ${e.toString()}');
    }
  }
}
