// SPDX-FileCopyrightText: 2026 FocusFlow contributors
// SPDX-License-Identifier: AGPL-3.0-only

part of '../../locked_time.dart';

/// Recurrence rule for locked time.
///
/// The current starter implementation only supports weekly recurrence because
/// that covers the product's fixed work/stream/relationship blocks. This object
/// keeps recurrence separate from [LockedBlock] so monthly or custom recurrence
/// rules can be added later without changing the rest of the locked-time model.
class LockedBlockRecurrence {
  /// Creates a `LockedBlockRecurrence.weekly` instance with the values required by its invariants.
  /// Callers should pass already-normalized scheduler data because validation and defaulting belong at the model or service boundary, not in arbitrary UI code.
  LockedBlockRecurrence.weekly({
    required Set<LockedWeekday> weekdays,
  }) : weekdays = Set<LockedWeekday>.unmodifiable(weekdays) {
    if (weekdays.isEmpty) {
      throw DomainValidationException(
        code: DomainValidationCode.emptyRecurrence,
        invalidValue: weekdays,
        name: 'weekdays',
        message: 'Recurring locked blocks need at least one weekday.',
      );
    }
  }

  /// Weekdays when this recurrence should produce an occurrence.
  final Set<LockedWeekday> weekdays;

  /// Whether this recurrence applies to [date].
  bool occursOn(CivilDate date) {
    return weekdays.any((weekday) => weekday.dateTimeValue == date.weekday);
  }
}
