import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; import '../../../state/app/modules/timetable/bloc/timetable_state.dart'; import '../queries/get_rooms/get_rooms_response.dart'; import '../queries/get_subjects/get_subjects_response.dart'; /// Resolves Webuntis IDs (subject, room) against the cached `TimetableState`. /// When a record is missing the resolver returns a placeholder fallback /// instead of `null` so call sites stay branch-free. class LessonResolver { static GetSubjectsResponseObject resolveSubject( TimetableState state, int? id, ) { final fallback = GetSubjectsResponseObject(0, '?', 'Unbekannt', '?', true); if (id == null) return fallback; return state.subjects?.result.firstWhereOrNull((s) => s.id == id) ?? fallback; } static GetRoomsResponseObject resolveRoom(TimetableState state, int? id) { final fallback = GetRoomsResponseObject(0, '?', 'Unbekannt', true, ''); if (id == null) return fallback; return state.rooms?.result.firstWhereOrNull((r) => r.id == id) ?? fallback; } } /// Pure formatting/labelling helpers for Webuntis lessons (status code → /// icon/label, "Name (Longname) · Extra" lines, subject prefix). No widgets, /// safe to unit-test. class LessonFormatter { static IconData iconForCode(String? code) { switch (code) { case 'cancelled': return Icons.event_busy_outlined; case 'irregular': return Icons.swap_horiz; default: return Icons.school_outlined; } } static String statusLabel(String? code) { switch (code) { case null: case '': return 'Regulär'; case 'cancelled': return 'Entfällt'; case 'irregular': return 'Geändert'; default: return code; } } static String codePrefix(String? code) { if (code == 'cancelled') return 'Entfällt: '; if (code == 'irregular') return 'Änderung: '; return code ?? ''; } /// Builds a single display line from the typical Webuntis triple of name, /// optional longname (rendered in parentheses if it differs from `name`), /// and optional extra info (joined with `·`). static String formatLine(String name, {String? longname, String? extra}) { final parts = [if (name.isNotEmpty) name else '?']; final ln = (longname ?? '').trim(); if (ln.isNotEmpty && ln != name) parts.add('($ln)'); final ex = (extra ?? '').trim(); if (ex.isNotEmpty) parts.add('· $ex'); return parts.join(' '); } }