import 'package:adhan/adhan.dart' as adhan;
import 'package:hive_flutter/hive_flutter.dart';
import '../local/hive_boxes.dart';
import '../local/models/cached_prayer_times.dart';
import 'package:intl/intl.dart';

/// Result object for prayer times.
class PrayerTimesResult {
  final DateTime fajr;
  final DateTime sunrise;
  final DateTime dhuhr;
  final DateTime asr;
  final DateTime maghrib;
  final DateTime isha;

  PrayerTimesResult({
    required this.fajr,
    required this.sunrise,
    required this.dhuhr,
    required this.asr,
    required this.maghrib,
    required this.isha,
  });
}

/// Prayer time calculation service using the adhan package.
class PrayerService {
  PrayerService._();
  static final PrayerService instance = PrayerService._();

  /// Calculate prayer times for a given location and date.
  /// Uses cache if available; writes to cache after calculation.
  PrayerTimesResult getPrayerTimes(double lat, double lng, DateTime date) {
    final dateKey = DateFormat('yyyy-MM-dd').format(date);
    final cacheKey = '${lat.toStringAsFixed(4)}_${lng.toStringAsFixed(4)}_$dateKey';

    // Check cache
    final cacheBox = Hive.box<CachedPrayerTimes>(HiveBoxes.cachedPrayerTimes);
    final cached = cacheBox.get(cacheKey);
    if (cached != null) {
      return PrayerTimesResult(
        fajr: cached.fajr,
        sunrise: cached.sunrise,
        dhuhr: cached.dhuhr,
        asr: cached.asr,
        maghrib: cached.maghrib,
        isha: cached.isha,
      );
    }

    // Calculate using adhan package
    final coordinates = adhan.Coordinates(lat, lng);
    final dateComponents = adhan.DateComponents(date.year, date.month, date.day);
    final params = adhan.CalculationMethod.muslim_world_league.getParameters();
    params.madhab = adhan.Madhab.shafi;

    final prayerTimes = adhan.PrayerTimes(coordinates, dateComponents, params);

    final result = PrayerTimesResult(
      fajr: prayerTimes.fajr!,
      sunrise: prayerTimes.sunrise!,
      dhuhr: prayerTimes.dhuhr!,
      asr: prayerTimes.asr!,
      maghrib: prayerTimes.maghrib!,
      isha: prayerTimes.isha!,
    );

    // Cache result
    cacheBox.put(
      cacheKey,
      CachedPrayerTimes(
        key: cacheKey,
        lat: lat,
        lng: lng,
        date: dateKey,
        fajr: result.fajr,
        sunrise: result.sunrise,
        dhuhr: result.dhuhr,
        asr: result.asr,
        maghrib: result.maghrib,
        isha: result.isha,
      ),
    );

    return result;
  }

  /// Get the next prayer name and time from now.
  MapEntry<String, DateTime>? getNextPrayer(PrayerTimesResult times) {
    final now = DateTime.now();
    final entries = {
      'Fajr': times.fajr,
      'Dhuhr': times.dhuhr,
      'Asr': times.asr,
      'Maghrib': times.maghrib,
      'Isha': times.isha,
    };

    for (final entry in entries.entries) {
      if (entry.value.isAfter(now)) {
        return entry;
      }
    }
    return null; // All prayers passed for today
  }

  /// Get the current active prayer (the last prayer whose time has passed).
  String? getCurrentPrayer(PrayerTimesResult times) {
    final now = DateTime.now();
    String? current;

    if (now.isAfter(times.isha)) {
      current = 'Isha';
    } else if (now.isAfter(times.maghrib)) {
      current = 'Maghrib';
    } else if (now.isAfter(times.asr)) {
      current = 'Asr';
    } else if (now.isAfter(times.dhuhr)) {
      current = 'Dhuhr';
    } else if (now.isAfter(times.fajr)) {
      current = 'Fajr';
    }

    return current;
  }
}
