import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';

import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart';
import 'package:hmg_patient_app_new/core/app_export.dart';
import 'package:hmg_patient_app_new/core/app_state.dart';
import 'package:hmg_patient_app_new/core/dependencies.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/core/utils/image_compression_helper.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/features/profile_settings/profile_settings_view_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/image_picker.dart';
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart';

class ProfilePictureWidget extends StatefulWidget {
  const ProfilePictureWidget({super.key});

  @override
  State<ProfilePictureWidget> createState() => _ProfilePictureWidgetState();
}

class _ProfilePictureWidgetState extends State<ProfilePictureWidget> {
  final AppState _appState = getIt.get<AppState>();
  File? _selectedImage;
  int? _currentPatientId;
  bool _isInitialLoadTriggered = false;

  /// Cache decoded image bytes to avoid decoding base64 on every rebuild
  Uint8List? _cachedImageBytes;
  String? _cachedImageDataHash;

  @override
  void initState() {
    super.initState();
    _currentPatientId = _appState.getAuthenticatedUser()?.patientId;

    // Pre-cache existing image data if available (prevents blink from default → loaded)
    _tryCacheExistingImage();

    // Use addPostFrameCallback to ensure widget is built before loading
    WidgetsBinding.instance.addPostFrameCallback((_) {
      if (!mounted || _isInitialLoadTriggered) return;
      _isInitialLoadTriggered = true;

      final patientID = _appState.getAuthenticatedUser()?.patientId;

      if (patientID == null) {
        print('⚠️ No authenticated user found');
        return;
      }

      // Load fresh data from API
      print('📥 Loading fresh profile image from API for patient: $patientID');
      _loadProfileImage(forceRefresh: false);
    });
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    // Only check for user switch, NOT on initial load (initState handles that)
    if (_isInitialLoadTriggered) {
      _checkAndUpdateUserImage();
    }
  }

  @override
  void didUpdateWidget(ProfilePictureWidget oldWidget) {
    super.didUpdateWidget(oldWidget);
    _checkAndUpdateUserImage();
  }

  /// Pre-cache already-loaded image bytes so we don't flash default avatar
  void _tryCacheExistingImage() {
    final imageData = _appState.getProfileImageData;
    if (imageData != null && imageData.isNotEmpty) {
      try {
        _cachedImageBytes = base64Decode(imageData);
        _cachedImageDataHash = '${imageData.length}_${imageData.hashCode}';
      } catch (_) {
        _cachedImageBytes = null;
        _cachedImageDataHash = null;
      }
    }
  }

  void _checkAndUpdateUserImage() {
    // Check if the authenticated user has changed (family member switch)
    final currentPatientId = _appState.getAuthenticatedUser()?.patientId;

    if (currentPatientId != null && currentPatientId != _currentPatientId) {
      print('🔄 User switched detected: $_currentPatientId -> $currentPatientId');

      // Update patient ID IMMEDIATELY before any other operations
      final oldPatientId = _currentPatientId;
      _currentPatientId = currentPatientId;

      // Clear the old profile image data from BOTH AppState and ViewModel
      try {
        final profileVm = context.read<ProfileSettingsViewModel>();

        print('🧹 Clearing cache for old user: $oldPatientId');

        // Clear AppState cache first
        _appState.clearProfileImageCache();

        // Then clear ViewModel cache
        profileVm.clearProfileImageCache();

        // Clear local decoded bytes cache
        _cachedImageBytes = null;
        _cachedImageDataHash = null;

        // Force rebuild to show default avatar immediately
        if (mounted) {
          setState(() {
            _selectedImage = null; // Clear any selected image
          });
        }

        print('📥 Loading profile image for new user: $currentPatientId');
        // Load the new user's profile image immediately
        profileVm.getProfileImage(
          patientID: currentPatientId,
          forceRefresh: true,
          onSuccess: (data) {
            print('✅ Profile image loaded successfully for user: $currentPatientId');
            if (mounted) {
              _tryCacheExistingImage();
              setState(() {}); // Force rebuild to show new data
            }
          },
          onError: (error) {
            print('❌ Error loading profile image: $error');
            if (mounted) {
              setState(() {}); // Force rebuild to show default avatar
            }
          },
        );
      } catch (e) {
        print('❌ Error in _checkAndUpdateUserImage: $e');
      }
    }
  }

  void _loadProfileImage({bool forceRefresh = false}) {
    // Check if profile image is already loaded in AppState (skip if forcing refresh)
    if (!forceRefresh && _appState.getProfileImageData != null && _appState.getProfileImageData!.isNotEmpty) {
      // Image already loaded, no need to call API
      return;
    }

    final profileVm = context.read<ProfileSettingsViewModel>();
    final patientID = _appState.getAuthenticatedUser()?.patientId;

    if (patientID != null) {
      print('📥 Loading profile image for patient: $patientID (forceRefresh: $forceRefresh)');
      profileVm.getProfileImage(
        patientID: patientID,
        forceRefresh: forceRefresh,
        onSuccess: (data) {
          print('✅ Profile image loaded successfully');
          if (mounted) {
            _tryCacheExistingImage();
            setState(() {}); // Rebuild with new cached bytes
          }
        },
        onError: (error) {
          print('❌ Error loading profile image: $error');
          // Error loading image
        },
      );
    }
  }

  void _pickImage() {
    // Show image picker options without checking permissions first
    ImageOptions.showImageOptionsNew(
      context,
      false, // Don't show files option, only camera and gallery
      (base64String, file) async {
        try {
          print('=== Starting image processing ===');
          print('File path: ${file.path}');
          print('File exists: ${await file.exists()}');
          print('Original file size: ${await file.length() / 1024} KB');

          // Compress and resize the image
          print('Calling compressAndResizeImage...');
          final compressedFile = await ImageCompressionHelper.compressAndResizeImage(file);

          File finalFile;
          String finalBase64;

          if (compressedFile == null) {
            print('⚠️ Compression failed - using original file as fallback');

            // Fallback: use original image if compression fails
            final originalSize = await file.length();
            final maxSize = 1048576; // 1MB

            if (originalSize > maxSize) {
              print('❌ Original file is too large: ${originalSize / 1024} KB');
              if (mounted) {
                Utils.showToast(
                  LocaleKeys.imageSizeTooLarge.tr(context: context),
                );
              }
              return;
            }

            print('✅ Using original file (${originalSize / 1024} KB)');
            finalFile = file;
            var bytes = await file.readAsBytes();
            finalBase64 = base64.encode(bytes);
          } else {
            // Check compressed file size
            final fileSize = await compressedFile.length();
            final maxSize = 1048576; // 1MB
            print('✅ Compression successful: ${fileSize / 1024} KB');

            if (fileSize > maxSize) {
              print('❌ Compressed file still too large');
              if (mounted) {
                Utils.showToast(
                  LocaleKeys.imageSizeTooLarge.tr(context: context),
                );
              }
              return;
            }

            finalFile = compressedFile;
            var bytes = await compressedFile.readAsBytes();
            finalBase64 = base64.encode(bytes);
          }

          print('Converting to base64... Length: ${finalBase64.length}');

          if (mounted) {
            setState(() {
              _selectedImage = finalFile;
            });

            print('📤 Starting upload...');
            // Upload the image
            _uploadImage(finalBase64);
          }

          print('=== Image processing complete ===');
        } catch (e, stackTrace) {
          print('❌ Error in _pickImage: $e');
          print('Stack trace: $stackTrace');
          if (mounted) {
            Utils.showToast(
              LocaleKeys.failedToProcessImage.tr(context: context),
            );
          }
        }
      },
      checkCameraPermission: _checkCameraPermission,
      checkGalleryPermission: _checkGalleryPermission,
    );
  }

  Future<bool> _checkCameraPermission() async {
    try {
      print('=== Checking camera permission ===');

      // First check current status
      PermissionStatus currentStatus = await Permission.camera.status;
      print('Current camera permission status: $currentStatus');

      // If already granted, return true
      if (currentStatus.isGranted) {
        print('✅ Camera permission already granted');
        return true;
      }

      // If denied or permanently denied, show settings dialog
      if (currentStatus.isDenied || currentStatus.isPermanentlyDenied) {
        // Request permission first
        PermissionStatus newStatus = await Permission.camera.request();
        print('Camera permission after request: $newStatus');

        if (newStatus.isGranted) {
          print('✅ Camera permission granted');
          return true;
        }

        // Still denied - show settings dialog
        print('⚠️ Camera permission denied - showing settings dialog');
        if (mounted) {
          showCommonBottomSheetWithoutHeight(
            title: LocaleKeys.notice.tr(context: context),
            context,
            child: Utils.getWarningWidget(
              loadingText: LocaleKeys.cameraPermissionMessage.tr(context: context),
              isShowActionButtons: true,
              onCancelTap: () {
                Navigator.pop(context);
              },
              onConfirmTap: () async {
                openAppSettings();
              },
            ),
            callBackFunc: () {},
            isFullScreen: false,
            isCloseButtonVisible: true,
          );
        }
        return false;
      }

      // Request permission for the first time
      PermissionStatus newStatus = await Permission.camera.request();
      print('Camera permission after request: $newStatus');

      if (newStatus.isGranted) {
        print('✅ Camera permission granted');
        return true;
      }

      // Denied - show settings dialog
      print('❌ Camera permission denied - showing settings dialog');
      if (mounted) {
        showCommonBottomSheetWithoutHeight(
          title: LocaleKeys.notice.tr(context: context),
          context,
          child: Utils.getWarningWidget(
            loadingText: LocaleKeys.cameraPermissionMessage.tr(context: context),
            isShowActionButtons: true,
            onCancelTap: () {
              Navigator.pop(context);
            },
            onConfirmTap: () async {
              openAppSettings();
            },
          ),
          callBackFunc: () {},
          isFullScreen: false,
          isCloseButtonVisible: true,
        );
      }
      return false;
    } catch (e) {
      print('❌ Error checking camera permission: $e');
      if (mounted) {
        Utils.showToast(
          LocaleKeys.failedToCheckPermissions.tr(context: context),
        );
      }
      return false;
    }
  }

  Future<bool> _checkGalleryPermission() async {
    try {
      print('=== Checking gallery permission ===');

      // For Android 13+ (API 33+), the Android Photo Picker handles permissions internally
      // No need to request READ_MEDIA_IMAGES or READ_EXTERNAL_STORAGE permissions
      if (Platform.isAndroid) {
        print('✅ Android Photo Picker will handle permissions internally');
        return true;
      }

      // iOS: Check photos permission
      Permission galleryPermission = Permission.photos;

      // First check current status
      PermissionStatus currentStatus = await galleryPermission.status;
      print('Current gallery permission status: $currentStatus');

      // If already granted, return true
      if (currentStatus.isGranted || currentStatus.isLimited) {
        print('✅ Gallery permission already granted');
        return true;
      }

      // If denied or permanently denied, request permission first
      if (currentStatus.isDenied || currentStatus.isPermanentlyDenied) {
        // Request permission first
        PermissionStatus newStatus = await galleryPermission.request();
        print('Gallery permission after request: $newStatus');

        if (newStatus.isGranted || newStatus.isLimited) {
          print('✅ Gallery permission granted');
          return true;
        }

        // Still denied - show settings dialog
        print('⚠️ Gallery permission denied - showing settings dialog');
        if (mounted) {
          showCommonBottomSheetWithoutHeight(
            title: LocaleKeys.notice.tr(context: context),
            context,
            child: Utils.getWarningWidget(
              loadingText: LocaleKeys.galleryPermissionMessage.tr(context: context),
              isShowActionButtons: true,
              onCancelTap: () {
                Navigator.pop(context);
              },
              onConfirmTap: () async {
                openAppSettings();
              },
            ),
            callBackFunc: () {},
            isFullScreen: false,
            isCloseButtonVisible: true,
          );
        }
        return false;
      }

      // Request permission for the first time
      PermissionStatus newStatus = await galleryPermission.request();
      print('Gallery permission after request: $newStatus');

      if (newStatus.isGranted || newStatus.isLimited) {
        print('✅ Gallery permission granted');
        return true;
      }

      // Denied - show settings dialog
      print('❌ Gallery permission denied - showing settings dialog');
      if (mounted) {
        showCommonBottomSheetWithoutHeight(
          title: LocaleKeys.notice.tr(context: context),
          context,
          child: Utils.getWarningWidget(
            loadingText: LocaleKeys.galleryPermissionMessage.tr(context: context),
            isShowActionButtons: true,
            onCancelTap: () {
              Navigator.pop(context);
            },
            onConfirmTap: () async {
              openAppSettings();
            },
          ),
          callBackFunc: () {},
          isFullScreen: false,
          isCloseButtonVisible: true,
        );
      }
      return false;
    } catch (e) {
      print('❌ Error checking gallery permission: $e');
      if (mounted) {
        Utils.showToast(
          LocaleKeys.failedToCheckPermissions.tr(context: context),
        );
      }
      return false;
    }
  }

  void _uploadImage(String base64String) {
    final profileVm = context.read<ProfileSettingsViewModel>();
    final patientID = _appState.getAuthenticatedUser()?.patientId;

    if (patientID != null) {
      profileVm.uploadProfileImage(
        patientID: patientID,
        imageData: base64String,
        onSuccess: (data) {
          if (mounted) {
            // Update cached bytes immediately from the uploaded data
            _tryCacheExistingImage();
            setState(() {
              _selectedImage = null; // Clear selected image after successful upload
            });
            print(
              LocaleKeys.profileImageUpdatedSuccessfully.tr(context: context),
            );
          }
        },
        onError: (error) {
          Utils.showToast(error);
        },
      );
    }
  }

  Widget _buildProfileImage(ProfileSettingsViewModel profileVm) {
    // Always get fresh user data
    final currentUser = _appState.getAuthenticatedUser();
    final currentPatientId = currentUser?.patientId;
    final gender = currentUser?.gender ?? 1;
    final age = currentUser?.age ?? 0;

    // Determine the default image based on gender and age
    final String defaultImage;
    if (gender == 1) {
      // Male
      defaultImage = age < 7 ? AppAssets.babyBoyImg : AppAssets.maleImg;
    } else {
      // Female
      defaultImage = age < 7 ? AppAssets.babyGirlImg : AppAssets.femaleImg;
    }

    // Show selected image if available (only during upload)
    if (_selectedImage != null) {
      return ClipOval(
        child: Image.file(
          _selectedImage!,
          width: 136.w,
          height: 136.h,
          fit: BoxFit.cover,
        ),
      );
    }

    // Use cached decoded bytes — update cache if source data changed
    final String? imageData = GetIt.instance<AppState>().getProfileImageData;
    final String? currentHash = (imageData != null && imageData.isNotEmpty) ? '${imageData.length}_${imageData.hashCode}' : null;

    // Re-decode only if the underlying data actually changed
    if (currentHash != null && currentHash != _cachedImageDataHash) {
      try {
        _cachedImageBytes = base64Decode(imageData!);
        _cachedImageDataHash = currentHash;
      } catch (e) {
        print('❌ Error decoding profile image: $e');
        _cachedImageBytes = null;
        _cachedImageDataHash = null;
      }
    } else if (currentHash == null) {
      _cachedImageBytes = null;
      _cachedImageDataHash = null;
    }

    // Show cached decoded image if available
    if (_cachedImageBytes != null) {
      return ClipOval(
        child: Image.memory(
          _cachedImageBytes!,
          key: ValueKey('profile_$currentPatientId'),
          width: 136.w,
          height: 136.h,
          fit: BoxFit.cover,
          gaplessPlayback: true, // Prevents blink during image rebuild
        ),
      );
    }

    // Show default image (no image data or user has no uploaded image)
    print('📷 Showing default avatar for user $currentPatientId');
    return Image.asset(
      defaultImage,
      key: ValueKey('default_$currentPatientId'),
      width: 136.w,
      height: 136.h,
      gaplessPlayback: true,
    );
  }

  @override
  Widget build(BuildContext context) {
    // Removed addPostFrameCallback from build() — it was causing redundant
    // _checkAndUpdateUserImage calls on every single rebuild.
    // didChangeDependencies + didUpdateWidget already handle user switches.

    return Consumer<ProfileSettingsViewModel>(
      builder: (context, profileVm, _) {
        // If we already have cached bytes, show the image even while "loading"
        // to prevent the shimmer→image blink on page open
        final bool showShimmer = profileVm.isProfileImageLoading && _cachedImageBytes == null && _selectedImage == null;

        return Center(
          child: Stack(
            children: [
              // Profile Image — use AnimatedSwitcher to smooth transition
              AnimatedSwitcher(
                duration: const Duration(milliseconds: 200),
                child: showShimmer
                    ? Container(
                        key: const ValueKey('shimmer'),
                        width: 136.w,
                        height: 136.h,
                        decoration: BoxDecoration(
                          shape: BoxShape.circle,
                          color: AppColors.greyTextColor.withValues(alpha: 0.2),
                        ),
                      ).toShimmer2(isShow: true)
                    : _buildProfileImage(profileVm),
              ),

              // Edit button
              Positioned(
                right: 0,
                top: 0,
                child: GestureDetector(
                  onTap: () {
                    if (!profileVm.isUploadingProfileImage) {
                      _pickImage();
                    }
                  },
                  child: Container(
                    width: 32.w,
                    height: 32.h,
                    decoration: BoxDecoration(
                      color: AppColors.primaryRedColor,
                      shape: BoxShape.circle,
                      border: Border.all(
                        color: AppColors.whiteColor,
                        width: 2.w,
                      ),
                    ),
                    child: profileVm.isUploadingProfileImage
                        ? SizedBox(
                            width: 16.w,
                            height: 16.h,
                            child: CircularProgressIndicator(
                              strokeWidth: 2.w,
                              valueColor: AlwaysStoppedAnimation<Color>(
                                AppColors.whiteColor,
                              ),
                            ).paddingAll(8.w),
                          )
                        : Icon(
                            Icons.camera_alt,
                            color: AppColors.whiteColor,
                            size: 16.w,
                          ),
                  ),
                ),
              ),
            ],
          ).paddingOnly(bottom: 24.h),
        );
      },
    );
  }
}
