import 'package:dio/dio.dart';

import '../../../errors/auth_exception.dart';
import '../../auth/token_storage.dart';
import '../../marianumconnect_api.dart';
import '../../marianumconnect_query.dart';

/// Probes that the stored bearer token still maps to the given credentials.
/// Server returns 200 only when the credentials belong to the user that the
/// token was issued for — a password rotation on that user's account flips
/// it to 401 even if the token itself would still be accepted.
///
/// Bypasses the shared dio singleton so the auth interceptor doesn't kick in
/// and obscure a real 401 with a silent re-login.
class AuthVerify extends MarianumConnectQuery {
  final MarianumConnectTokenStorage _tokenStorage;

  AuthVerify({
    MarianumConnectTokenStorage tokenStorage =
        const MarianumConnectTokenStorage(),
    Dio? dio,
  }) : _tokenStorage = tokenStorage,
       super(dio: dio ?? MarianumConnectApi.plainDio());

  /// Throws [AuthException] on 401 (credentials no longer match the token's
  /// user, token missing, or token rejected), other [AppException]s on
  /// network/server errors. Completes silently on success.
  Future<void> run({
    required String username,
    required String password,
  }) async {
    final token = await _tokenStorage.readToken();
    if (token == null || token.isEmpty) {
      throw AuthException.unauthorized(
        technicalDetails: 'AuthVerify: no bearer token in storage',
      );
    }
    return guard(() async {
      await dio.post<void>(
        endpoint('auth/verify'),
        data: {'username': username, 'password': password},
        options: Options(headers: {'Authorization': 'Bearer $token'}),
      );
    });
  }
}
