import 'package:flutter/foundation.dart';
import 'package:universal_html/html.dart' as html;
import 'package:universal_html/js_util.dart';

/// X-App-SDK Service for Flutter Web
/// Provides simple integration with x-app-sdk for token retrieval and app closing
class XAppSDKService {
  static final XAppSDKService _instance = XAppSDKService._internal();
  factory XAppSDKService() => _instance;
  XAppSDKService._internal();

  bool _isInitialized = false;
  dynamic _sdkModule;
  String? _cachedToken;
  String? _lastError;

  /// Check if SDK is available and initialized
  bool get isInitialized => _isInitialized;

  /// Get cached token (if any)
  String? get cachedToken => _cachedToken;

  /// Get last error message
  String? get lastError => _lastError;

  /// Initialize the SDK service
  Future<void> initialize() async {
    if (!kIsWeb) {
      print('⚠️ XAppSDKService: Not running on web platform');
      return;
    }

    try {
      print('🔍 XAppSDKService: Initializing...');
      final module = await _loadSdkModule();
      if (module == null) {
        _lastError = 'x-app-sdk module could not be loaded';
        print('❌ XAppSDKService: $_lastError');
        return;
      }
      _sdkModule = module;
      _isInitialized = true;
      print('✅ XAppSDKService: Initialized successfully');
      
    } catch (e) {
      _lastError = 'Failed to initialize SDK: $e';
      print('❌ XAppSDKService: $_lastError');
    }
  }

  /// Get token from x-app-sdk
  Future<String?> getToken() async {
    if (!kIsWeb) {
      print('⚠️ XAppSDKService: getToken() called on non-web platform');
      return null;
    }

    if (!_isInitialized) {
      print('⚠️ XAppSDKService: SDK not initialized, attempting to initialize...');
      await initialize();
      if (!_isInitialized) {
        _lastError = 'SDK initialization failed';
        return null;
      }
    }

    try {
      print('🔍 XAppSDKService: Getting token...');
      
      final sdk = await _loadSdkModule();
      if (sdk == null) {
        _lastError = 'x-app-sdk not available';
        print('❌ XAppSDKService: $_lastError');
        return null;
      }

      final hasGetToken = _hasProperty(sdk, 'getToken');
      if (!hasGetToken) {
        _lastError = 'getToken method not found in SDK';
        print('❌ XAppSDKService: $_lastError');
        return null;
      }

      // Execute getToken method from SDK
      final result = await promiseToFuture(callMethod(sdk, 'getToken', []));
      
      if (result != null) {
        final status = getProperty(result, 'status')?.toString();
        final data = getProperty(result, 'data');
        final message = getProperty(result, 'message');
        final errorMessage = message?.toString();

        if (status == 'success' && data != null && data.toString().isNotEmpty) {
          final tokenString = data.toString();
          _cachedToken = tokenString;
          _lastError = null;
          final preview = tokenString.length > 8 ? tokenString.substring(0, 8) : tokenString;
          print('✅ XAppSDKService: Token retrieved successfully: $preview...');
          return _cachedToken;
        } else {
          final details = errorMessage?.isNotEmpty == true ? ' - $errorMessage' : '';
          _lastError = 'SDK returned status: $status$details';
          print('❌ XAppSDKService: $_lastError');
        }
      } else {
        _lastError = 'getToken returned null';
        print('❌ XAppSDKService: $_lastError');
      }
      
    } catch (e) {
      _lastError = 'Error getting token: $e';
      print('❌ XAppSDKService: $_lastError');
    }

    return null;
  }

  /// Close app and return to Super App
  Future<void> closeApp([Map<String, dynamic>? data]) async {
    if (!kIsWeb) {
      print('⚠️ XAppSDKService: closeApp() called on non-web platform');
      return;
    }

    if (!_isInitialized) {
      print('⚠️ XAppSDKService: SDK not initialized, attempting to initialize...');
      await initialize();
      if (!_isInitialized) {
        print('❌ XAppSDKService: Cannot close app - SDK not initialized');
        return;
      }
    }

    try {
      print('🔍 XAppSDKService: Closing app...');
      
      final sdk = await _loadSdkModule();
      if (sdk == null) {
        print('❌ XAppSDKService: x-app-sdk not available for closeApp');
        return;
      }

      final hasCloseApp = _hasProperty(sdk, 'closeApp');
      if (!hasCloseApp) {
        print('❌ XAppSDKService: closeApp method not found in SDK');
        return;
      }

      // Execute closeApp method from SDK with optional data
      if (data != null) {
        callMethod(sdk, 'closeApp', [data]);
        print('✅ XAppSDKService: App closed with data: $data');
      } else {
        callMethod(sdk, 'closeApp', []);
        print('✅ XAppSDKService: App closed successfully');
      }
      
    } catch (e) {
      print('❌ XAppSDKService: Error closing app: $e');
      // Fallback: try to close window or go back
      try {
        if (html.window.history.length > 1) {
          html.window.history.back();
        } else {
          html.window.close();
        }
        print('✅ XAppSDKService: Fallback close executed');
      } catch (fallbackError) {
        print('❌ XAppSDKService: Fallback close also failed: $fallbackError');
      }
    }
  }

  /// Clear cached token
  void clearToken() {
    _cachedToken = null;
    _lastError = null;
    print('🧹 XAppSDKService: Token cache cleared');
  }

  /// Reset service state
  void reset() {
    _isInitialized = false;
    _sdkModule = null;
    _cachedToken = null;
    _lastError = null;
    try {
      final loader = getProperty(html.window, '__xAppSdkLoader');
      if (loader != null) {
        if (_hasProperty(loader, 'resetCachedModule')) {
          callMethod(loader, 'resetCachedModule', []);
        }
      }
    } catch (_) {}
    print('🔄 XAppSDKService: Service reset');
  }

  Future<dynamic> _loadSdkModule() async {
    if (_sdkModule != null) {
      return _sdkModule;
    }

    // Access loader API exposed in JS
    final loader = getProperty(html.window, '__xAppSdkLoader');
    if (loader == null) {
      _lastError = 'x-app-sdk loader not found on global scope';
      print('❌ XAppSDKService: $_lastError');
      return null;
    }

    final hasLoadFunction = _hasProperty(loader, 'loadXAppSdkModule');
    if (!hasLoadFunction) {
      _lastError = 'x-app-sdk loader missing loadXAppSdkModule';
      print('❌ XAppSDKService: $_lastError');
      return null;
    }

    try {
      final module = await promiseToFuture(callMethod(loader, 'loadXAppSdkModule', []));
      if (module == null) {
        _lastError = 'x-app-sdk module resolved to null';
        print('❌ XAppSDKService: $_lastError');
        return null;
      }

      final source = getProperty(module, '__xAppSdkSource');
      if (source != null) {
        print('🔗 XAppSDKService: Module loaded from $source');
      }

      final hasGetToken = _hasProperty(module, 'getToken');
      final hasCloseApp = _hasProperty(module, 'closeApp');
      if (!hasGetToken || !hasCloseApp) {
        _lastError = 'x-app-sdk module missing required exports';
        print('❌ XAppSDKService: $_lastError');
        return null;
      }

      _sdkModule = module;
      return _sdkModule;
    } catch (e) {
      _lastError = 'Failed to load x-app-sdk module: $e';
      print('❌ XAppSDKService: $_lastError');
      return null;
    }
  }

  bool _hasProperty(dynamic target, String name) {
    try {
      final value = getProperty(target, name);
      return value != null;
    } catch (_) {
      return false;
    }
  }
}
