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

part of '../../repositories.dart';

/// Snapshot of one scheduling operation or persisted planning state.
class SchedulingStateSnapshot {
  /// Creates a `SchedulingStateSnapshot` 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.
  SchedulingStateSnapshot({
    required this.id,
    required this.capturedAt,
    required this.window,
    required List<Task> tasks,
    List<TimeInterval> lockedIntervals = const <TimeInterval>[],
    List<TimeInterval> requiredVisibleIntervals = const <TimeInterval>[],
    List<SchedulingNotice> notices = const <SchedulingNotice>[],
    List<SchedulingChange> changes = const <SchedulingChange>[],
    List<SchedulingOverlap> overlaps = const <SchedulingOverlap>[],
    this.operationName,
  })  : tasks = List<Task>.unmodifiable(tasks),
        lockedIntervals = List<TimeInterval>.unmodifiable(lockedIntervals),
        requiredVisibleIntervals =
            List<TimeInterval>.unmodifiable(requiredVisibleIntervals),
        notices = List<SchedulingNotice>.unmodifiable(notices),
        changes = List<SchedulingChange>.unmodifiable(changes),
        overlaps = List<SchedulingOverlap>.unmodifiable(overlaps);

  /// Stable snapshot id.
  final String id;

  /// Time this snapshot was created.
  final DateTime capturedAt;

  /// Planning window represented by the snapshot.
  final SchedulingWindow window;

  /// Task documents visible to the operation.
  final List<Task> tasks;

  /// Locked intervals supplied to the scheduler.
  final List<TimeInterval> lockedIntervals;

  /// Extra visible required intervals supplied to the scheduler.
  final List<TimeInterval> requiredVisibleIntervals;

  /// Human-readable scheduling notices.
  final List<SchedulingNotice> notices;

  /// Machine-readable task movements.
  final List<SchedulingChange> changes;

  /// Analysis-only overlap findings.
  final List<SchedulingOverlap> overlaps;

  /// Optional operation label, such as `push` or `rollover`.
  final String? operationName;

  /// Rebuild scheduler input from the persisted state shape.
  SchedulingInput get input {
    return SchedulingInput(
      tasks: List<Task>.unmodifiable(tasks),
      window: window,
      lockedIntervals: List<TimeInterval>.unmodifiable(lockedIntervals),
      requiredVisibleIntervals:
          List<TimeInterval>.unmodifiable(requiredVisibleIntervals),
    );
  }

  /// Rebuild scheduler result details from the persisted state shape.
  SchedulingResult get result {
    return SchedulingResult(
      tasks: List<Task>.unmodifiable(tasks),
      notices: List<SchedulingNotice>.unmodifiable(notices),
      changes: List<SchedulingChange>.unmodifiable(changes),
      overlaps: List<SchedulingOverlap>.unmodifiable(overlaps),
    );
  }
}
