import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:equatable/equatable.dart';

// --- State ---
class AvailabilityState extends Equatable {
  final DateTime currentWeekStart;
  final DateTime selectedDate;
  final Map<String, bool> dayAvailability;
  final Map<String, Map<String, bool>> timeSlotAvailability;

  const AvailabilityState({
    required this.currentWeekStart,
    required this.selectedDate,
    required this.dayAvailability,
    required this.timeSlotAvailability,
  });

  AvailabilityState copyWith({
    DateTime? currentWeekStart,
    DateTime? selectedDate,
    Map<String, bool>? dayAvailability,
    Map<String, Map<String, bool>>? timeSlotAvailability,
  }) {
    return AvailabilityState(
      currentWeekStart: currentWeekStart ?? this.currentWeekStart,
      selectedDate: selectedDate ?? this.selectedDate,
      dayAvailability: dayAvailability ?? this.dayAvailability,
      timeSlotAvailability: timeSlotAvailability ?? this.timeSlotAvailability,
    );
  }

  @override
  List<Object> get props => [
        currentWeekStart,
        selectedDate,
        dayAvailability,
        timeSlotAvailability,
      ];
}

// --- Cubit ---
class AvailabilityCubit extends Cubit<AvailabilityState> {
  AvailabilityCubit()
      : super(AvailabilityState(
          currentWeekStart: _getStartOfWeek(DateTime.now()),
          selectedDate: DateTime.now(),
          dayAvailability: {
            'monday': true,
            'tuesday': true,
            'wednesday': true,
            'thursday': true,
            'friday': true,
            'saturday': false,
            'sunday': false,
          },
          timeSlotAvailability: {
            'monday': {'morning': true, 'afternoon': true, 'evening': true},
            'tuesday': {'morning': true, 'afternoon': true, 'evening': true},
            'wednesday': {'morning': true, 'afternoon': true, 'evening': true},
            'thursday': {'morning': true, 'afternoon': true, 'evening': true},
            'friday': {'morning': true, 'afternoon': true, 'evening': true},
            'saturday': {'morning': false, 'afternoon': false, 'evening': false},
            'sunday': {'morning': false, 'afternoon': false, 'evening': false},
          },
        ));

  static DateTime _getStartOfWeek(DateTime date) {
    final diff = date.weekday - 1; // Mon=1 -> 0
    final start = date.subtract(Duration(days: diff));
    return DateTime(start.year, start.month, start.day);
  }

  void selectDate(DateTime date) {
    emit(state.copyWith(selectedDate: date));
  }

  void navigateWeek(int weeks) {
    emit(state.copyWith(
      currentWeekStart: state.currentWeekStart.add(Duration(days: weeks * 7)),
    ));
  }

  void toggleDay(String dayKey) {
    final currentObj = Map<String, bool>.from(state.dayAvailability);
    currentObj[dayKey] = !(currentObj[dayKey] ?? false);
    emit(state.copyWith(dayAvailability: currentObj));
  }

  void toggleSlot(String dayKey, String slotId) {
    final allSlots = Map<String, Map<String, bool>>.from(state.timeSlotAvailability);
    final daySlots = Map<String, bool>.from(allSlots[dayKey] ?? {});
    
    // Default to true if missing, so we toggle to false
    final currentVal = daySlots[slotId] ?? true;
    daySlots[slotId] = !currentVal;
    
    allSlots[dayKey] = daySlots;
    emit(state.copyWith(timeSlotAvailability: allSlots));
  }

  void quickSet(String type) {
    final newAvailability = <String, bool>{};
    final days = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'];

    switch (type) {
      case 'all':
        for (var d in days) {
          newAvailability[d] = true;
        }
        break;
      case 'weekdays':
        for (var d in days) {
          newAvailability[d] = (d != 'saturday' && d != 'sunday');
        }
        break;
      case 'weekends':
        for (var d in days) {
          newAvailability[d] = (d == 'saturday' || d == 'sunday');
        }
        break;
      case 'clear':
        for (var d in days) {
          newAvailability[d] = false;
        }
        break;
    }
    
    emit(state.copyWith(dayAvailability: newAvailability));
  }
}
