import 'dart:convert';
import 'package:flutter/services.dart';
import 'package:hive_flutter/hive_flutter.dart';
import '../local/hive_boxes.dart';
import '../local/models/dzikir_counter.dart';
import 'package:intl/intl.dart';

/// Represents a single dzikir item from the bundled JSON.
class DzikirItem {
  final String id;
  final String arabic;
  final String transliteration;
  final String translation;
  final int targetCount;
  final String? source;

  DzikirItem({
    required this.id,
    required this.arabic,
    required this.transliteration,
    required this.translation,
    required this.targetCount,
    this.source,
  });

  factory DzikirItem.fromJson(Map<String, dynamic> json) {
    return DzikirItem(
      id: json['id'] as String,
      arabic: json['arabic'] as String? ?? '',
      transliteration: json['transliteration'] as String? ?? '',
      translation: json['translation'] as String? ?? '',
      targetCount: json['target_count'] as int? ?? 1,
      source: json['source'] as String?,
    );
  }
}

/// Types of dzikir sessions.
enum DzikirType { pagi, petang }

/// Service to load dzikir data and manage counters.
class DzikirService {
  DzikirService._();
  static final DzikirService instance = DzikirService._();

  final Map<DzikirType, List<DzikirItem>> _cache = {};

  /// Load dzikir items from bundled JSON.
  Future<List<DzikirItem>> getDzikir(DzikirType type) async {
    if (_cache.containsKey(type)) return _cache[type]!;

    final path = type == DzikirType.pagi
        ? 'assets/dzikir/dzikir_pagi.json'
        : 'assets/dzikir/dzikir_petang.json';

    try {
      final jsonString = await rootBundle.loadString(path);
      final List<dynamic> data = json.decode(jsonString);
      _cache[type] =
          data.map((d) => DzikirItem.fromJson(d as Map<String, dynamic>)).toList();
    } catch (_) {
      _cache[type] = [];
    }

    return _cache[type]!;
  }

  /// Get counters for a specific date from Hive.
  Map<String, int> getCountersForDate(String date) {
    final box = Hive.box<DzikirCounter>(HiveBoxes.dzikirCounters);
    final result = <String, int>{};

    for (final key in box.keys) {
      final counter = box.get(key);
      if (counter != null && counter.date == date) {
        result[counter.dzikirId] = counter.count;
      }
    }

    return result;
  }

  /// Increment a dzikir counter for a specific ID on a specific date.
  Future<void> increment(String dzikirId, String date, int target) async {
    final box = Hive.box<DzikirCounter>(HiveBoxes.dzikirCounters);
    final key = '${dzikirId}_$date';

    final existing = box.get(key);
    if (existing != null) {
      existing.count = (existing.count + 1).clamp(0, target);
      await existing.save();
    } else {
      await box.put(
        key,
        DzikirCounter(
          dzikirId: dzikirId,
          date: date,
          count: 1,
          target: target,
        ),
      );
    }
  }

  /// Get today's date string.
  String get todayKey => DateFormat('yyyy-MM-dd').format(DateTime.now());
}
