import 'package:freezed_annotation/freezed_annotation.dart';

import '../../../../../api/marianumconnect/queries/timetable_get_holidays/timetable_get_holidays_response.dart';
import '../../../../../api/marianumconnect/queries/timetable_get_rooms/timetable_get_rooms_response.dart';
import '../../../../../api/marianumconnect/queries/timetable_get_schoolyear/timetable_get_schoolyear_response.dart';
import '../../../../../api/marianumconnect/queries/timetable_get_subjects/timetable_get_subjects_response.dart';
import '../../../../../api/marianumconnect/queries/timetable_get_timegrid/timetable_get_timegrid_response.dart';
import '../../../../../api/marianumconnect/queries/timetable_get_week/timetable_get_week_response.dart';
import '../../../../../api/mhsl/custom_timetable_event/get/get_custom_timetable_event_response.dart';

part 'timetable_state.freezed.dart';
part 'timetable_state.g.dart';

@freezed
abstract class TimetableState with _$TimetableState {
  const TimetableState._();

  const factory TimetableState({
    @Default(<String, TimetableGetWeekResponse>{})
    Map<String, TimetableGetWeekResponse> weekCache,
    TimetableGetRoomsResponse? rooms,
    TimetableGetSubjectsResponse? subjects,
    TimetableGetHolidaysResponse? schoolHolidays,
    TimetableGetSchoolyearResponse? schoolyear,
    TimetableGetTimegridResponse? timegrid,
    GetCustomTimetableEventResponse? customEvents,
    required DateTime startDate,
    required DateTime endDate,
    @Default(0) int dataVersion,
    // Boundaries learned from past server denials. A week is permitted when its
    // start is on/before `accessibleEndDate` and its end on/after
    // `accessibleStartDate`. Null = that bound not discovered yet.
    DateTime? accessibleStartDate,
    DateTime? accessibleEndDate,
  }) = _TimetableState;

  factory TimetableState.fromJson(Map<String, Object?> json) =>
      _$TimetableStateFromJson(json);

  Iterable<McTimetableEntry> getAllKnownLessons() =>
      weekCache.values.expand((response) => response.entries);

  bool get hasReferenceData =>
      rooms != null &&
      subjects != null &&
      schoolHolidays != null &&
      customEvents != null;
}
