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

import '../../data/models/login_request_model.dart';
import '../../domain/entities/user_entity.dart';
import '../../domain/usecases/login_usecase.dart';

/// Authentication state
///
/// Represents the current authentication status and user data
class AuthState extends Equatable {
  /// Current authenticated user (null if not authenticated)
  final UserEntity? user;

  /// Whether user is authenticated
  final bool isAuthenticated;

  /// Whether an authentication operation is in progress
  final bool isLoading;

  /// Error message if authentication fails
  final String? error;

  const AuthState({
    this.user,
    this.isAuthenticated = false,
    this.isLoading = false,
    this.error,
  });

  /// Initial state (not authenticated, not loading)
  const AuthState.initial()
      : user = null,
        isAuthenticated = false,
        isLoading = false,
        error = null;

  /// Loading state
  const AuthState.loading()
      : user = null,
        isAuthenticated = false,
        isLoading = true,
        error = null;

  /// Authenticated state with user data
  const AuthState.authenticated(UserEntity user)
      : user = user,
        isAuthenticated = true,
        isLoading = false,
        error = null;

  /// Error state
  const AuthState.error(String message)
      : user = null,
        isAuthenticated = false,
        isLoading = false,
        error = message;

  /// Create a copy with modified fields
  AuthState copyWith({
    UserEntity? user,
    bool? isAuthenticated,
    bool? isLoading,
    String? error,
  }) {
    return AuthState(
      user: user ?? this.user,
      isAuthenticated: isAuthenticated ?? this.isAuthenticated,
      isLoading: isLoading ?? this.isLoading,
      error: error,
    );
  }

  @override
  List<Object?> get props => [user, isAuthenticated, isLoading, error];

  @override
  String toString() {
    return 'AuthState(isAuthenticated: $isAuthenticated, isLoading: $isLoading, error: $error, user: $user)';
  }
}

/// Auth state notifier that manages authentication state
///
/// Handles login, logout, and authentication status checks
class AuthNotifier extends StateNotifier<AuthState> {
  final LoginUseCase loginUseCase;
  final LogoutUseCase logoutUseCase;
  final CheckAuthStatusUseCase checkAuthStatusUseCase;
  final GetCurrentUserUseCase getCurrentUserUseCase;

  AuthNotifier({
    required this.loginUseCase,
    required this.logoutUseCase,
    required this.checkAuthStatusUseCase,
    required this.getCurrentUserUseCase,
  }) : super(const AuthState.initial());

  /// Login with username and password
  ///
  /// Updates state to loading, then either authenticated or error
  Future<void> login(String username, String password) async {
    // Set loading state
    state = const AuthState.loading();

    // Create login request
    final request = LoginRequestModel(
      username: username,
      password: password,
    );

    // Call login use case
    final result = await loginUseCase(request);

    // Handle result
    result.fold(
      (failure) {
        // Login failed - set error state
        state = AuthState.error(failure.message);
      },
      (user) {
        // Login successful - set authenticated state
        state = AuthState.authenticated(user);
      },
    );
  }

  /// Logout current user
  ///
  /// Clears authentication data and returns to initial state
  Future<void> logout() async {
    // Clear tokens from secure storage
    await logoutUseCase();

    // Always reset to initial state (clear local data even if API call fails)
    state = const AuthState.initial();
  }

  /// Check authentication status on app start
  ///
  /// Loads user data from storage if authenticated
  Future<void> checkAuthStatus() async {
    // Check if user is authenticated
    final isAuthenticated = await checkAuthStatusUseCase();

    if (isAuthenticated) {
      // Try to load user data
      final result = await getCurrentUserUseCase();

      result.fold(
        (failure) {
          // Failed to load user data - reset to initial state
          state = const AuthState.initial();
        },
        (user) {
          // User data loaded - set authenticated state
          state = AuthState.authenticated(user);
        },
      );
    } else {
      // Not authenticated - initial state
      state = const AuthState.initial();
    }
  }

  /// Clear error message
  void clearError() {
    if (state.error != null) {
      state = state.copyWith(error: null);
    }
  }

  /// Reset to initial state
  void reset() {
    state = const AuthState.initial();
  }
}
