// ignore_for_file: prefer_single_quotes

import 'dart:convert';

import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:tm_app/core/utils/logger.dart';
import 'package:tm_app/data/services/api/auth_api.dart';
import 'package:tm_app/data/services/model/forgot_password_response/forgot_password_response_model.dart';
import 'package:tm_app/data/services/model/login_response/login_response_model.dart';
import 'package:tm_app/data/services/model/logout_response/logout_response.dart';
import 'package:tm_app/data/services/model/reset_password_response/reset_password_response.dart';
import 'package:tm_app/data/services/model/verify_otp_response/verify_otp_response_model.dart';

import '../../core/network/network_manager.dart';
import '../../core/utils/result.dart';

class AuthService {
  AuthService({required NetworkManager networkManager})
    : _networkManager = networkManager;

  final NetworkManager _networkManager;

  Future<Result<LoginResponseModel>> login({
    required String username,
    required String password,
  }) async {
    //get device fcm token
    final FirebaseMessaging firebaseMessaging = FirebaseMessaging.instance;
    final fcmToken = await firebaseMessaging.getToken();
    var data = jsonEncode({
      "password": password,
      "username": username,
      "device_token": fcmToken ?? '',
    });

    final result = await _networkManager.makeRequest(
      AuthApi.login,
      method: 'POST',
      (json) => LoginResponseModel.fromJson(json),
      data: data,
    );

    if (result is Ok<LoginResponseModel>) {
      final prefs = await SharedPreferences.getInstance();
      final token = result.value.data.accessToken;
      AppLogger().info('🔑 Bearer token: $token');
      final refreshToken = result.value.data.refreshToken;

      await prefs.setString('bearer', token!);
      await prefs.setString('refresh_token', refreshToken!);
    }
    return result;
  }

  Future<Result<LogoutResponse>> logout() async {
    final result = await _networkManager.makeRequest(
      AuthApi.logout,
      method: 'DELETE',
      (json) => LogoutResponse.fromJson(json),
    );
    return result;
  }

  Future<Result<ResetPasswordResponse>> resetPassword({
    required String newPassword,
    required String token,
  }) async {
    var data = jsonEncode({"new_password": newPassword, "token": token});
    final result = await _networkManager.makeRequest(
      AuthApi.resetPassword,
      method: 'POST',
      (json) => ResetPasswordResponse.fromJson(json),
      data: data,
    );
    return result;
  }

  Future<void> localLogout() async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.remove('bearer');
    await prefs.remove('refresh_token');
    appLogger.info('tokens cleared!');
  }

  Future<Result<ForgotPasswordResponseModel>> forgotPassword({
    required String email,
  }) async {
    final data = jsonEncode({"email": email});

    final result = await _networkManager.makeRequest(
      AuthApi.forgotPassword,
      method: 'POST',
      (json) => ForgotPasswordResponseModel.fromJson(json),
      data: data,
    );

    return result;
  }

  Future<Result<VerifyOtpResponseModel>> verifyOtp({
    required String code,
    required String email,
  }) async {
    final data = jsonEncode({"code": code, "email": email});

    final result = await _networkManager.makeRequest(
      AuthApi.forgotPasswordOtp,
      method: 'POST',
      (json) => VerifyOtpResponseModel.fromJson(json),
      data: data,
    );

    return result;
  }

  Future<Result<bool>> checkIsLoggedIn() async {
    final prefs = await SharedPreferences.getInstance();
    final token = prefs.getString('bearer');
    if (token == null) {
      return const Result.ok(false);
    }
    return const Result.ok(true);
  }
}
