import 'dart:convert';

import 'package:autos/data/models/user_model.dart';
import 'package:autos/data/repositories/user_repository_impl.dart';
import 'package:autos/data/sources/remote/api_service.dart';
import 'package:autos/domain/entities/user.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_riverpod/legacy.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';

// Provide a single ApiService instance across the app
final apiServiceProvider = Provider<ApiService>((ref) => ApiService());

// Provide repository that depends on ApiService
final userRepositoryProvider = Provider<UserRepositoryImpl>(
  (ref) => UserRepositoryImpl(ref.read(apiServiceProvider)),
);

// Manage user state
final loginProvider = StateNotifierProvider<UserNotifier, AsyncValue<User?>>((
  ref,
) {
  final repo = ref.read(userRepositoryProvider);
  return UserNotifier(repo);
});

final signupProvider = StateNotifierProvider<UserNotifier, AsyncValue<User?>>((
  ref,
) {
  final repo = ref.read(userRepositoryProvider);
  return UserNotifier(repo);
});

final userProvider = StateNotifierProvider<UserNotifier, AsyncValue<User?>>((
  ref,
) {
  final repo = ref.read(userRepositoryProvider);
  return UserNotifier(repo);
});

final userDetailsProvider = FutureProvider<UserModel?>((ref) async {
  final userAsync = ref.watch(userProvider);

  // Waiting for login provider to finish
  if (userAsync.isLoading) return null;

  final user = userAsync.value;
  if (user == null) return null;

  // Fetch Full Details
  final repo = ref.read(userRepositoryProvider);
  return await repo.getUserDetails(user.id);
});

enum AuthAction { idle, login, signup }

class UserNotifier extends StateNotifier<AsyncValue<User?>> {
  final UserRepositoryImpl repository;
  final _storage = const FlutterSecureStorage();
  static const _userKey = 'logged_in_user';
  AuthAction lastAction = AuthAction.idle;

  UserNotifier(this.repository) : super(const AsyncValue.data(null));

  ///Load saved user from storage (auto-login)
  Future<void> loadUserFromStorage() async {
    final jsonString = await _storage.read(key: _userKey);
    if (jsonString != null) {
      debugPrint("RESULT: $jsonString");
      final jsonData = jsonDecode(jsonString);
      final user = UserModel.fromJson(jsonData);
      await Future.microtask(() {});
      state = AsyncValue.data(user);
    }
  }

  ///Login
  Future<void> login(String email, String password) async {
    lastAction = AuthAction.login;
    state = const AsyncValue.loading();
    try {
      final user = await repository.login(email, password);
      // ✅ Save user to secure storage
      if (user is UserModel) {
        await _storage.write(key: _userKey, value: user.toRawJson());
      }
      state = AsyncValue.data(user);
    } catch (e, st) {
      state = AsyncValue.error(e, st);
    }
  }

  /// Logout
  Future<void> logout() async {
    await _storage.delete(key: _userKey);
    state = const AsyncValue.data(null);
  }

  ///Sign up
  Future<void> signup(
    String name,
    String email,
    String password,
    String phone,
  ) async {
    lastAction = AuthAction.signup;
    state = const AsyncValue.loading();
    try {
      final user = await repository.signup(name, email, password, phone);
      state = AsyncValue.data(user);
    } catch (e, st) {
      state = AsyncValue.error(e, st);
    }
  }

  ///Reset password
  Future<void> sendPasswordResetLink(String email) async {
    state = const AsyncValue.loading();
    try {
      await repository.sendPasswordResetLink(email);
      state = const AsyncValue.data(null);
    } catch (e, st) {
      state = AsyncValue.error(e, st);
    }
  }

  /// Fetch user details from backend
  Future<void> getUserDetails(String userId) async {
    state = const AsyncValue.loading();

    try {
      final user = await repository.getUserDetails(userId);

      // Save full details separately
      await saveUserDetails(user);

      state = AsyncValue.data(user);
    } catch (e, st) {
      state = AsyncValue.error(e, st);
    }
  }

  /// Save full user details separately
  Future<void> saveUserDetails(UserModel user) async {
    await _storage.write(
      key: 'logged_in_user_details',
      value: user.toRawJson(),
    );
  }
}
