class SetPartial {
  const SetPartial({
    required this.set,
    required this.home,
    required this.away,
  });

  final int set;
  final int home;
  final int away;

  factory SetPartial.fromJson(Map<String, dynamic> json) {
    return SetPartial(
      set: json['set'] as int? ?? 1,
      home: json['home'] as int? ?? 0,
      away: json['away'] as int? ?? 0,
    );
  }

  Map<String, dynamic> toJson() => {
        'set': set,
        'home': home,
        'away': away,
      };
}

class ScoreState {
  const ScoreState({
    this.homeSets = 0,
    this.awaySets = 0,
    this.homePoints = 0,
    this.awayPoints = 0,
    this.currentSet = 1,
    this.setPartials = const [],
    this.timeoutHome = false,
    this.timeoutAway = false,
  });

  final int homeSets;
  final int awaySets;
  final int homePoints;
  final int awayPoints;
  final int currentSet;
  final List<SetPartial> setPartials;
  final bool timeoutHome;
  final bool timeoutAway;

  factory ScoreState.fromJson(Map<String, dynamic> json) {
    final rawPartials = json['set_partials'];
    final partials = rawPartials is List
        ? rawPartials
            .whereType<Map>()
            .map((e) => SetPartial.fromJson(Map<String, dynamic>.from(e)))
            .toList()
        : <SetPartial>[];

    return ScoreState(
      homeSets: json['home_sets'] as int? ?? 0,
      awaySets: json['away_sets'] as int? ?? 0,
      homePoints: json['home_points'] as int? ?? 0,
      awayPoints: json['away_points'] as int? ?? 0,
      currentSet: json['current_set'] as int? ?? 1,
      setPartials: partials,
      timeoutHome: json['timeout_home'] as bool? ?? false,
      timeoutAway: json['timeout_away'] as bool? ?? false,
    );
  }

  Map<String, dynamic> toCablePayload() => {
        'type': 'score_update',
        'home_sets': homeSets,
        'away_sets': awaySets,
        'home_points': homePoints,
        'away_points': awayPoints,
        'current_set': currentSet,
        'set_partials': setPartials.map((p) => p.toJson()).toList(),
      };

  ScoreState copyWith({
    int? homeSets,
    int? awaySets,
    int? homePoints,
    int? awayPoints,
    int? currentSet,
    List<SetPartial>? setPartials,
    bool? timeoutHome,
    bool? timeoutAway,
  }) {
    return ScoreState(
      homeSets: homeSets ?? this.homeSets,
      awaySets: awaySets ?? this.awaySets,
      homePoints: homePoints ?? this.homePoints,
      awayPoints: awayPoints ?? this.awayPoints,
      currentSet: currentSet ?? this.currentSet,
      setPartials: setPartials ?? this.setPartials,
      timeoutHome: timeoutHome ?? this.timeoutHome,
      timeoutAway: timeoutAway ?? this.timeoutAway,
    );
  }
}
