import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:get_it/get_it.dart';
import 'package:hmg_patient_app_new/core/app_state.dart';
import 'package:hmg_patient_app_new/features/medical_file/medical_file_view_model.dart';
import 'package:hmg_patient_app_new/features/profile_settings/models/get_patient_info_response_model.dart';
import 'package:hmg_patient_app_new/features/profile_settings/profile_settings_repo.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/profile_settings/widgets/preferred_language_widget.dart';
import 'package:hmg_patient_app_new/services/cache_service.dart';
import 'package:hmg_patient_app_new/services/error_handler_service.dart';
import 'package:hmg_patient_app_new/services/navigation_service.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
import 'package:screen_brightness/screen_brightness.dart';

class ProfileSettingsViewModel extends ChangeNotifier {
  static const String _darkModeKey = 'is_dark_mode';
  static const String _fontSizeStepKey = 'accessibility_font_size_step';
  static const String _visualModeKey = 'accessibility_visual_mode';

  final CacheService _cacheService;
  final ProfileSettingsRepo profileSettingsRepo;
  final ErrorHandlerService errorHandlerService;

  // ── Dark-mode state ──────────────────────────────────────────────────
  bool _isDarkMode = false;
  bool get isDarkMode => _isDarkMode;

  // ── Accessibility settings ───────────────────────────────────────────
  int _fontSizeStep = 2; // 0: Small, 1: Small-Medium, 2: Medium (default), 3: Medium-Large, 4: Large
  int get fontSizeStep => _fontSizeStep;

  String _visualMode = 'off'; // off, invert, dim, highContrast
  String get visualMode => _visualMode;

  // ── Update email state ───────────────────────────────────────────────
  bool isUpdateEmailLoading = false;
  bool isUpdateEmailSuccess = false;
  String? updateEmailError;

  // ── Update patient info state ────────────────────────────────────────
  bool isUpdatePatientInfoLoading = false;
  bool isUpdatePatientInfoSuccess = false;
  String? updatePatientInfoError;

  // ── Deactivate account state ─────────────────────────────────────────
  bool isDeactivateAccountLoading = false;
  bool isDeactivateAccountSuccess = false;
  String? deactivateAccountError;

  GetPatientInfoForUpdate? getPatientInfoForUpdate;
  bool isPatientProfileLoading = false;

  // ── Profile image state ──────────────────────────────────────────────
  bool isProfileImageLoading = false;
  bool isUploadingProfileImage = false;
  String? profileImageData;
  String? profileImageError;

  // ==================== EMAIL UPDATE ERROR TRACKING ====================
  // Individual field error for email
  String? _emailError;

  // Getter for email error
  String? get emailError => _emailError;

  // Clear email error
  void clearEmailError() {
    _emailError = null;
    notifyListeners();
  }

  // Validate email before updating
  bool validateEmail(String email) {
    final appState = GetIt.instance.get<AppState>();
    final isArabic = appState.isArabic();

    // Clear previous error
    _emailError = null;

    // Check if email is empty
    if (email.trim().isEmpty) {
      _emailError = isArabic ? "الرجاء إدخال البريد الإلكتروني" : "Please enter email address";
      notifyListeners();
      return false;
    }

    // Validate email format
    final bool emailIsValid = RegExp(r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9\-]+\.[a-zA-Z]{2,}$").hasMatch(email.trim());
    if (!emailIsValid) {
      _emailError = isArabic ? "الرجاء إدخال تنسيق بريد إلكتروني صالح" : "Please enter a valid email format";
      notifyListeners();
      return false;
    }

    // Email is valid
    notifyListeners();
    return true;
  }

  // ==================== EMERGENCY CONTACT ERROR TRACKING ====================
  // Individual field error for emergency contact
  String? _emergencyContactError;

  // Getter for emergency contact error
  String? get emergencyContactError => _emergencyContactError;

  // Clear emergency contact error
  void clearEmergencyContactError() {
    _emergencyContactError = null;
    notifyListeners();
  }

  // Validate emergency contact number before updating
  bool validateEmergencyContact(String contactNumber) {
    final appState = GetIt.instance.get<AppState>();
    final isArabic = appState.isArabic();

    // Clear previous error
    _emergencyContactError = null;

    // Check if contact number is empty
    if (contactNumber.trim().isEmpty) {
      _emergencyContactError = isArabic ? "الرجاء إدخال رقم الاتصال في حالات الطوارئ" : "Please enter emergency contact number";
      notifyListeners();
      return false;
    }

    // Remove any non-digit characters for validation
    String cleanedNumber = contactNumber.replaceAll(RegExp(r'[^0-9]'), '');

    // Check if it's a valid Saudi phone number (starts with 05 and has 10 digits)
    if (cleanedNumber.length != 10) {
      _emergencyContactError = isArabic ? "يجب أن يكون رقم الهاتف 10 أرقام" : "Phone number must be 10 digits";
      notifyListeners();
      return false;
    }

    if (!cleanedNumber.startsWith('05')) {
      _emergencyContactError = isArabic ? "يجب أن يبدأ رقم الهاتف بـ 05" : "Phone number must start with 05";
      notifyListeners();
      return false;
    }

    // Contact number is valid
    notifyListeners();
    return true;
  }

  ProfileSettingsViewModel({
    required CacheService cacheService,
    required this.profileSettingsRepo,
    required this.errorHandlerService,
  }) : _cacheService = cacheService;

  // ── Dark mode ────────────────────────────────────────────────────────

  /// Call once at app startup (before the first frame) to restore the
  /// persisted dark-mode preference.
  void loadDarkMode() {
    final saved = _cacheService.getBool(key: _darkModeKey);
    _isDarkMode = saved ?? false;
    AppColors.isDarkMode = _isDarkMode;
    // No notifyListeners() here — we are called before build.
  }

  void toggleDarkMode(bool value) {
    _isDarkMode = value;
    AppColors.isDarkMode = value;
    _cacheService.saveBool(key: _darkModeKey, value: value);
    notifyListeners();
  }

  // ── Accessibility settings ───────────────────────────────────────────

  /// Load accessibility settings at app startup
  void loadAccessibilitySettings() {
    _fontSizeStep = _cacheService.getInt(key: _fontSizeStepKey) ?? 2;
    _visualMode = _cacheService.getString(key: _visualModeKey) ?? 'off';

    // Apply brightness based on saved visual mode
    _applyBrightnessForMode(_visualMode);

    // No notifyListeners() here — we are called before build.
  }

  /// Update font size step and save to cache
  void setFontSizeStep(int step) {
    _fontSizeStep = step;
    _cacheService.saveInt(key: _fontSizeStepKey, value: step);
    notifyListeners();
  }

  /// Update visual mode and save to cache
  void setVisualMode(String mode) {
    _visualMode = mode;
    _cacheService.saveString(key: _visualModeKey, value: mode);
    notifyListeners();
  }

  /// Apply screen brightness based on visual mode
  void _applyBrightnessForMode(String mode) async {
    try {
      final screenBrightness = ScreenBrightness();

      if (mode == 'dim') {
        // Reduce brightness to 40% for dim mode
        await screenBrightness.setScreenBrightness(0.4);
      } else {
        // For other modes, reset to system brightness
        await screenBrightness.resetScreenBrightness();
      }
    } catch (e) {
      print('Error applying brightness for mode: $e');
    }
  }

  /// Get font scale multiplier based on current font size step
  double getFontScaleMultiplier() {
    switch (_fontSizeStep) {
      case 0:
        return 0.85; // Small
      case 1:
        return 0.95; // Small-Medium
      case 2:
        return 1.0; // Medium (default)
      case 3:
        return 1.15; // Medium-Large
      case 4:
        return 1.3; // Large
      default:
        return 1.0;
    }
  }

  // ── Update patient info ──────────────────────────────────────────────

  Future<void> updatePatientInfo({
    required Map<String, dynamic> patientInfo,
    Function(dynamic)? onSuccess,
    Function(String)? onError,
  }) async {
    isUpdatePatientInfoLoading = true;
    isUpdatePatientInfoSuccess = false;
    updatePatientInfoError = null;
    notifyListeners();

    final result = await profileSettingsRepo.updatePatientInfo(patientInfo: patientInfo);

    result.fold(
      (failure) {
        isUpdatePatientInfoLoading = false;
        updatePatientInfoError = failure.message;
        notifyListeners();
        if (onError != null) {
          onError(failure.message);
        } else {
          errorHandlerService.handleError(failure: failure);
        }
      },
      (response) {
        isUpdatePatientInfoLoading = false;
        isUpdatePatientInfoSuccess = true;
        notifyListeners();
        onSuccess?.call(response.data);
      },
    );
  }

  Future<void> getProfileSettings({
    Function(dynamic)? onSuccess,
    Function(String)? onError,
  }) async {
    isPatientProfileLoading = true;
    notifyListeners();

    final result = await profileSettingsRepo.getProfileSettings();

    result.fold(
      (failure) {
        isPatientProfileLoading = false;
        notifyListeners();
        if (onError != null) {
          onError(failure.message);
        } else {
          errorHandlerService.handleError(failure: failure);
        }
      },
      (response) {
        getPatientInfoForUpdate = response.data;
        isPatientProfileLoading = false;
        notifyListeners();
        onSuccess?.call(response.data);
      },
    );
  }

  // ── Deactivate account ───────────────────────────────────────────────

  Future<void> deactivateAccount({
    Function(dynamic)? onSuccess,
    Function(String)? onError,
  }) async {
    isDeactivateAccountLoading = true;
    isDeactivateAccountSuccess = false;
    deactivateAccountError = null;
    notifyListeners();

    final result = await profileSettingsRepo.deactivateAccount();

    result.fold(
      (failure) {
        isDeactivateAccountLoading = false;
        deactivateAccountError = failure.message;
        notifyListeners();
        if (onError != null) {
          onError(failure.message);
        } else {
          errorHandlerService.handleError(failure: failure);
        }
      },
      (response) {
        isDeactivateAccountLoading = false;
        isDeactivateAccountSuccess = true;
        notifyListeners();
        onSuccess?.call(response.data);
      },
    );
  }

  // ── Helpers ──────────────────────────────────────────────────────────

  openPreferredLanguageBottomSheet() {
    showCommonBottomSheetWithoutHeight(
      title: LocaleKeys.preferredLanguage.tr(),
      GetIt.instance<NavigationService>().navigatorKey.currentContext!,
      child: PreferredLanguageWidget(),
      callBackFunc: () {},
      isFullScreen: false,
      isCloseButtonVisible: true,
    );
  }

  // ── Profile image ────────────────────────────────────────────────────

  Future<void> getProfileImage({
    required int patientID,
    Function(dynamic)? onSuccess,
    Function(String)? onError,
    bool forceRefresh = false, // Add flag to force refresh
  }) async {
    print('🌐 Fetching profile image from API for patient: $patientID (forceRefresh: $forceRefresh)');

    // IMPORTANT: Always clear old data BEFORE fetching
    // Do NOT use cached data - always fetch fresh from API
    profileImageData = null;

    isProfileImageLoading = true;
    profileImageError = null;
    notifyListeners(); // Notify to show loading state

    final result = await profileSettingsRepo.getProfileImage(patientID: patientID);

    result.fold(
      (failure) {
        isProfileImageLoading = false;
        profileImageError = failure.message;
        print('❌ Failed to fetch profile image: ${failure.message}');

        // Ensure data is cleared on failure
        profileImageData = null;

        notifyListeners();
        if (onError != null) {
          onError(failure.message);
        }
      },
      (response) {
        isProfileImageLoading = false;

        // Extract image data from response
        if (response.data != null && response.data['Patient_GetProfileImageDataList'] != null) {
          var imageList = response.data['Patient_GetProfileImageDataList'];
          if (imageList is List && imageList.isNotEmpty) {
            profileImageData = imageList[0]['ImageData'];

            if (profileImageData != null && profileImageData!.isNotEmpty) {
              // ONLY store in ViewModel - AppState will be updated separately by auth flow
              print('✅ Profile image loaded from API (length: ${profileImageData!.length})');
            } else {
              profileImageData = null;
              print('⚠️ Profile image data is empty in API response');
            }
          } else {
            profileImageData = null;
            print('⚠️ Profile image list is empty in API response');
          }
        } else {
          profileImageData = null;
          print('⚠️ No profile image data in API response');
        }

        notifyListeners(); // Notify to update UI with new/null data
        onSuccess?.call(response.data);
      },
    );
  }

  /// Clear profile image data from ViewModel
  void clearProfileImageCache() {
    print('🧹 Clearing profile image from ViewModel');
    profileImageData = null;
    notifyListeners();
  }

  /// Sync profile image data from AppState - DISABLED
  /// Profile Settings screen uses only ViewModel data from API
  void syncProfileImageFromAppState() {
    // DO NOTHING - Profile Settings uses only direct API data
    // No syncing from AppState to avoid stale cache issues
    print('⚠️ syncProfileImageFromAppState called but disabled - use API data only');
  }

  Future<void> uploadProfileImage({
    required int patientID,
    required String imageData,
    Function(dynamic)? onSuccess,
    Function(String)? onError,
  }) async {
    isUploadingProfileImage = true;
    profileImageError = null;
    notifyListeners();

    final result = await profileSettingsRepo.uploadProfileImage(
      patientID: patientID,
      imageData: imageData,
      isActive: true,
    );

    result.fold(
      (failure) {
        isUploadingProfileImage = false;
        profileImageError = failure.message;
        notifyListeners();
        if (onError != null) {
          onError(failure.message);
        } else {
          errorHandlerService.handleError(failure: failure);
        }
      },
      (response) {
        isUploadingProfileImage = false;
        profileImageData = imageData;

        // Store in AppState for global access FIRST
        GetIt.instance<AppState>().setProfileImageData = imageData;

        // Update the family files cache with the new profile image (after AppState update)
        try {
          final medicalFileViewModel = GetIt.instance.get<MedicalFileViewModel>();
          // Only update if family files are loaded
          if (medicalFileViewModel.patientFamilyFiles.isNotEmpty ||
              medicalFileViewModel.pendingFamilyFiles.isNotEmpty) {
            medicalFileViewModel.updateFamilyMemberProfileImage(patientID, imageData);
          } else {
            print("ℹ️ Family files not loaded yet, skipping cache update");
          }
        } catch (e) {
          print("⚠️ Could not update family files cache: $e");
        }

        notifyListeners();
        onSuccess?.call(response.data);
      },
    );
  }
}
