import 'package:json_annotation/json_annotation.dart';
import 'dashboard_stats.dart';

part 'websocket_message.g.dart';

@JsonSerializable()
class WebSocketMessage {
  final WebSocketMessageType type;
  final Map<String, dynamic>? data;
  final int timestamp;

  WebSocketMessage({required this.type, this.data, required this.timestamp});

  factory WebSocketMessage.fromJson(Map<String, dynamic> json) => _$WebSocketMessageFromJson(json);

  Map<String, dynamic> toJson() => _$WebSocketMessageToJson(this);

  // Factory constructors for specific message types
  factory WebSocketMessage.statsUpdate(DashboardStats stats) {
    return WebSocketMessage(
      type: WebSocketMessageType.statsUpdate,
      data: stats.toJson(),
      timestamp: DateTime.now().millisecondsSinceEpoch,
    );
  }

  factory WebSocketMessage.xpBreakdownUpdate(Map<String, int> breakdown) {
    return WebSocketMessage(
      type: WebSocketMessageType.xpBreakdownUpdate,
      data: breakdown,
      timestamp: DateTime.now().millisecondsSinceEpoch,
    );
  }

  factory WebSocketMessage.achievementUnlocked(Map<String, dynamic> achievement) {
    return WebSocketMessage(
      type: WebSocketMessageType.achievementUnlocked,
      data: achievement,
      timestamp: DateTime.now().millisecondsSinceEpoch,
    );
  }

  factory WebSocketMessage.levelUp(int newLevel) {
    return WebSocketMessage(
      type: WebSocketMessageType.levelUp,
      data: {'level': newLevel},
      timestamp: DateTime.now().millisecondsSinceEpoch,
    );
  }

  factory WebSocketMessage.focusSessionComplete(Map<String, dynamic> session) {
    return WebSocketMessage(
      type: WebSocketMessageType.focusSessionComplete,
      data: session,
      timestamp: DateTime.now().millisecondsSinceEpoch,
    );
  }

  factory WebSocketMessage.ping() {
    return WebSocketMessage(type: WebSocketMessageType.ping, timestamp: DateTime.now().millisecondsSinceEpoch);
  }

  factory WebSocketMessage.pong() {
    return WebSocketMessage(type: WebSocketMessageType.pong, timestamp: DateTime.now().millisecondsSinceEpoch);
  }
}

enum WebSocketMessageType {
  statsUpdate('stats_update'),
  xpBreakdownUpdate('xp_breakdown_update'),
  achievementUnlocked('achievement_unlocked'),
  levelUp('level_up'),
  focusSessionComplete('focus_session_complete'),
  ping('ping'),
  pong('pong');

  const WebSocketMessageType(this.value);
  final String value;
}
