import 'package:drift/drift.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../../../shared/data/local/app_database.dart';
import '../../../../../main.dart';

final questRepositoryProvider = Provider<QuestRepository>((ref) {
  final db = ref.watch(appDatabaseProvider);
  return QuestRepository(db: db);
});

class QuestRepository {
  final AppDatabase db;

  QuestRepository({required this.db});

  Future<List<QuestCollection>> getActiveQuests() async {
    final now = DateTime.now();
    return await (db.select(db.quests)
          ..where((q) {
            final notExpired =
                q.expiresAt.isNull() | q.expiresAt.isBiggerThanValue(now);
            return notExpired;
          })
          ..orderBy([
            (q) =>
                OrderingTerm(expression: q.isCompleted, mode: OrderingMode.asc)
          ])) // Offene zuerst
        .get();
  }

  Future<void> createQuest(QuestCollection quest) async {
    await db.into(db.quests).insertOnConflictUpdate(QuestsCompanion(
          id: Value(quest.id),
          type: Value(quest.type),
          title: Value(quest.title),
          description: Value(quest.description),
          targetValue: Value(quest.targetValue),
          currentValue: Value(quest.currentValue),
          rewardXP: Value(quest.rewardXP),
          rewardItem: Value(quest.rewardItem),
          expiresAt: Value(quest.expiresAt),
          createdAt: Value(DateTime.now()),
        ));
  }

  Future<void> updateProgress(String questId, int addValue) async {
    final quest = await (db.select(db.quests)
          ..where((q) => q.id.equals(questId)))
        .getSingleOrNull();
    if (quest != null && !quest.isCompleted) {
      final newValue = quest.currentValue + addValue;
      final isComplete = newValue >= quest.targetValue;

      await (db.update(db.quests)..where((q) => q.id.equals(questId)))
          .write(QuestsCompanion(
        currentValue: Value(newValue),
        isCompleted: Value(isComplete),
      ));
    }
  }

  Future<void> claimQuest(String questId) async {
    await (db.update(db.quests)..where((q) => q.id.equals(questId))).write(
      const QuestsCompanion(isClaimed: Value(true)),
    );
  }

  Future<void> cleanupExpiredQuests() async {
    final now = DateTime.now();
    await (db.delete(db.quests)
          ..where((q) => q.expiresAt.isSmallerThanValue(now)))
        .go();
  }

  Stream<List<QuestCollection>> watchQuests() {
    return (db.select(db.quests)
          ..orderBy([
            (q) =>
                OrderingTerm(expression: q.isCompleted, mode: OrderingMode.desc)
          ]))
        .watch();
  }
}
