import 'package:isar/isar.dart';
import '../../../../core/errors/result.dart';
import '../../../../core/errors/errors.dart';
import '../../domain/entities/chat.dart';
import '../../domain/entities/message.dart';
import '../models/chat_model.dart';
import '../models/message_model.dart';
import 'chat_local_datasource.dart';

class ChatLocalDataSourceImpl implements ChatLocalDataSource {
  final Isar isar;

  ChatLocalDataSourceImpl(this.isar);

  @override
  Future<Result<List<Chat>>> getCachedChats() async {
    try {
      final chatModels = await isar.chatModels.where().sortByLastMessageTimeDesc().findAll();
      return Result.success(chatModels.map((m) => m.toEntity()).toList());
    } catch (e) {
      return Result.failure(AppError.database(message: e.toString()));
    }
  }

  @override
  Future<Result<void>> cacheChats(List<Chat> chats) async {
    try {
      final models = chats.map((c) => ChatModel.fromEntity(c)).toList();
      await isar.writeTxn(() async {
        await isar.chatModels.putAll(models);
      });
      return const Result.success(null);
    } catch (e) {
      return Result.failure(AppError.database(message: e.toString()));
    }
  }

  @override
  Future<Result<Chat>> getChatFromCache(String chatId) async {
    try {
      final model = await isar.chatModels.filter().idEqualTo(chatId).findFirst();
      if (model != null) {
        return Result.success(model.toEntity());
      }
      return const Result.failure(AppError.notFound(message: 'Chat not found in cache'));
    } catch (e) {
      return Result.failure(AppError.database(message: e.toString()));
    }
  }

  @override
  Future<Result<void>> cacheChat(Chat chat) async {
    try {
      final model = ChatModel.fromEntity(chat);
      await isar.writeTxn(() async {
        await isar.chatModels.put(model);
      });
      return const Result.success(null);
    } catch (e) {
      return Result.failure(AppError.database(message: e.toString()));
    }
  }

  @override
  Future<Result<List<Message>>> getMessagesFromCache(String chatId) async {
    try {
      final messageModels = await isar.messageModels
          .filter()
          .chatIdEqualTo(chatId)
          .sortByCreatedAtDesc()
          .findAll();
      return Result.success(messageModels.map((m) => m.toEntity()).toList());
    } catch (e) {
      return Result.failure(AppError.database(message: e.toString()));
    }
  }

  @override
  Future<Result<void>> cacheMessages(String chatId, List<Message> messages) async {
    try {
      final models = messages.map((m) => MessageModel.fromEntity(m)).toList();
      await isar.writeTxn(() async {
        await isar.messageModels.putAll(models);
      });
      return const Result.success(null);
    } catch (e) {
      return Result.failure(AppError.database(message: e.toString()));
    }
  }

  @override
  Future<Result<void>> clearCache() async {
    // ignore: avoid_print
    print('[DEBUG] ChatLocalDataSource.clearCache calling isar.clear()');
    try {
      await isar.writeTxn(() => isar.clear());
      // ignore: avoid_print
      print('[DEBUG] ChatLocalDataSource.clearCache SUCCESS');
      return const Result.success(null);
    } catch (e) {
      // ignore: avoid_print
      print('[DEBUG] ChatLocalDataSource.clearCache ERROR: $e');
      return Result.failure(AppError.database(message: e.toString()));
    }
  }
}
