import 'package:chepuhagram/data/datasources/local_db_service.dart';
import 'package:flutter/material.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'dart:convert';
import 'dart:io';
import '/core/constants.dart';
import 'package:http/http.dart' as http;
import 'package:chepuhagram/domain/services/api_service.dart';
import 'package:chepuhagram/data/datasources/ws_client.dart';
import 'package:chepuhagram/domain/services/crypto_service.dart';

class AuthProvider extends ChangeNotifier {
  bool _isLoading = false;
  bool get isLoading => _isLoading;

  int? _currentUserId;
  int? get currentUserId => _currentUserId;

  String? _username;
  String? get username => _username;

  String? _firstName;
  String? get firstName => _firstName;

  String? _lastName;
  String? get lastName => _lastName;

  String? _phone;
  String? get phone => _phone;

  String? _email;
  String? get email => _email;

  String? _about;
  String? get about => _about;

  String? _avatarPath;
  String? get avatarPath => _avatarPath;

  String? _avatarUrl;
  String? get avatarUrl => _avatarUrl;

  // Privacy settings
  bool? _showEmail;
  bool? get showEmail => _showEmail;

  bool? _showPhone;
  bool? get showPhone => _showPhone;

  bool? _showAvatar;
  bool? get showAvatar => _showAvatar;

  bool? _showAbout;
  bool? get showAbout => _showAbout;

  bool? _showUsername;
  bool? get showUsername => _showUsername;

  String get displayName {
    final full = '${_firstName ?? ''} ${_lastName ?? ''}'.trim();
    if (full.isNotEmpty) return full;
    if ((_username ?? '').isNotEmpty) return _username!;
    return 'User';
  }

  // Флаги для определения пути пользователя
  bool _needsSetup = false;
  bool get needsSetup => _needsSetup;

  bool _needsKeyRecovery = false;
  bool get needsKeyRecovery => _needsKeyRecovery;

  bool _hasPublicKeyOnServer = false;
  bool get hasPublicKeyOnServer => _hasPublicKeyOnServer;

  final _storage = const FlutterSecureStorage();
  final _client = http.Client();
  final ApiService _apiService = ApiService();
  final SocketService _socketService = SocketService();
  final CryptoService _cryptoService = CryptoService();

  Future<void> initRealtime() async {
    try {
      await _socketService.connect(_apiService);
    } catch (e) {
      throw Exception(e);
    }
  }

  void closeRealtime() {
    _socketService.disconnect();
  }

  SocketService get socketService => _socketService;

  Future<bool> login(String username, String password, {String? totpCode}) async {
    _isLoading = true;
    notifyListeners();

    try {
      final body = {'username': username, 'password': password};
      if (totpCode != null) {
        body['totp_code'] = totpCode;
      }
      final response = await _client.post(
        Uri.parse('${AppConstants.baseUrl}/auth/login'),
        headers: {'Content-Type': 'application/json'},
        body: jsonEncode(body),
      );

      final decodedResponse =
          jsonDecode(utf8.decode(response.bodyBytes)) as Map;

      if (response.statusCode == 200) {
        await _storage.write(
          key: 'access_token',
          value: decodedResponse['access_token'],
        );
        await _storage.write(
          key: 'refresh_token',
          value: decodedResponse['refresh_token'],
        );
        await _storage.write(
          key: 'user_id',
          value: decodedResponse['user_id'].toString(),
        );
        _currentUserId = decodedResponse['user_id'];

        // Проверяем статус аккаунта (нужна ли настройка или восстановление)
        await _checkAccountStatus();

        _isLoading = false;
        notifyListeners();
        return true;
      } else {
        _isLoading = false;
        notifyListeners();
        final error = decodedResponse['detail'] ?? 'Ошибка запроса';
        throw Exception(error);
      }
    } catch (e) {
      _isLoading = false;
      notifyListeners();
      rethrow;
    }
  }

  Future<void> logout() async {
    final mode = await _storage.read(key: 'theme_mode');
    final color = await _storage.read(key: 'accent_color');
    final wallpaper = await _storage.read(key: 'wallpaper_path');
    final avatar = await _storage.read(key: 'avatar_path');
    await _storage.deleteAll();
    final prefs = await SharedPreferences.getInstance();
    await prefs.clear();
    await LocalDbService().clearDatabase();
    _currentUserId = null;
    _username = null;
    _firstName = null;
    _lastName = null;
    _phone = null;
    _email = null;
    _about = null;
    _avatarPath = null;
    _avatarUrl = null;
    if (mode != null) {
      await _storage.write(key: 'theme_mode', value: mode);
    }
    if (color != null) {
      await _storage.write(key: 'accent_color', value: color);
    }
    if (wallpaper != null) {
      await _storage.write(key: 'wallpaper_path', value: wallpaper);
    }
    if (avatar != null) {
      await _storage.write(key: 'avatar_path', value: avatar);
    }
    notifyListeners();
  }

  Future<bool> tryAutoLogin() async {
    final token = await _apiService.getAccessToken();
    if (token == null) return false;

    // Загружаем currentUserId из хранилища
    /*final userIdStr = await _storage.read(key: 'user_id');
    if (userIdStr != null) {
      _currentUserId = int.tryParse(userIdStr);
    }

    try {
      final response = await _client
          .get(
            Uri.parse('${AppConstants.baseUrl}/users/me'),
            headers: {'Authorization': 'Bearer $token'},
          )
          .timeout(const Duration(seconds: 5));

      if (response.statusCode == 200) {
        // Проверяем статус аккаунта для определения дальнейшего пути
        await _checkAccountStatus();
        return true;
      } else if (response.statusCode == 401) {
        bool isUpdated = await _apiService.refreshToken();
        if (isUpdated) {
          // После обновления токена проверяем статус
          await _checkAccountStatus();
        }
        return isUpdated;
      } else {
        return false;
      }
    } catch (e) {
      // Если сервер недоступен, позволяем offline mode
      return true;
    }*/
    return true;
  }

  Future<bool> updateProfileAndSecurity({
    required String firstName,
    String? lastName,
    required String masterPassword,
  }) async {
    notifyListeners();

    try {
      final token = await _apiService.getAccessToken();

      // Генерируем ключи и шифруем приватный
      final keys = await _cryptoService.initAccountSecurity(masterPassword);

      final response = await _client.post(
        Uri.parse('${AppConstants.baseUrl}/auth/setup-account'),
        headers: {
          'Content-Type': 'application/json',
          'Authorization': 'Bearer $token',
        },
        body: jsonEncode({
          'first_name': firstName,
          'last_name': lastName,
          'public_key': keys['public_key'],
          'encrypted_private_key': keys['encrypted_private_key'],
        }),
      );

      if (response.statusCode == 200) {
        _needsSetup = false;
        notifyListeners();
        return true;
      } else {
        print("Ошибка настройки профиля: ${response.body}");
        return false;
      }
    } catch (e) {
      print("Ошибка сети: $e");
      return false;
    } finally {
      notifyListeners();
    }
  }

  // Приватный метод для проверки статуса аккаунта
  Future<void> _checkAccountStatus() async {
    try {
      final token = await _apiService.getAccessToken();
      final response = await _client.get(
        Uri.parse('${AppConstants.baseUrl}/users/me'),
        headers: {'Authorization': 'Bearer $token'},
      );

      if (response.statusCode == 200) {
        final data = jsonDecode(utf8.decode(response.bodyBytes)) as Map;

        _currentUserId = data['id'] as int?;
        _username = data['username']?.toString();
        _firstName = data['first_name']?.toString();
        _lastName = data['last_name']?.toString();
        _phone = data['phone']?.toString();
        _email = data['email']?.toString();
        _about = data['about']?.toString();
        final avatarFileId = data['avatar_file_id']?.toString();
        _avatarUrl = avatarFileId != null ? '${AppConstants.baseUrl}/media/$avatarFileId' : null;

        // Загружаем локальные настройки
        _avatarPath = await _storage.read(key: 'avatar_path');

        // Проверяем наличие публичного ключа на сервере
        _hasPublicKeyOnServer =
            data['public_key'] != null && data['public_key'].isNotEmpty;

        // Проверяем наличие приватного ключа локально
        final hasLocalPrivateKey =
            await _storage.read(key: 'private_key') != null;

        if (!_hasPublicKeyOnServer) {
          // Путь А: Первая настройка - нужно создать ключи и профиль
          _needsSetup = true;
          _needsKeyRecovery = false;
        } else if (!hasLocalPrivateKey) {
          // Путь В: Переустановка - ключ на сервере, но его нет локально
          _needsKeyRecovery = true;
          _needsSetup = false;
        } else {
          // Путь Б: Нормальный вход - все в порядке
          _needsSetup = false;
          _needsKeyRecovery = false;
        }
      }

      // Загружаем настройки конфиденциальности
      try {
        final privacyData = await _apiService.getPrivacySettings();
        _showEmail = privacyData['show_email'] as bool?;
        _showPhone = privacyData['show_phone'] as bool?;
        _showAvatar = privacyData['show_avatar'] as bool?;
        _showAbout = privacyData['show_about'] as bool?;
        _showUsername = privacyData['show_username'] as bool?;
      } catch (e) {
        print("Ошибка загрузки настроек конфиденциальности: $e");
        // Устанавливаем значения по умолчанию
        _showEmail = true;
        _showPhone = true;
        _showAvatar = true;
        _showAbout = true;
        _showUsername = true;
      }
    } catch (e) {
      print("Ошибка проверки статуса: $e");
      _needsSetup = false;
      _needsKeyRecovery = false;
    }
    notifyListeners();
  }

  Future<void> refreshMe() async {
    await _checkAccountStatus();
  }

  // Метод для начала с чистого листа (новые ключи)
  Future<void> resetKeys() async {
    await _storage.delete(key: 'private_key');
    _needsKeyRecovery = false;
    notifyListeners();
  }

  void updateAvatarPath(String? path) {
    _avatarPath = path;
    if (path != null) {
      _storage.write(key: 'avatar_path', value: path);
    } else {
      _storage.delete(key: 'avatar_path');
    }
    notifyListeners();
  }

  Future<bool> updateAvatar(String path) async {
    try {
      final bytes = await File(path).readAsBytes();
      final fileId = await _apiService.uploadMedia(bytes);
      if (fileId != null) {
        final success = await _apiService.updateAvatar(fileId);
        if (success) {
          updateAvatarPath(path);
          await refreshMe(); // Обновить данные профиля, включая avatarUrl
          return true;
        }
      }
      return false;
    } catch (e) {
      print('Ошибка обновления аватарки: $e');
      return false;
    }
  }
}
