import 'package:comwell_key_app/authentication/authentication_repository.dart';
import 'package:comwell_key_app/database/comwell_db.dart';
import 'package:comwell_key_app/domain/models/user.dart';
import 'package:comwell_key_app/services/api.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:comwell_key_app/utils/locator.dart';
import 'package:flutter/material.dart';

class ProfileRepository {
  final AuthenticationRepository _authenticationRepository;
  final Api _api;

  ProfileRepository(
    this._authenticationRepository,
    this._api,
  );

  Future<void> logOut() async {
    await _authenticationRepository.logOut();
  }

  Future<User> signupForComwellClub(User user) async {
    try {
      await _api.signupForComwellClub();
      return await _updateAndPersistUser(user);
    } catch (e, st) {
      debugPrint('Error during Comwell Club signup: $e');
      debugPrintStack(stackTrace: st);
      rethrow;
    }
  }

  Future<User> _updateAndPersistUser(User user) async {
    final userResponse = await _api.updateUser(user.toSimpleUserDto());
    final data = userResponse.data as Json;
    final userDto = UserDto.fromJson(data);
    final updatedUser = userDto.toUser();
    await locator<ComwellDatabase>().userDAO.saveUser(userDto);
    return updatedUser;
  }

  Future<User> fetchRemoteProfile() async {
    final response = await _api.fetchProfileSettings();
    final data = response.data as Json;
    final userDto = UserDto.fromJson(data);
    final user = userDto.toUser();
    return user;
  }

  Future<User?> _checkIfProfileSettingsExists() async {
    try {
      final user = await locator<ComwellDatabase>().userDAO.getUser();
      return user;
    } catch (e) {
      debugPrint("Error checking if profile settings exists: $e");
      return null;
    }
  }

  Future<User> _fetchAndSaveProfileSettingsToDatabase() async {
    try {
      final response = await _api.fetchProfileSettings();
      final data = response.data as Json;
      final userDto = UserDto.fromJson(data);
      final user = userDto.toUser();
      await locator<ComwellDatabase>().userDAO.saveUser(userDto);
      return user;
    } catch (e) {
      debugPrint("Error fetching profile settings: $e");
      rethrow;
    }
  }

  Future<User> fetchProfileSettings({bool fetchRemote = false}) async {
    if (fetchRemote) {
      final user = await fetchRemoteProfile();
      return user;
    }
    final user = await _checkIfProfileSettingsExists();
    if (user != null) {
      return user;
    }
    final newUser = await _fetchAndSaveProfileSettingsToDatabase();
    return newUser;
  }
}