import 'package:flutter/material.dart'; import '../../../../api/webuntis/queries/get_timegrid_units/get_timegrid_units_response.dart'; import '../../../../state/app/modules/timetable/bloc/timetable_state.dart'; class LessonPeriod { final String name; final TimeOfDay start; final TimeOfDay end; final bool isBreak; const LessonPeriod({ required this.name, required this.start, required this.end, this.isBreak = false, }); Duration get duration => Duration( minutes: (end.hour * 60 + end.minute) - (start.hour * 60 + start.minute), ); int get _startMinutes => start.hour * 60 + start.minute; } class LessonPeriodSchedule { final List periods; const LessonPeriodSchedule(this.periods); static LessonPeriodSchedule? fromApi(GetTimegridUnitsResponse response) { final canonical = response.result.firstWhere( (d) => d.day == 1, orElse: () => response.result.isNotEmpty ? response.result.first : GetTimegridUnitsResponseDay(0, []), ); if (canonical.timeUnits.isEmpty) return null; final periods = canonical.timeUnits .map( (u) => LessonPeriod( name: u.name, start: _fromHHMM(u.startTime), end: _fromHHMM(u.endTime), ), ) .toList() ..sort((a, b) => a._startMinutes.compareTo(b._startMinutes)); return LessonPeriodSchedule(periods); } static LessonPeriodSchedule fallback() => const LessonPeriodSchedule([ LessonPeriod( name: '0', start: TimeOfDay(hour: 7, minute: 10), end: TimeOfDay(hour: 7, minute: 53), ), LessonPeriod( name: '1', start: TimeOfDay(hour: 7, minute: 55), end: TimeOfDay(hour: 8, minute: 40), ), LessonPeriod( name: '2', start: TimeOfDay(hour: 8, minute: 40), end: TimeOfDay(hour: 9, minute: 25), ), LessonPeriod( name: '3', start: TimeOfDay(hour: 9, minute: 30), end: TimeOfDay(hour: 10, minute: 15), ), LessonPeriod( name: '4', start: TimeOfDay(hour: 10, minute: 35), end: TimeOfDay(hour: 11, minute: 20), ), LessonPeriod( name: '5', start: TimeOfDay(hour: 11, minute: 25), end: TimeOfDay(hour: 12, minute: 10), ), LessonPeriod( name: '6', start: TimeOfDay(hour: 12, minute: 15), end: TimeOfDay(hour: 13, minute: 0), ), LessonPeriod( name: '7', start: TimeOfDay(hour: 13, minute: 5), end: TimeOfDay(hour: 13, minute: 50), ), LessonPeriod( name: '8', start: TimeOfDay(hour: 14, minute: 5), end: TimeOfDay(hour: 14, minute: 50), ), LessonPeriod( name: '9', start: TimeOfDay(hour: 14, minute: 50), end: TimeOfDay(hour: 15, minute: 35), ), LessonPeriod( name: '10', start: TimeOfDay(hour: 15, minute: 40), end: TimeOfDay(hour: 16, minute: 25), ), LessonPeriod( name: '11', start: TimeOfDay(hour: 16, minute: 25), end: TimeOfDay(hour: 17, minute: 10), ), ]); static LessonPeriodSchedule fromState(TimetableState state) { final fromApi = state.timegrid != null ? LessonPeriodSchedule.fromApi(state.timegrid!) : null; return (fromApi ?? fallback()).withSyntheticBreaks(); } LessonPeriodSchedule withSyntheticBreaks() { final result = []; for (var i = 0; i < periods.length; i++) { final current = periods[i]; result.add(current); if (i + 1 >= periods.length) continue; final next = periods[i + 1]; final gapMinutes = next._startMinutes - (current.end.hour * 60 + current.end.minute); if (gapMinutes >= 10) { result.add( LessonPeriod( name: 'Pause', start: current.end, end: next.start, isBreak: true, ), ); } } return LessonPeriodSchedule(result); } static TimeOfDay _fromHHMM(int hhmm) => TimeOfDay(hour: hhmm ~/ 100, minute: hhmm % 100); }