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

part of '../../document_mapping.dart';

/// Document mapping for [SchedulingStateSnapshot].
abstract final class SchedulingSnapshotDocumentMapping {
  /// Converts scheduler data for `toDocument` without changing the source object.
  /// Conversion helpers keep persistence and export shapes explicit so domain models do not depend on storage-specific details.
  static Map<String, Object?> toDocument(
    SchedulingStateSnapshot snapshot, {
    required String ownerId,
    int revision = 1,
    CivilDate? sourceDate,
    CivilDate? targetDate,
    DateTime? retentionExpiresAt,
    bool truncated = false,
  }) {
    return {
      ..._commonFields(
        id: snapshot.id,
        ownerId: ownerId,
        revision: revision,
        createdAt: snapshot.capturedAt,
        updatedAt: snapshot.capturedAt,
      ),
      SchedulingSnapshotDocumentFields.capturedAt:
          PersistenceDateTimeConvention.toStoredString(snapshot.capturedAt),
      SchedulingSnapshotDocumentFields.sourceDate:
          _civilDateToStored(sourceDate),
      SchedulingSnapshotDocumentFields.targetDate:
          _civilDateToStored(targetDate),
      SchedulingSnapshotDocumentFields.window:
          SchedulingWindowDocumentMapping.toDocument(snapshot.window),
      SchedulingSnapshotDocumentFields.tasks: snapshot.tasks
          .map(
            (task) => TaskDocumentMapping.toDocument(
              task,
              ownerId: ownerId,
            ),
          )
          .toList(growable: false),
      SchedulingSnapshotDocumentFields.lockedIntervals: snapshot.lockedIntervals
          .map(TimeIntervalDocumentMapping.toDocument)
          .toList(growable: false),
      SchedulingSnapshotDocumentFields.requiredVisibleIntervals: snapshot
          .requiredVisibleIntervals
          .map(TimeIntervalDocumentMapping.toDocument)
          .toList(growable: false),
      SchedulingSnapshotDocumentFields.notices: snapshot.notices
          .map(SchedulingNoticeDocumentMapping.toDocument)
          .toList(growable: false),
      SchedulingSnapshotDocumentFields.changes: snapshot.changes
          .map(SchedulingChangeDocumentMapping.toDocument)
          .toList(growable: false),
      SchedulingSnapshotDocumentFields.overlaps: snapshot.overlaps
          .map(SchedulingOverlapDocumentMapping.toDocument)
          .toList(growable: false),
      SchedulingSnapshotDocumentFields.operationName: snapshot.operationName,
      SchedulingSnapshotDocumentFields.retentionExpiresAt:
          _dateTimeToStored(retentionExpiresAt),
      SchedulingSnapshotDocumentFields.truncated: truncated,
    };
  }

  /// Converts scheduler data for `fromDocument` without changing the source object.
  /// Conversion helpers keep persistence and export shapes explicit so domain models do not depend on storage-specific details.
  static SchedulingStateSnapshot fromDocument(Map<String, Object?> document) {
    return _mapInvalidValues(() {
      _readCommon(document);
      return SchedulingStateSnapshot(
        id: _requiredString(document, SchedulingSnapshotDocumentFields.id),
        capturedAt: _requiredDateTime(
          document,
          SchedulingSnapshotDocumentFields.capturedAt,
        ),
        window: SchedulingWindowDocumentMapping.fromDocument(
          _requiredMap(document, SchedulingSnapshotDocumentFields.window),
        ),
        tasks: _mappedList(
          document,
          SchedulingSnapshotDocumentFields.tasks,
          TaskDocumentMapping.fromDocument,
        ),
        lockedIntervals: _mappedList(
          document,
          SchedulingSnapshotDocumentFields.lockedIntervals,
          TimeIntervalDocumentMapping.fromDocument,
        ),
        requiredVisibleIntervals: _mappedList(
          document,
          SchedulingSnapshotDocumentFields.requiredVisibleIntervals,
          TimeIntervalDocumentMapping.fromDocument,
        ),
        notices: _mappedList(
          document,
          SchedulingSnapshotDocumentFields.notices,
          SchedulingNoticeDocumentMapping.fromDocument,
        ),
        changes: _mappedList(
          document,
          SchedulingSnapshotDocumentFields.changes,
          SchedulingChangeDocumentMapping.fromDocument,
        ),
        overlaps: _mappedList(
          document,
          SchedulingSnapshotDocumentFields.overlaps,
          SchedulingOverlapDocumentMapping.fromDocument,
        ),
        operationName: _requiredNullableString(
          document,
          SchedulingSnapshotDocumentFields.operationName,
        ),
      ).._validateSchedulingSnapshotDocumentMetadata(document);
    });
  }
}
