import 'dart:developer';

import 'package:intl/intl.dart';
import 'package:marianum_mobile/api/apiResponse.dart';
import 'package:marianum_mobile/api/webuntis/queries/getHolidays/getHolidaysCache.dart';
import 'package:marianum_mobile/api/webuntis/queries/getHolidays/getHolidaysResponse.dart';
import 'package:marianum_mobile/api/webuntis/queries/getRooms/getRoomsCache.dart';
import 'package:marianum_mobile/api/webuntis/queries/getRooms/getRoomsResponse.dart';
import 'package:marianum_mobile/api/webuntis/queries/getSubjects/getSubjectsCache.dart';
import 'package:marianum_mobile/api/webuntis/queries/getSubjects/getSubjectsResponse.dart';
import 'package:marianum_mobile/data/dataHolder.dart';

import '../../api/webuntis/queries/getTimetable/getTimetableCache.dart';
import '../../api/webuntis/queries/getTimetable/getTimetableResponse.dart';

extension DateTimeExtension on DateTime {
  DateTime next(int day) {
    return add(
      Duration(
        days: (day - weekday) % DateTime.daysPerWeek,
      ),
    );
  }
}

class TimetableProps extends DataHolder {
  var _queryWeek = DateTime.now();

  late DateTime startDate = getDate(_queryWeek.subtract(Duration(days: _queryWeek.weekday - 1)));
  late DateTime endDate = getDate(_queryWeek.add(Duration(days: DateTime.daysPerWeek - _queryWeek.weekday)));

  GetTimetableResponse? _getTimetableResponse;
  GetTimetableResponse get getTimetableResponse => _getTimetableResponse!;

  GetRoomsResponse? _getRoomsResponse;
  GetRoomsResponse get getRoomsResponse => _getRoomsResponse!;

  GetSubjectsResponse? _getSubjectsResponse;
  GetSubjectsResponse get getSubjectsResponse => _getSubjectsResponse!;

  GetHolidaysResponse? _getHolidaysResponse;
  GetHolidaysResponse get getHolidaysResponse => _getHolidaysResponse!;


  TimetableProps() {
    //nearest();

  }

  @override
  List<ApiResponse?> properties() {
    return [_getTimetableResponse, _getRoomsResponse, _getSubjectsResponse, _getHolidaysResponse];
  }

  @override
  void run() {
    GetTimetableCache(
        startdate: int.parse(DateFormat("yyyyMMdd").format(startDate)),
        enddate: int.parse(DateFormat("yyyyMMdd").format(endDate)),
        onUpdate: (GetTimetableResponse data) => {
          _getTimetableResponse = data,
          notifyListeners(),
        }
    );

    GetRoomsCache(
        onUpdate: (GetRoomsResponse data) => {
          _getRoomsResponse = data,
          notifyListeners(),
        }
    );

    GetSubjectsCache(
        onUpdate: (GetSubjectsResponse data) => {
          _getSubjectsResponse = data,
          notifyListeners(),
        }
    );

    GetHolidaysCache(
      onUpdate: (GetHolidaysResponse data) => {
        _getHolidaysResponse = data,
        notifyListeners(),
      }
    );
  }

  void nearest() {
    _queryWeek = _queryWeek = DateTime.now();
    updateWeek();
  }

  void switchWeek({previous = false}) {
    if(previous) {
      _queryWeek = _queryWeek.subtract(const Duration(days: 7));
    } else {
      _queryWeek = _queryWeek.add(const Duration(days: 7));
    }
    updateWeek();
  }

  DateTime getDate(DateTime d) => DateTime(d.year, d.month, d.day);

  bool isWeekend(DateTime queryDate) {
    return queryDate.weekday == DateTime.saturday || queryDate.weekday == DateTime.sunday;
  }

  void updateWeek() {
    startDate = getDate(_queryWeek.subtract(Duration(days: _queryWeek.weekday - 1)));
    endDate = getDate(_queryWeek.add(Duration(days: DateTime.daysPerWeek - _queryWeek.weekday)));
    run();
  }
}