enum AdminAiTraceSource { receipt, flyer }

enum AdminAiTraceStatus { success, warning, error }

extension AdminAiTraceSourceX on AdminAiTraceSource {
  String get apiValue =>
      this == AdminAiTraceSource.receipt ? 'receipt' : 'flyer';

  String get label => this == AdminAiTraceSource.receipt ? 'Kvitto' : 'Flyer';

  static AdminAiTraceSource fromApi(String? value) {
    if (value == 'receipt') return AdminAiTraceSource.receipt;
    return AdminAiTraceSource.flyer;
  }
}

extension AdminAiTraceStatusX on AdminAiTraceStatus {
  String get label => switch (this) {
        AdminAiTraceStatus.success => 'OK',
        AdminAiTraceStatus.warning => 'Varning',
        AdminAiTraceStatus.error => 'Fel',
      };

  static AdminAiTraceStatus fromApi(String? value) {
    return switch (value) {
      'error' => AdminAiTraceStatus.error,
      'warning' => AdminAiTraceStatus.warning,
      _ => AdminAiTraceStatus.success,
    };
  }
}

class AdminAiTraceListItem {
  final String id;
  final AdminAiTraceSource source;
  final AdminAiTraceStatus status;
  final DateTime createdAt;
  final int userId;
  final String userLabel;
  final int? sessionId;
  final String? fileName;
  final String? model;
  final int? durationMs;
  final int warningsCount;
  final bool hasPrompt;
  final bool hasOutput;
  final String? error;

  const AdminAiTraceListItem({
    required this.id,
    required this.source,
    required this.status,
    required this.createdAt,
    required this.userId,
    required this.userLabel,
    required this.sessionId,
    required this.fileName,
    required this.model,
    required this.durationMs,
    required this.warningsCount,
    required this.hasPrompt,
    required this.hasOutput,
    required this.error,
  });

  factory AdminAiTraceListItem.fromJson(Map<String, dynamic> json) {
    return AdminAiTraceListItem(
      id: (json['id'] ?? '').toString(),
      source: AdminAiTraceSourceX.fromApi(json['source']?.toString()),
      status: AdminAiTraceStatusX.fromApi(json['status']?.toString()),
      createdAt: DateTime.tryParse((json['createdAt'] ?? '').toString()) ??
          DateTime.fromMillisecondsSinceEpoch(0),
      userId: (json['userId'] as num?)?.toInt() ?? 0,
      userLabel: (json['userLabel'] ?? '').toString(),
      sessionId: (json['sessionId'] as num?)?.toInt(),
      fileName: json['fileName']?.toString(),
      model: json['model']?.toString(),
      durationMs: (json['durationMs'] as num?)?.toInt(),
      warningsCount: (json['warningsCount'] as num?)?.toInt() ?? 0,
      hasPrompt: json['hasPrompt'] == true,
      hasOutput: json['hasOutput'] == true,
      error: json['error']?.toString(),
    );
  }
}

class AdminAiTraceListResponse {
  final List<AdminAiTraceListItem> items;
  final String? nextCursor;

  const AdminAiTraceListResponse({
    required this.items,
    required this.nextCursor,
  });

  factory AdminAiTraceListResponse.fromJson(Map<String, dynamic> json) {
    final rawItems = (json['items'] as List<dynamic>?) ?? const [];
    return AdminAiTraceListResponse(
      items: rawItems
          .whereType<Map>()
          .map((entry) =>
              AdminAiTraceListItem.fromJson(Map<String, dynamic>.from(entry)))
          .toList(),
      nextCursor: json['nextCursor']?.toString(),
    );
  }
}
