import 'package:flutter/foundation.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:get/get.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
import 'package:terepi_seged/services/app_logger.dart';

/// Ember által olvasható hitelesítési hiba.
class AuthServiceException implements Exception {
  final String message;
  AuthServiceException(this.message);
  @override
  String toString() => message;
}

/// Hitelesítési service — google_sign_in 7.x + Supabase.
///
/// Folyamat: natív Google bejelentkezés → idToken (+ accessToken az
/// authorizationClient-ből) → Supabase signInWithIdToken → Supabase
/// session (amit a supabase_flutter magától perzisztál és frissít, ezért
/// app-újraindításnál NEM kell újra Google-bejelentkezés).
///
/// FONTOS (google_sign_in 7.x változások a 6.x-hez képest):
///  * singleton: GoogleSignIn.instance (nincs konstruktor-példányosítás)
///  * kötelező egyszeri initialize() minden más hívás előtt
///  * signIn() helyett authenticate(); a megszakítást kivétel jelzi
///  * az authentication már csak idToken-t ad; accessToken a
///    authorizationClient-től kérhető
///
/// A GetX-minta szerint az állapot Rx-ekben él: a UI (drawer-fejléc,
/// beállítások) Obx-szel figyeli a currentUser-t.
class AuthService extends GetxService {
  static AuthService get to => Get.find();

  SupabaseClient get _supabase => Supabase.instance.client;

  // ── Reaktív állapot ──────────────────────────────────────────────
  final currentUser = Rxn<User>();
  final isBusy = false.obs;

  bool get isSignedIn => currentUser.value != null;

  String get displayName {
    final u = currentUser.value;
    if (u == null) return 'Nincs bejelentkezve';
    return (u.userMetadata?['full_name'] as String?) ??
        (u.userMetadata?['name'] as String?) ??
        u.email ??
        'Felhasználó';
  }

  String get email => currentUser.value?.email ?? '';

  String? get avatarUrl =>
      currentUser.value?.userMetadata?['avatar_url'] as String?;

  bool _googleInitialized = false;

  @override
  void onInit() {
    super.onInit();

    // A Supabase a sessiont maga perzisztálja — induláskor csak átvesszük.
    currentUser.value = _supabase.auth.currentUser;

    // Minden auth-változás (bejelentkezés, kijelentkezés, token-frissítés)
    // ide fut be; a UI a currentUser-en keresztül reagál.
    _supabase.auth.onAuthStateChange.listen((data) {
      currentUser.value = data.session?.user;
    }, onError: (Object error, StackTrace stack) {
      if (kDebugMode) debugPrint('[Auth] onAuthStateChange hiba: $error');
      AppLogger.e('Auth', '[Auth] onAuthStateChange hiba: $error');
    });
  }

  /// Egyszeri google_sign_in inicializálás (a 7.x megköveteli).
  /// A serverClientId a Supabase-ben engedélyezett WEB client ID —
  /// az idToken "közönsége" (aud) így egyezik a Supabase elvárásával.
  Future<void> _ensureGoogleInitialized() async {
    if (_googleInitialized) return;
    final webClientId = dotenv.env['GOOGLE_WEB_CLIENT_ID'];
    if (webClientId == null || webClientId.isEmpty) {
      throw AuthServiceException(
          'Hiányzó GOOGLE_WEB_CLIENT_ID a .env fájlból.');
    }
    await GoogleSignIn.instance.initialize(serverClientId: webClientId);
    _googleInitialized = true;
  }

  /// Google bejelentkezés → Supabase session.
  /// Visszatérés: true = bejelentkezve; false = a felhasználó megszakította.
  /// Egyéb hibánál [AuthServiceException]-t dob, magyar üzenettel.
  Future<bool> signInWithGoogle() async {
    if (isBusy.value) return false;
    isBusy.value = true;
    try {
      await _ensureGoogleInitialized();

      // Interaktív bejelentkezés — megszakítást kivétel jelzi (7.x).
      final GoogleSignInAccount account;
      try {
        account = await GoogleSignIn.instance.authenticate();
      } on GoogleSignInException catch (e) {
        if (e.code == GoogleSignInExceptionCode.canceled) return false;
        throw AuthServiceException('Google-bejelentkezési hiba: '
            '${e.description ?? e.code.name}');
      }

      final idToken = account.authentication.idToken;
      if (idToken == null) {
        throw AuthServiceException(
            'A Google nem adott vissza idToken-t — ellenőrizd a '
            'GOOGLE_WEB_CLIENT_ID beállítást.');
      }

      // accessToken a 7.x-ben külön engedélyezési lépés (a Supabase
      // Google idToken-flow-ja kéri).
      const scopes = ['email', 'profile'];
      final authorization =
          await account.authorizationClient.authorizationForScopes(scopes) ??
              await account.authorizationClient.authorizeScopes(scopes);

      await _supabase.auth.signInWithIdToken(
        provider: OAuthProvider.google,
        idToken: idToken,
        accessToken: authorization.accessToken,
      );

      // currentUser-t az onAuthStateChange listener állítja be.
      if (kDebugMode) {
        debugPrint('[Auth] Bejelentkezve: ${account.email}');
      }
      return true;
    } on AuthException catch (e) {
      throw AuthServiceException('Supabase hitelesítési hiba: ${e.message}');
    } finally {
      isBusy.value = false;
    }
  }

  /// Kijelentkezés mindkét oldalról (Supabase session + Google fiók).
  Future<void> signOut() async {
    isBusy.value = true;
    try {
      await _supabase.auth.signOut();
      if (_googleInitialized) {
        try {
          await GoogleSignIn.instance.signOut();
        } catch (_) {
          // A Google-oldali kijelentkezés hibája nem kritikus.
        }
      }
    } finally {
      isBusy.value = false;
    }
  }
}
