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

part of '../../../../application_layer.dart';

/// Private implementation type for `_UnitOfWorkOwnerSettingsRepository` in this library.
/// It keeps supporting state and behavior scoped to the owning file so the public API stays focused on the scheduler concepts that callers use directly.
class _UnitOfWorkOwnerSettingsRepository implements OwnerSettingsRepository {
  /// Creates a `_UnitOfWorkOwnerSettingsRepository` 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.
  _UnitOfWorkOwnerSettingsRepository({
    required Map<String, OwnerSettings> settingsByOwnerId,
    required Map<String, int> revisionsByOwnerId,
  })  : _settingsByOwnerId = settingsByOwnerId,
        _revisionsByOwnerId = revisionsByOwnerId;

  /// Private state stored as `_settingsByOwnerId` for this implementation.
  /// The field is intentionally scoped to this library so only the owning type can change the related scheduler or UI behavior.
  final Map<String, OwnerSettings> _settingsByOwnerId;

  /// Private state stored as `_revisionsByOwnerId` for this implementation.
  /// The field is intentionally scoped to this library so only the owning type can change the related scheduler or UI behavior.
  final Map<String, int> _revisionsByOwnerId;

  /// Runs the `findByOwnerId` operation and completes after its asynchronous work finishes.
  /// Callers should await the returned future so repository writes, UI refreshes, and failure handling happen in a predictable order.
  @override
  Future<OwnerSettings?> findByOwnerId(String ownerId) async {
    return _settingsByOwnerId[ownerId];
  }

  /// Runs the `findRecordByOwnerId` operation and completes after its asynchronous work finishes.
  /// Callers should await the returned future so repository writes, UI refreshes, and failure handling happen in a predictable order.
  @override
  Future<RepositoryRecord<OwnerSettings>?> findRecordByOwnerId(
    String ownerId,
  ) async {
    final settings = _settingsByOwnerId[ownerId];
    if (settings == null) {
      return null;
    }
    return RepositoryRecord(
      value: settings,
      ownerId: ownerId,
      revision: _revisionsByOwnerId[ownerId] ?? 1,
    );
  }

  /// Runs the `save` operation and completes after its asynchronous work finishes.
  /// Callers should await the returned future so repository writes, UI refreshes, and failure handling happen in a predictable order.
  @override
  Future<void> save(OwnerSettings settings) async {
    _settingsByOwnerId[settings.ownerId] = settings;
    _revisionsByOwnerId[settings.ownerId] =
        (_revisionsByOwnerId[settings.ownerId] ?? 1) + 1;
  }

  /// Runs the `saveIfRevision` operation and completes after its asynchronous work finishes.
  /// Callers should await the returned future so repository writes, UI refreshes, and failure handling happen in a predictable order.
  @override
  Future<RepositoryMutationResult> saveIfRevision({
    required OwnerSettings settings,
    required int expectedRevision,
  }) async {
    final ownerId = settings.ownerId;
    if (!_settingsByOwnerId.containsKey(ownerId)) {
      return RepositoryMutationResult.failure(
        RepositoryFailure(
          code: RepositoryFailureCode.notFound,
          entityId: ownerId,
        ),
      );
    }
    final actualRevision = _revisionsByOwnerId[ownerId] ?? 1;
    if (actualRevision != expectedRevision) {
      return RepositoryMutationResult.failure(
        RepositoryFailure(
          code: RepositoryFailureCode.staleRevision,
          entityId: ownerId,
          expectedRevision: expectedRevision,
          actualRevision: actualRevision,
        ),
      );
    }
    final nextRevision = actualRevision + 1;
    _settingsByOwnerId[ownerId] = settings;
    _revisionsByOwnerId[ownerId] = nextRevision;
    return RepositoryMutationResult.success(revision: nextRevision);
  }
}
