import 'package:json_annotation/json_annotation.dart';

import '../../../api_response.dart';

part 'timetable_get_timegrid_response.g.dart';

/// Java DayOfWeek serializes as the enum name (MONDAY, TUESDAY, …).
enum McDayOfWeek {
  monday,
  tuesday,
  wednesday,
  thursday,
  friday,
  saturday,
  sunday,
}

McDayOfWeek _dayFromJson(String raw) {
  switch (raw.toUpperCase()) {
    case 'MONDAY':
      return McDayOfWeek.monday;
    case 'TUESDAY':
      return McDayOfWeek.tuesday;
    case 'WEDNESDAY':
      return McDayOfWeek.wednesday;
    case 'THURSDAY':
      return McDayOfWeek.thursday;
    case 'FRIDAY':
      return McDayOfWeek.friday;
    case 'SATURDAY':
      return McDayOfWeek.saturday;
    case 'SUNDAY':
      return McDayOfWeek.sunday;
    default:
      // Unknown values keep the timetable rendering from crashing; the UI
      // falls back to its hardcoded grid in that case.
      return McDayOfWeek.monday;
  }
}

String _dayToJson(McDayOfWeek d) {
  switch (d) {
    case McDayOfWeek.monday:
      return 'MONDAY';
    case McDayOfWeek.tuesday:
      return 'TUESDAY';
    case McDayOfWeek.wednesday:
      return 'WEDNESDAY';
    case McDayOfWeek.thursday:
      return 'THURSDAY';
    case McDayOfWeek.friday:
      return 'FRIDAY';
    case McDayOfWeek.saturday:
      return 'SATURDAY';
    case McDayOfWeek.sunday:
      return 'SUNDAY';
  }
}

@JsonSerializable(explicitToJson: true)
class McTimegridUnit {
  @JsonKey(fromJson: _dayFromJson, toJson: _dayToJson)
  final McDayOfWeek dayOfWeek;

  final String label;

  @JsonKey(fromJson: _timeFromJson, toJson: _timeToJson)
  final DateTime startTime;

  @JsonKey(fromJson: _timeFromJson, toJson: _timeToJson)
  final DateTime endTime;

  McTimegridUnit({
    required this.dayOfWeek,
    required this.label,
    required this.startTime,
    required this.endTime,
  });

  factory McTimegridUnit.fromJson(Map<String, dynamic> json) =>
      _$McTimegridUnitFromJson(json);
  Map<String, dynamic> toJson() => _$McTimegridUnitToJson(this);

  static DateTime _timeFromJson(String raw) => DateTime.parse('1970-01-01T$raw');
  static String _timeToJson(DateTime t) =>
      '${t.hour.toString().padLeft(2, '0')}:${t.minute.toString().padLeft(2, '0')}:${t.second.toString().padLeft(2, '0')}';
}

@JsonSerializable(explicitToJson: true)
class TimetableGetTimegridResponse extends ApiResponse {
  final List<McTimegridUnit> result;

  TimetableGetTimegridResponse({required this.result});

  factory TimetableGetTimegridResponse.fromJson(Map<String, dynamic> json) =>
      _$TimetableGetTimegridResponseFromJson(json);
  Map<String, dynamic> toJson() => _$TimetableGetTimegridResponseToJson(this);
}
