import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

import '../models/auth_state.dart';
import 'auth_service.dart';

final authControllerProvider = AsyncNotifierProvider<AuthController, AuthState>(
  AuthController.new,
);

class AuthController extends AsyncNotifier<AuthState> {
  @override
  Future<AuthState> build() async {
    final session = await ref.read(authServiceProvider).restoreSession();
    if (session == null) {
      return const AuthState.unauthenticated();
    }
    final authState = AuthState.authenticated(
      token: session.token,
      userRole: session.userRole,
      routeId: session.routeId,
    );
    _subscribeIfCitizen(authState);
    return authState;
  }

  Future<void> login({required String email, required String password}) async {
    state = const AsyncLoading<AuthState>();
    try {
      final session = await ref
          .read(authServiceProvider)
          .login(email: email, password: password);
      final authState = AuthState.authenticated(
        token: session.token,
        userRole: session.userRole,
        routeId: session.routeId,
      );
      _subscribeIfCitizen(authState);
      state = AsyncData(authState);
    } catch (error, stackTrace) {
      state = AsyncError<AuthState>(error, stackTrace);
      rethrow;
    }
  }

  Future<void> register({
    required String name,
    required String email,
    required String phone,
    required String password,
    String? addressCalle,
    String? addressColonia,
    String? addressLabel,
    double? addressLat,
    double? addressLng,
  }) async {
    state = const AsyncLoading<AuthState>();
    try {
      final session = await ref
          .read(authServiceProvider)
          .register(
            name: name,
            email: email,
            phone: phone,
            password: password,
            addressCalle: addressCalle,
            addressColonia: addressColonia,
            addressLabel: addressLabel,
            addressLat: addressLat,
            addressLng: addressLng,
          );

      final authState = AuthState.authenticated(
        token: session.token,
        userRole: session.userRole,
        routeId: session.routeId,
      );
      _subscribeIfCitizen(authState);
      state = AsyncData(authState);
    } catch (error, stackTrace) {
      state = AsyncError<AuthState>(error, stackTrace);
      rethrow;
    }
  }

  Future<void> logout() async {
    final previousRouteId = state.value?.routeId;
    await ref.read(authServiceProvider).logout();
    if (previousRouteId != null) {
      FirebaseMessaging.instance.unsubscribeFromTopic('topic_$previousRouteId');
    }
    state = const AsyncData(AuthState.unauthenticated());
  }

  void _subscribeIfCitizen(AuthState authState) {
    if (authState.userRole == 'citizen' && authState.routeId != null) {
      FirebaseMessaging.instance.subscribeToTopic('topic_${authState.routeId}');
    }
  }
}
