import 'dart:developer' as developer;

import 'package:facebook_app_events/facebook_app_events.dart';
import 'package:flutter/foundation.dart';

class FacebookInitConfig {
  final String applicationId;
  final String? secret;

  const FacebookInitConfig({required this.applicationId, this.secret});

  static FacebookInitConfig? fromRemote(dynamic source) {
    if (source is! Map) return null;

    final applicationId = source['m']?.toString().trim();
    if (applicationId == null || applicationId.length < 5) return null;

    return FacebookInitConfig(
      applicationId: applicationId,
      secret: source['n']?.toString().trim(),
    );
  }
}

class FacebookService {
  FacebookService._();

  static final FacebookService instance = FacebookService._();

  final FacebookAppEvents _events = FacebookAppEvents();
  bool _inited = false;
  String? _applicationId;

  bool get inited => _inited;

  Future<void> init(FacebookInitConfig config) async {
    if (_inited && _applicationId == config.applicationId) {
      developer.log('[Facebook] already inited', name: 'Facebook');
      return;
    }

    try {
      await _events.setAutoLogAppEventsEnabled(false);
      await _events.setAdvertiserTracking(enabled: true, collectId: true);
      await _events.activateApp(applicationId: config.applicationId);

      _applicationId = config.applicationId;
      _inited = true;
      developer.log(
        '[Facebook] inited appId=${config.applicationId}',
        name: 'Facebook',
      );
    } catch (e, st) {
      developer.log(
        '[Facebook] init error: $e',
        name: 'Facebook',
        stackTrace: st,
      );
    }
  }

  Future<void> initFromRemote(dynamic source) async {
    final config = FacebookInitConfig.fromRemote(source);
    if (config == null) return;
    await init(config);
  }

  Future<void> initWithParams(Map<String, dynamic> params) async {
    await initFromRemote(params);
  }

  Future<void> trackEvent(
    String eventName, [
    Map<String, dynamic>? params,
  ]) async {
    if (!_inited || eventName.isEmpty) return;

    try {
      await _events.logEvent(name: eventName, parameters: params);
    } catch (e) {
      debugPrint('[Facebook] track event failed: $e');
    }
  }
}
