import 'package:baseproject/core/common/index.dart';
import 'package:baseproject/core/constants/index.dart';
import 'package:baseproject/core/extension/string_extension.dart';
import 'package:baseproject/features/repositories/hra_repository.dart';
import 'package:dartz/dartz.dart';
import 'package:dio/dio.dart';
import 'package:injectable/injectable.dart';

@lazySingleton
class UserUseCases {
  final HraRepository _hraRepository;

  UserUseCases(this._hraRepository);

  Future<Either<String, LoginResponseDto>> loginAccount(LoginDto request) async {
    try {
      final result = await _hraRepository.accountLoginMobile(request);

      if (result.data == null || result.success == false) {
        return Left<String, LoginResponseDto>(result.message ?? 'Login failed');
      }

      await saveToken(result.data?.token ?? '', refreshToken: result.data?.refreshToken ?? '');
      await saveUserInfo(result.data?.userInfo);

      return Right<String, LoginResponseDto>(result.data!);
    } catch (ex) {
      return Left<String, LoginResponseDto>(ex.toString());
    }
  }

  Future<void> saveToken(String token, {String? refreshToken}) async {
    await LocalStoreManager.setString(StorageKey.tokenUser, token);
    if (refreshToken != null) {
      await LocalStoreManager.setString(StorageKey.refreshToken, refreshToken);
    }
  }

  Future<void> saveUserInfo(UserInfoDto? userInfo) async {
    if (userInfo != null) {
      await LocalStoreManager.setObject(StorageKey.userInfo, userInfo.toJson());
    }
  }

  UserInfoDto? getUserInfo() {
    final Map<String, dynamic>? temp = LocalStoreManager.getObject(StorageKey.userInfo);
    if (temp != null) return UserInfoDto.fromJson(temp);
    return null;
  }

  int getCurrentUserId() {
    return getUserInfo()?.id?.toInt() ?? 0;
  }

  Future<void> clearData() async {
    await LocalStoreManager.remove(StorageKey.refreshToken);
    await LocalStoreManager.remove(StorageKey.tokenUser);
    await LocalStoreManager.remove(StorageKey.userInfo);
  }

  Future<Either<String, DNTCaptchaApiResponse>> getCaptcha() async {
    try {
      final result = await _hraRepository.accountCaptcha();

      return Right<String, DNTCaptchaApiResponse>(result);
    } catch (ex) {
      return Left<String, DNTCaptchaApiResponse>(ex.toString());
    }
  }

  Future<Either<String, bool>> refreshToken() async {
    final refreshToken = LocalStoreManager.getString(StorageKey.refreshToken);
    if (refreshToken.isNullOrEmpty) {
      return const Left<String, bool>('Refresh token not found');
    }
    try {
      final result = await _hraRepository.accountRefreshToken(
          RefreshTokenRequestDto(refreshToken: LocalStoreManager.getString(StorageKey.refreshToken)));
      if (result.data != null) {
        await saveToken(result.data?.token ?? '');
      }
      return Right<String, bool>(result.success ?? false);
    } catch (ex) {
      await clearData();
      return Left<String, bool>(ex.toString());
    }
  }

  Future<Either<String, UserInfoDto>> getUserInfoFromApi() async {
    try {
      final result = await _hraRepository.accountUserInfo();
      await saveUserInfo(result);
      return Right<String, UserInfoDto>(result);
    } catch (ex) {
      await clearData();
      return Left<String, UserInfoDto>(ex.toString());
    }
  }

  Future<bool> tryRefreshToken() async {
    try {
      RefreshTokenRequestDto requestModel =
          RefreshTokenRequestDto(refreshToken: LocalStoreManager.getString(StorageKey.refreshToken));
      final RefreshTokenResponseDtoApiResponse? token =
          await HraRepository(Dio(), baseUrl: ApiPath.hra).accountRefreshToken(requestModel);
      if (token != null) {
        await saveToken(token.data?.token ?? '');
      }

      return token != null;
    } catch (e) {
      return false;
    }
  }
}
