import 'dart:convert';

import 'package:comwell_key_app/database/comwell_db.dart';
import 'package:comwell_key_app/domain/models/user.dart';
import 'package:comwell_key_app/services/mappers/user_mapper.dart';
import 'package:comwell_key_app/services/models/user_dto.dart';
import 'package:comwell_key_app/utils/json.dart';
import 'package:drift/drift.dart';

import '../tables/user_table.dart';

part '../../.generated/database/daos/user_dao.g.dart';

@DriftAccessor(tables: [UserEntity])
class UserDAO extends DatabaseAccessor<ComwellDatabase> with _$UserDAOMixin {
  UserDAO(super.attachedDatabase);

  Future<void> saveUser(UserDto user) async {
    await insert([user]);
  }

  Future<void> insert(Iterable<UserDto> users) async {
    final entities = users.map((user) {
      final json = jsonEncode(user.toJson());
      return UserEntityCompanion.insert(id: user.id, json: json);
    });
    await batch((batch) => batch.insertAll(userEntity, entities,
        mode: InsertMode.insertOrReplace));
  }

  Future<User> getUser() async {
    final user = await select(userEntity).get();
    final json = jsonDecode(user.first.json) as Json;
    return UserDto.fromJson(json).toUser();
  }

  Stream<UserDto> watchUser() {
    return (select(userEntity).watch()).map((users) {
      final userTable = users.first;
      final json = jsonDecode(userTable.json) as Json;
      return UserDto.fromJson(json);
    });
  }
}