// lib/features/auth/services/auth_service.dart
import 'package:flutter/foundation.dart' show kDebugMode, debugPrint;
import 'package:shared_preferences/shared_preferences.dart';
import '../../../core/api/api_client.dart';
import '../../../core/api/api_endpoints.dart';
import '../../../core/auth/auth_guard.dart';
import '../../../core/storage/token_storage.dart';
import '../models/user_model.dart';

class AuthService {
  final ApiClient _api = ApiClient();

  /// LOGIN → returns UserModel
  Future<UserModel> login(String username, String password) async {
    try {
      final res = await _api.post(
        ApiEndpoints.login,
        body: {
          "username": username,
          "password": password,
        },
        requiresAuth: false,
      );

      final token = res['token'];
      if (token == null) {
        throw Exception('Token missing from response');
      }

      final serverUsername = (res['username'] is String && (res['username'] as String).isNotEmpty) ? res['username'] as String : null;
      final serverEmail = (res['email'] is String && (res['email'] as String).isNotEmpty) ? res['email'] as String : null;
      // savedEmail is the canonical identifier for this account
      final savedEmail = serverEmail ?? username;
      // candidate display name (server username or email fallback)
      final displayCandidate = serverUsername ?? savedEmail;

      // clear guest mode on successful login
      AuthGuard.setGuest(false);

      // save token (TokenStorage stays responsible for token)
      await TokenStorage.saveToken(token.toString(), savedEmail);

      // persist per-account fields in SharedPreferences
      final prefs = await SharedPreferences.getInstance();
      // mark current logged-in account
      await prefs.setString('current_email', savedEmail);
      // always keep a canonical 'email' pointing to current user's email for old callers
      await prefs.setString('email', savedEmail);
      // save per-account display name (do not overwrite an explicit per-account display name if already set)
      final perKey = 'display_name_$savedEmail';
      final existingPer = prefs.getString(perKey);
      if (existingPer == null || existingPer.trim().isEmpty) {
        await prefs.setString(perKey, displayCandidate);
      }
      // save server-provided email (if any) separately too
      if (serverEmail != null) await prefs.setString('server_email', serverEmail);

      // Save phone if provided (optional)
      if (res['phone_number'] != null) await prefs.setString('phone_number', res['phone_number'].toString());

      return UserModel.fromJson(res);
    } catch (e) {
      if (kDebugMode) debugPrint('AuthService.login error: $e');
      rethrow;
    }
  }

  /// REGISTER → returns UserModel
  Future<UserModel> register({
    required String email,
    required String phoneNumber,
    required String password,
  }) async {
    try {
      final res = await _api.post(
        ApiEndpoints.register,
        body: {
          "email": email,
          "phone_number": phoneNumber,
          "password": password,
        },
        requiresAuth: false,
      );

      final token = res['token'];
      if (token == null) {
        throw Exception('Token missing from response');
      }

      final serverUsername = (res['username'] is String && (res['username'] as String).isNotEmpty) ? res['username'] as String : null;
      final serverEmail = (res['email'] is String && (res['email'] as String).isNotEmpty) ? res['email'] as String : null;
      final savedEmail = serverEmail ?? email;
      final savedUsername = serverUsername ?? savedEmail;
      final savedRole = (res['role'] ?? 'user').toString();
      final savedPhone = (res['phone_number'] ?? phoneNumber)?.toString();

      // clear guest mode on successful registration
      AuthGuard.setGuest(false);

      // Save token + canonical user id for token storage
      await TokenStorage.saveToken(token.toString(), savedEmail);

      // Persist per-account keys
      final prefs = await SharedPreferences.getInstance();
      await prefs.setString('current_email', savedEmail);
      await prefs.setString('email', savedEmail);

      // Set display_name_<email> if not present yet
      final perKey = 'display_name_$savedEmail';
      final existing = prefs.getString(perKey);
      if (existing == null || existing.trim().isEmpty) {
        await prefs.setString(perKey, savedUsername);
      }

      // Optionally save phone/email in prefs
      await prefs.setString('server_email', savedEmail);
      if (savedPhone != null) await prefs.setString('phone_number', savedPhone);

      // Return a simple UserModel (defensive)
      return UserModel(
        username: savedUsername,
        email: savedEmail,
        role: savedRole,
        token: token.toString(),
        phoneNumber: savedPhone,
      );
    } catch (e) {
      if (kDebugMode) debugPrint('AuthService.register error: $e');
      rethrow;
    }
  }

  /// Logout – clear auth token and current_email (keep per-account display_name entries so they persist)
  Future<void> logout() async {
    try {
      final prefs = await SharedPreferences.getInstance();
      // clear token storage (should delete token + auth headers)
      await TokenStorage.clear();
      // remove current_email marker so no previous account remains current
      await prefs.remove('current_email');
      // Also remove canonical 'email' pointing to current user
      await prefs.remove('email');
      // Do not delete display_name_<email> entries — they are per-account and should remain on device.
    } catch (e) {
      if (kDebugMode) debugPrint('AuthService.logout warning: $e');
    }
  }
}
