import 'dart:developer';

import 'package:firebase_auth/firebase_auth.dart';
import 'package:injectable/injectable.dart';
import 'package:krow/core/application/clients/api/api_client.dart';
import 'package:krow/core/application/di/injectable.dart';
import 'package:krow/core/data/models/staff/staff.dart';
import 'package:krow/core/data/static/email_validation_constants.dart';
import 'package:krow/core/sevices/auth_state_service/auth_service_data_provider.dart';
import 'package:shared_preferences/shared_preferences.dart';

enum AuthStatus {
  authenticated,
  adminValidation,
  prepareProfile,
  unauthenticated,
  error
}

@injectable
class AuthService {
  final AuthServiceDataProvider _dataProvider;

  AuthService(this._dataProvider);

  Future<AuthStatus> getAuthStatus() async {
    User? user;
    try {
      user = FirebaseAuth.instance.currentUser;
      if (user == null) {
        return AuthStatus.unauthenticated;
      }
      user.getIdToken();
    } catch (e) {
      return AuthStatus.unauthenticated;
    }

    final staffStatus = await getCachedStaffStatus();

    if (staffStatus == StaffStatus.deactivated) {
      return AuthStatus.unauthenticated;
    } else if (staffStatus == StaffStatus.pending) {
      return AuthStatus.adminValidation;
    } else if (staffStatus == StaffStatus.registered ||
        staffStatus == StaffStatus.declined) {
      return AuthStatus.prepareProfile;
    } else {
      return AuthStatus.authenticated;
    }
  }

  Future<void> signInWithEmailLink({required Uri link}) async {
    final auth = FirebaseAuth.instance;

    //TODO: Investigate iOS issue that blocks correct usage of continue URL for seamless email verification
    //
    // if (!auth.isSignInWithEmailLink(link.toString())) {
    //   throw Exception('Invalid auth link provided.');
    // }
    //
    // final sharedPrefs = await SharedPreferences.getInstance();
    //
    // final userEmail = sharedPrefs.getString(
    //   EmailValidationConstants.storedEmailKey,
    // );
    //
    // if (userEmail == null) {
    //   throw Exception(
    //     'Failed to sign in user with Email Link, '
    //     'because the is no email stored',
    //   );
    // }
    //
    // await auth.currentUser?.linkWithCredential(
    //   EmailAuthProvider.credentialWithLink(
    //     email: userEmail,
    //     emailLink: link.toString(),
    //   ),
    // );

    final oobCode = link.queryParameters[EmailValidationConstants.oobCodeKey];

    if (oobCode == null) return;

    log('Incoming auth link: $link');

    return auth.applyActionCode(oobCode);
  }

  Future<StaffStatus?> getCachedStaffStatus() async {
    final SharedPreferences prefs = await SharedPreferences.getInstance();
    var uid = FirebaseAuth.instance.currentUser?.uid;

    try {
      var staffStatus = await _dataProvider.getStaffStatus();
      prefs.setInt('staff_status_$uid', staffStatus.index);
      return staffStatus;
    } catch (e) {
      log('Error in AuthService, on getCachedStaffStatus()', error: e);
    }

    if (uid != null) {
      var staffStatusIndex = prefs.getInt('staff_status_$uid');
      if (staffStatusIndex != null) {
        return StaffStatus.values[staffStatusIndex];
      }
    }
    return null;
  }

  void logout() {
    FirebaseAuth.instance.signOut();
    getIt<ApiClient>().dropCache();
  }

  Future<void> deleteAccount() async {
    await FirebaseAuth.instance.currentUser!.delete();
    getIt<ApiClient>().dropCache();
  }
}
