import 'package:flutter/foundation.dart';
import 'package:mypoint_flutter_app/core/services/web/web_helper.dart';

class WebData {
  WebData._internal();

  static final WebData _instance = WebData._internal();
  static WebData get instance => _instance;

  static const Duration _sdkTimeout = Duration(seconds: 10);
  static const String _defaultUserInfoKey = 'USER_ID';

  Map<String, dynamic>? _cachedUserInfo;

  /// Convenience static getter for cached data.
  static Map<String, dynamic>? get cachedUserInfo => _instance._cachedUserInfo;

  /// Return cached info if available, otherwise refresh from SDK.
  static Future<Map<String, dynamic>?> getInfoFromSDK({
    bool forceRefresh = false,
    dynamic key,
  }) {
    return _instance._getInfoFromSDK(forceRefresh: forceRefresh, key: key);
  }

  /// Refresh user info data and store it in memory.
  Future<Map<String, dynamic>?> refreshUserInfo({dynamic key}) =>
      _getInfoFromSDK(forceRefresh: true, key: key);

  /// Retrieve cached data (without hitting SDK).
  Map<String, dynamic>? get userInfo => _cachedUserInfo;

  /// Retrieve cached full name (if available).
  String? get _fullName => _extractFullName(_cachedUserInfo);

  /// Retrieve cached identity number (if available).
  String? get _identityNumber => _extractIdentityNumber(_cachedUserInfo);

  /// Retrieve cached email (if available).
  String? get _email => _extractEmail(_cachedUserInfo);

  /// Retrieve cached gender label/value (if available).
  String? get _gender => _extractGender(_cachedUserInfo);

  /// Retrieve cached address (if available).
  String? get _address => _extractAddress(_cachedUserInfo);

  /// Retrieve cached birthday (if available).
  String? get _birthday => _extractBirthday(_cachedUserInfo);

  /// Retrieve cached avatar (if available).
  String? get _avatar => _extractAvatar(_cachedUserInfo);

  /// Convenience static getter for cached full name.
  static String? getFullName() => _instance._fullName;

  /// Convenience static getter for cached identity number.
  static String? getIdentityNumber() => _instance._identityNumber;

  /// Convenience static getter for cached email.
  static String? getEmail() => _instance._email;

  /// Convenience static getter for cached gender.
  static String? getGender() => _instance._gender;

  /// Convenience static getter for cached address.
  static String? getAddress() => _instance._address;

  /// Convenience static getter for cached birthday.
  static String? getBirthday() => _instance._birthday;

  /// Convenience static getter for cached avatar.
  static String? getAvatar() => _instance._avatar;

  /// Clear cached SDK data.
  void clearUserInfo() {
    _cachedUserInfo = null;
  }

  Future<Map<String, dynamic>?> _getInfoFromSDK({
    bool forceRefresh = false,
    dynamic key,
  }) async {
    if (!kIsWeb) return null;
    if (!forceRefresh && _cachedUserInfo != null) {
      return _cachedUserInfo;
    }
    try {
      debugPrint('🔍 WebInfoData - Requesting info from x-app-sdk...');
      final ready = await _ensureSdkReady();
      if (!ready) {
        debugPrint('⚠️ WebInfoData - SDK not ready');
        return null;
      }
      final response = await webGetInfo(key ?? _defaultUserInfoKey).timeout(_sdkTimeout);
      debugPrint('🔍 WebInfoData - getInfo response: $response');
      if (response == null || response.isEmpty) {
        final error = webGetLastError();
        debugPrint('⚠️ WebInfoData - getInfo returned empty payload: $error');
        _cachedUserInfo = null;
        return null;
      }
      final status = response['status']?.toString().toLowerCase();
      if (status != null && status != 'success') {
        debugPrint('⚠️ WebInfoData - getInfo returned non-success status: $status');
        _cachedUserInfo = null;
        return null;
      }
      final userInfo = _mapFromDynamic(response['data']);
      if (userInfo != null && userInfo.isNotEmpty) {
        _cachedUserInfo = userInfo;
        debugPrint('✅ WebInfoData - User info cached from x-app-sdk');
        return _cachedUserInfo;
      }
      debugPrint('⚠️ WebInfoData - getInfo returned missing profile data');
      _cachedUserInfo = null;
    } catch (e) {
      debugPrint('❌ WebInfoData - Error getting profile from SDK: $e');
      _cachedUserInfo = null;
    }
    return null;
  }

  static Future<bool> _ensureSdkReady() async {
    try {
      await webInitializeXAppSDK().timeout(_sdkTimeout);
    } catch (e) {
      debugPrint('⚠️ WebInfoData - SDK init attempt failed: $e');
    }
    final ready = webIsSDKInitialized();
    return ready;
  }

  static Map<String, dynamic>? _mapFromDynamic(dynamic source) {
    if (source == null) return null;
    if (source is Map<String, dynamic>) {
      return source.map((key, value) => MapEntry(key, _normalizeDynamicValue(value)));
    }
    if (source is Map) {
      final mapped = <String, dynamic>{};
      source.forEach((key, dynamic value) {
        if (key == null) {
          return;
        }
        mapped[key.toString()] = _normalizeDynamicValue(value);
      });
      return mapped;
    }
    return null;
  }

  static dynamic _normalizeDynamicValue(dynamic value) {
    if (value is Map) {
      return _mapFromDynamic(value);
    }
    if (value is Iterable) {
      return List<dynamic>.from(value.map(_normalizeDynamicValue));
    }
    return value;
  }

  String? _extractFullName(Map<String, dynamic>? data) {
    if (data == null || data.isEmpty) {
      return null;
    }
    final possibleKeys = <String>[
      'Full_Name',
      'FullName',
      'fullName',
      'fullname',
      'full_name',
      'name',
    ];
    for (final key in possibleKeys) {
      final value = data[key];
      if (value is String && value.trim().isNotEmpty) {
        return value.trim();
      }
    }
    final workerSite = data['worker_site'];
    if (workerSite is Map) {
      final nestedName = _extractFullName(_mapFromDynamic(workerSite));
      if (nestedName != null && nestedName.isNotEmpty) {
        return nestedName;
      }
    }
    return null;
  }

  String? _extractIdentityNumber(Map<String, dynamic>? data) {
    if (data == null || data.isEmpty) {
      return null;
    }
    const possibleKeys = <String>[
      'identityNumber',
      'identity_number',
      'identificationNumber',
      'identification_number',
      'idNumber',
      'id_number',
    ];
    for (final key in possibleKeys) {
      final value = data[key];
      if (value is String && value.trim().isNotEmpty) {
        return value.trim();
      }
    }
    final workerSite = data['worker_site'];
    if (workerSite is Map) {
      final nestedIdentity = _extractIdentityNumber(_mapFromDynamic(workerSite));
      if (nestedIdentity != null && nestedIdentity.isNotEmpty) {
        return nestedIdentity;
      }
    }
    return null;
  }

  String? _extractEmail(Map<String, dynamic>? data) {
    if (data == null || data.isEmpty) {
      return null;
    }
    const possibleKeys = <String>[
      'email',
      'Email',
      'userEmail',
      'user_email',
    ];
    for (final key in possibleKeys) {
      final value = data[key];
      if (value is String && value.trim().isNotEmpty) {
        return value.trim();
      }
    }
    final workerSite = data['worker_site'];
    if (workerSite is Map) {
      final nestedEmail = _extractEmail(_mapFromDynamic(workerSite));
      if (nestedEmail != null && nestedEmail.isNotEmpty) {
        return nestedEmail;
      }
    }
    return null;
  }

  String? _extractGender(Map<String, dynamic>? data) {
    if (data == null || data.isEmpty) {
      return null;
    }
    const possibleKeys = <String>[
      'gender',
      'Gender',
      'sex',
      'sexLabel',
      'sex_label',
    ];
    for (final key in possibleKeys) {
      final value = data[key];
      if (value == null) {
        continue;
      }
      if (value is String && value.trim().isNotEmpty) {
        return value.trim();
      }
      if (value is num) {
        return value.toString();
      }
    }
    final workerSite = data['worker_site'];
    if (workerSite is Map) {
      final nestedGender = _extractGender(_mapFromDynamic(workerSite));
      if (nestedGender != null && nestedGender.isNotEmpty) {
        return nestedGender;
      }
    }
    return null;
  }

  String? _extractAddress(Map<String, dynamic>? data) {
    if (data == null || data.isEmpty) {
      return null;
    }
    const possibleKeys = <String>[
      'address',
      'Address',
      'addressFull',
      'address_full',
      'permanentAddress',
      'permanent_address',
    ];
    for (final key in possibleKeys) {
      final value = data[key];
      if (value is String && value.trim().isNotEmpty) {
        return value.trim();
      }
    }
    final workerSite = data['worker_site'];
    if (workerSite is Map) {
      final nestedAddress = _extractAddress(_mapFromDynamic(workerSite));
      if (nestedAddress != null && nestedAddress.isNotEmpty) {
        return nestedAddress;
      }
    }
    return null;
  }

  String? _extractBirthday(Map<String, dynamic>? data) {
    if (data == null || data.isEmpty) {
      return null;
    }
    const possibleKeys = <String>[
      'birthday',
      'birthDay',
      'birth_day',
      'dob',
      'dateOfBirth',
      'date_of_birth',
    ];
    for (final key in possibleKeys) {
      final value = data[key];
      if (value is String && value.trim().isNotEmpty) {
        return value.trim();
      }
    }
    final workerSite = data['worker_site'];
    if (workerSite is Map) {
      final nestedBirthday = _extractBirthday(_mapFromDynamic(workerSite));
      if (nestedBirthday != null && nestedBirthday.isNotEmpty) {
        return nestedBirthday;
      }
    }
    return null;
  }

  String? _extractAvatar(Map<String, dynamic>? data) {
    if (data == null || data.isEmpty) {
      return null;
    }
    const possibleKeys = <String>[
      'avatar',
      'avatarUrl',
      'avatarURL',
      'avatar_url',
      'avatar2',
      'avatar_2',
      'profileImage',
      'profile_image',
    ];
    for (final key in possibleKeys) {
      final value = data[key];
      if (value is String && value.trim().isNotEmpty) {
        return value.trim();
      }
    }
    final workerSite = data['worker_site'];
    if (workerSite is Map) {
      final nestedAvatar = _extractAvatar(_mapFromDynamic(workerSite));
      if (nestedAvatar != null && nestedAvatar.isNotEmpty) {
        return nestedAvatar;
      }
    }
    final workingSite = data['working_site'];
    if (workingSite is Map) {
      final nestedAvatar = _extractAvatar(_mapFromDynamic(workingSite));
      if (nestedAvatar != null && nestedAvatar.isNotEmpty) {
        return nestedAvatar;
      }
    }
    return null;
  }
}
