import 'package:equatable/equatable.dart';

/// 事件级别
enum EventLevel {
  debug,
  info,
  warning,
  error,
  fatal,
}

/// 事件类型
enum EventType {
  /// 页面访问
  pageView,

  /// 用户行为
  userAction,

  /// API请求
  apiCall,

  /// 性能指标
  performance,

  /// 错误异常
  error,

  /// 崩溃
  crash,

  /// 会话事件 (app_session_start, app_session_end)
  session,

  /// 在线状态 (心跳相关)
  presence,
}

/// 遥测事件模型
class TelemetryEvent extends Equatable {
  /// 事件ID (UUID)
  final String eventId;

  /// 事件类型
  final EventType type;

  /// 事件级别
  final EventLevel level;

  /// 事件名称: 'app_session_start', 'open_planting_page'
  final String name;

  /// 事件参数
  final Map<String, dynamic>? properties;

  /// 事件时间戳
  final DateTime timestamp;

  /// 用户ID（登录后设置）
  final String? userId;

  /// 会话ID
  final String? sessionId;

  /// 安装ID（设备唯一标识）
  final String installId;

  /// 关联设备信息ID
  final String deviceContextId;

  const TelemetryEvent({
    required this.eventId,
    required this.type,
    required this.level,
    required this.name,
    this.properties,
    required this.timestamp,
    this.userId,
    this.sessionId,
    required this.installId,
    required this.deviceContextId,
  });

  factory TelemetryEvent.fromJson(Map<String, dynamic> json) {
    return TelemetryEvent(
      eventId: json['eventId'] as String,
      type: EventType.values.firstWhere(
        (e) => e.name == json['type'],
        orElse: () => EventType.userAction,
      ),
      level: EventLevel.values.firstWhere(
        (e) => e.name == json['level'],
        orElse: () => EventLevel.info,
      ),
      name: json['name'] as String,
      properties: json['properties'] as Map<String, dynamic>?,
      timestamp: DateTime.parse(json['timestamp'] as String),
      userId: json['userId'] as String?,
      sessionId: json['sessionId'] as String?,
      installId: json['installId'] as String,
      deviceContextId: json['deviceContextId'] as String,
    );
  }

  /// 转换为本地存储 JSON 格式
  Map<String, dynamic> toJson() {
    return {
      'eventId': eventId,
      'type': type.name,
      'level': level.name,
      'name': name,
      'properties': properties,
      'timestamp': timestamp.toIso8601String(),
      'userId': userId,
      'sessionId': sessionId,
      'installId': installId,
      'deviceContextId': deviceContextId,
    };
  }

  /// 转换为服务端 API 格式（Amplitude 风格：设备字段为顶层独立列，方便服务端索引）
  /// 顶层字段: eventName, userId, installId, clientTs, deviceBrand, deviceModel,
  ///           deviceOs, appVersion, locale
  /// properties: 仅保留事件专属数据（页面名、金额等）
  Map<String, dynamic> toServerJson() {
    // 从 properties 中提取设备字段（提升为顶层），剩余为事件专属数据
    final props = Map<String, dynamic>.from(properties ?? {});
    final deviceBrand = props.remove('device_brand');
    final deviceModel = props.remove('device_model');
    final deviceOs = props.remove('device_os');
    final appVersion = props.remove('app_version');
    final locale = props.remove('locale');

    return {
      'eventName': name,
      'userId': userId,
      'installId': installId,
      'clientTs': timestamp.millisecondsSinceEpoch ~/ 1000,
      'deviceBrand': deviceBrand,
      'deviceModel': deviceModel,
      'deviceOs': deviceOs,
      'appVersion': appVersion,
      'locale': locale,
      'properties': {
        ...props,
        'eventId': eventId,
        'type': type.name,
        'level': level.name,
        'sessionId': sessionId,
        'deviceContextId': deviceContextId,
      },
    };
  }

  TelemetryEvent copyWith({
    String? eventId,
    EventType? type,
    EventLevel? level,
    String? name,
    Map<String, dynamic>? properties,
    DateTime? timestamp,
    String? userId,
    String? sessionId,
    String? installId,
    String? deviceContextId,
  }) {
    return TelemetryEvent(
      eventId: eventId ?? this.eventId,
      type: type ?? this.type,
      level: level ?? this.level,
      name: name ?? this.name,
      properties: properties ?? this.properties,
      timestamp: timestamp ?? this.timestamp,
      userId: userId ?? this.userId,
      sessionId: sessionId ?? this.sessionId,
      installId: installId ?? this.installId,
      deviceContextId: deviceContextId ?? this.deviceContextId,
    );
  }

  @override
  List<Object?> get props => [
        eventId,
        type,
        level,
        name,
        properties,
        timestamp,
        userId,
        sessionId,
        installId,
        deviceContextId,
      ];
}
