import 'dart:convert';

import 'package:flutter/foundation.dart';
import 'package:shared_preferences/shared_preferences.dart';

import 'api_service.dart';
import 'user_model.dart';

class AuthService extends ChangeNotifier {
  AuthService({
    ApiService? api,
  }) : _api = api ??
            ApiService(
              baseUrl: ApiService.defaultBaseUrl,
              tokenProvider: () => null,
            );

  static const _tokenKey = 'auth_token';
  static const _userKey = 'auth_user_json';

  late ApiService _api;

  bool _initialized = false;
  bool _loading = false;
  String? _token;
  UserModel? _user;

  bool get initialized => _initialized;
  bool get loading => _loading;
  String? get token => _token;
  UserModel? get user => _user;
  bool get isAuthenticated => _token != null && _user != null;
  ApiService get api => _api;

  Future<void> init() async {
    final prefs = await SharedPreferences.getInstance();
    _token = prefs.getString(_tokenKey);
    final userJson = prefs.getString(_userKey);

    if (_token != null && userJson != null) {
      final decoded = jsonDecode(userJson);
      if (decoded is Map<String, dynamic>) {
        _user = UserModel.fromJson(decoded);
      }
    }

    _api = ApiService(
      baseUrl: ApiService.defaultBaseUrl,
      tokenProvider: () => _token,
    );

    if (_token != null) {
      try {
        await refreshMe();
      } catch (_) {}
    }

    _initialized = true;
    notifyListeners();
  }

  Future<void> login({
    required String identifier,
    required String password,
  }) async {
    _loading = true;
    notifyListeners();

    try {
      final data = await _api.postJson(
        '/api/v1/login',
        body: {
          'identifier': identifier,
          'password': password,
        },
      );

      final token = data['token'];
      final user = data['user'];

      if (token is! String || token.trim().isEmpty) {
        throw const ApiException(statusCode: 0, message: 'لم يتم استلام التوكن');
      }
      if (user is! Map<String, dynamic>) {
        throw const ApiException(statusCode: 0, message: 'بيانات المستخدم غير صالحة');
      }

      _token = token;
      _user = UserModel.fromJson(user);
      _api = ApiService(
        baseUrl: ApiService.defaultBaseUrl,
        tokenProvider: () => _token,
      );

      final prefs = await SharedPreferences.getInstance();
      await prefs.setString(_tokenKey, _token!);
      await prefs.setString(_userKey, jsonEncode(_user!.toJson()));

      await refreshMe();
    } finally {
      _loading = false;
      notifyListeners();
    }
  }

  Future<void> refreshMe() async {
    if (_token == null) {
      return;
    }

    final data = await _api.getJson('/api/v1/me');
    final user = data['user'];
    if (user is! Map<String, dynamic>) {
      throw const ApiException(statusCode: 0, message: 'بيانات المستخدم غير صالحة');
    }

    _user = UserModel.fromJson(user);
    final prefs = await SharedPreferences.getInstance();
    await prefs.setString(_userKey, jsonEncode(_user!.toJson()));
    notifyListeners();
  }

  Future<void> updatePassword({
    required String newPassword,
  }) async {
    if (_token == null) {
      throw const ApiException(statusCode: 401, message: 'يرجى تسجيل الدخول');
    }

    _loading = true;
    notifyListeners();
    try {
      await _api.postJson(
        '/api/v1/me/password',
        body: {
          'password': newPassword,
        },
      );
    } finally {
      _loading = false;
      notifyListeners();
    }
  }

  Future<void> logout() async {
    if (_token != null) {
      try {
        await _api.postJson('/api/v1/logout', body: {});
      } catch (_) {}
    }

    _token = null;
    _user = null;
    _api = ApiService(
      baseUrl: ApiService.defaultBaseUrl,
      tokenProvider: () => _token,
    );

    final prefs = await SharedPreferences.getInstance();
    await prefs.remove(_tokenKey);
    await prefs.remove(_userKey);
    notifyListeners();
  }
}
