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

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

/// Concrete locked-time occurrence for one calendar day.
///
/// [LockedBlock] is a rule; [LockedBlockOccurrence] is the actual result on a
/// specific date. The scheduler only needs occurrences/time intervals, while UI
/// can use ids and visibility flags to explain where the blocked time came from.
class LockedBlockOccurrence {
  /// Creates a `LockedBlockOccurrence` 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.
  const LockedBlockOccurrence({
    required this.name,
    required this.interval,
    required this.hiddenByDefault,
    this.lockedBlockId,
    this.overrideId,
    this.projectId,
  });

  /// Display/debug label for this occurrence.
  final String name;

  /// Concrete start/end on one calendar date.
  final TimeInterval interval;

  /// Visibility hint for UI; does not affect scheduling.
  final bool hiddenByDefault;

  /// Source recurring/one-off block id, when this came from a base block.
  final String? lockedBlockId;

  /// Source override id, when this was replaced or added for one date.
  final String? overrideId;

  /// Optional project/category association for UI colors or reports.
  final String? projectId;

  /// Scheduler-facing interval. Visibility only affects future UI overlays.
  ///
  /// A fresh [TimeInterval] is returned with [name] as the label so scheduling
  /// notices/debugging can identify the blocked source without depending on the
  /// richer occurrence object.
  TimeInterval get schedulingInterval {
    return TimeInterval(
      start: interval.start,
      end: interval.end,
      label: name,
    );
  }
}
