import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:logger/logger.dart';
import 'package:pocketbase/pocketbase.dart';

import '../../../core/constants/app_constants.dart';
import 'pb_auth_store.dart';

// final apiClientProvider = Provider<ApiClient>((ref) => ApiClient());
final apiClientProvider =
    Provider<ApiClient>((ref) => throw UnimplementedError());

class ApiClient {
  late final PocketBase _pb;
  // final PbAuthStore _authStore;
  final Logger _logger;

  PocketBase get pb => _pb;

  Stream<AuthStoreEvent> get authStateChanges => _pb.authStore.onChange;

  ApiClient({
    required AuthStore authStore,
    Logger? logger,
  }) : _logger = logger ?? Logger() {
    _pb = PocketBase(
      AppConstants.apiBaseUrl,
      authStore: authStore, // Hier kommt der geladene Store rein
    );
  }
  // ApiClient({
  //   PbAuthStore? authStore,
  //   FlutterSecureStorage? storage,
  //   Logger? logger,
  // })  : _logger = logger ?? Logger(),
  //       _authStore = authStore ?? PbAuthStore(storage: storage) {
  //   _pb = PocketBase(
  //     AppConstants.apiBaseUrl,
  //     authStore: _authStore,
  //   );
  //   if (authStore == null) {
  //     _authStore.loadFromStorage();
  //   }
  // }

  Future<T> _handleRequest<T>(Future<T> Function() request) async {
    try {
      return await request();
    } on ClientException catch (e) {
      if (e.statusCode == 401) {
        _logger.w('🔄 Token expired or invalid (401). Attempting refresh...');
        try {
          await _pb.collection('users').authRefresh();
          return await request();
        } catch (refreshError) {
          _logger.e('❌ Token refresh failed - logging out',
              error: refreshError);
          _pb.authStore.clear();
          rethrow;
        }
      }
      _logger.e('API Error: ${e.statusCode} ${e.response}', error: e);
      rethrow;
    } catch (e) {
      _logger.e('Unexpected API Error', error: e);
      rethrow;
    }
  }

  Future<RecordAuth> login(String email, String password) async {
    try {
      final authData = await _pb.collection('users').authWithPassword(
            email,
            password,
          );
      _logger.i('✅ Login successful for ${authData.record.id}');
      return authData;
    } catch (e) {
      _logger.e('Login failed', error: e);
      rethrow;
    }
  }

  Future<RecordAuth> register({
    required String email,
    required String username,
    required String password,
    required double bodyweight,
    required Map<String, dynamic> inventorySettings,
    Map<String, dynamic>? exerciseVariants,
    Map<String, dynamic>? avatarConfig,
  }) async {
    try {
      final user = await _pb.collection('users').create(body: {
        'email': email,
        'name': username,
        'password': password,
        'passwordConfirm': password,
        'emailVisibility': true,
        'xp': 0,
        'level': 1,
        'current_bodyweight': bodyweight,
        'inventory_settings': inventorySettings,
        'exercise_variants': exerciseVariants ?? {},
        'avatar_config': avatarConfig ?? {},
      });

      return await login(email, password);
    } catch (e) {
      _logger.e('Registration failed', error: e);
      rethrow;
    }
  }

  Future<void> requestVerification(String email) async {
    try {
      await _pb.collection('users').requestVerification(email);
      _logger.i('Verification email requested for $email');
    } catch (e) {
      _logger.e('Request verification failed', error: e);
      rethrow;
    }
  }

  Future<void> refreshAuth() async {
    try {
      await _pb.collection('users').authRefresh();
      _logger.i('✅ Auth refreshed successfully');
    } catch (e) {
      _logger.e('Auth refresh failed', error: e);
      _pb.authStore.clear();
      rethrow;
    }
  }

  Future<void> logout() async {
    _pb.authStore.clear();
  }

  Future<Map<String, dynamic>> sync({
    required String lastSyncTimestamp,
    required Map<String, dynamic> pushData,
  }) async {
    return _handleRequest(() async {
      final result = await _pb.send(
        ApiEndpoints.sync,
        method: 'POST',
        body: {
          'last_sync_timestamp': lastSyncTimestamp,
          'push_data': pushData,
        },
      );
      return result as Map<String, dynamic>;
    });
  }

  Future<Map<String, dynamic>> createCycle(
      Map<String, double> trainingMaxes) async {
    return _handleRequest(() async {
      final result = await _pb.send(
        ApiEndpoints.cycleCreate,
        method: 'POST',
        body: {'training_maxes': trainingMaxes},
      );
      return result as Map<String, dynamic>;
    });
  }

  Future<Map<String, dynamic>> finishCycle(String cycleId) async {
    return _handleRequest(() async {
      final result = await _pb.send(
        ApiEndpoints.cycleFinish,
        method: 'POST',
        body: {'cycle_id': cycleId},
      );
      return result as Map<String, dynamic>;
    });
  }

  Future<Map<String, dynamic>> getCurrentCycle() async {
    return _handleRequest(() async {
      final result = await _pb.send(ApiEndpoints.cycleCurrent, method: 'GET');
      return result as Map<String, dynamic>;
    });
  }

  Future<Map<String, dynamic>> getStatsHistory({
    required String exercise,
    required String range,
  }) async {
    return _handleRequest(() async {
      final result = await _pb.send(
        ApiEndpoints.statsHistory,
        method: 'GET',
        query: {
          'exercise': exercise,
          'range': range,
        },
      );
      return result as Map<String, dynamic>;
    });
  }

  Future<Map<String, dynamic>> getStatsSummary() async {
    return _handleRequest(() async {
      final result = await _pb.send(ApiEndpoints.statsSummary, method: 'GET');
      return result as Map<String, dynamic>;
    });
  }

  Future<void> updateBodyweight(double bodyweight) async {
    await _handleRequest(() async {
      await _pb.send(
        ApiEndpoints.profileBodyweight,
        method: 'PATCH',
        body: {'bodyweight': bodyweight},
      );
    });
  }

  Future<void> updateInventory(Map<String, dynamic> inventory) async {
    await _handleRequest(() async {
      await _pb.send(
        ApiEndpoints.profileInventory,
        method: 'PATCH',
        body: inventory,
      );
    });
  }

  Future<void> updatePassword({
    required String userId,
    required String oldPassword,
    required String newPassword,
    required String newPasswordConfirm,
  }) async {
    await _handleRequest(() async {
      await _pb.collection('users').update(userId, body: {
        'oldPassword': oldPassword,
        'password': newPassword,
        'passwordConfirm': newPasswordConfirm,
      });
    });
  }

  Future<void> deleteAccount(String userId) async {
    await _handleRequest(() async {
      await _pb.collection('users').delete(userId);
    });
  }

  Future<void> resetProgress() async {
    await _handleRequest(() async {
      await _pb.send(
        ApiEndpoints.profileReset,
        method: 'POST',
      );
    });
  }

  String? getToken() {
    return _pb.authStore.token.isNotEmpty ? _pb.authStore.token : null;
  }

  String? getUserId() {
    return _pb.authStore.record?.id;
  }
}
