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

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

/// Private implementation type for `_UnitOfWorkOperationRepository` 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 _UnitOfWorkOperationRepository implements ApplicationOperationRepository {
  /// Creates a `_UnitOfWorkOperationRepository` 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.
  _UnitOfWorkOperationRepository(this._operationsById);

  /// Private state stored as `_operationsById` 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, ApplicationOperationRecord> _operationsById;

  /// Runs the `findById` 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<ApplicationOperationRecord?> findById(String operationId) async {
    return _operationsById[operationId];
  }

  /// Runs the `findByIdempotencyKey` 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<ApplicationOperationRecord?> findByIdempotencyKey({
    required String ownerId,
    required String operationId,
  }) async {
    final operation = _operationsById[operationId];
    if (operation == null || operation.ownerId != ownerId) {
      return null;
    }
    return operation;
  }

  /// 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(ApplicationOperationRecord operation) async {
    _operationsById[operation.operationId] = operation;
  }

  /// Runs the `insertIfAbsent` 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> insertIfAbsent(
    ApplicationOperationRecord operation,
  ) async {
    if (_operationsById.containsKey(operation.operationId)) {
      return RepositoryMutationResult.failure(
        RepositoryFailure(
          code: RepositoryFailureCode.duplicateOperation,
          entityId: operation.operationId,
        ),
      );
    }
    _operationsById[operation.operationId] = operation;
    return RepositoryMutationResult.success(revision: 1);
  }
}

/// Top-level helper that performs the `_noticeAcknowledgementKey` operation for this file.
/// Keeping the helper private makes the surrounding flow easier to read while preventing unrelated libraries from depending on implementation detail.
String _noticeAcknowledgementKey({
  required String ownerId,
  required String noticeId,
}) {
  return '$ownerId::$noticeId';
}

/// Top-level helper that performs the `_page<T>` operation for this file.
/// Keeping the helper private makes the surrounding flow easier to read while preventing unrelated libraries from depending on implementation detail.
RepositoryPage<T> _page<T>(List<T> sortedItems, RepositoryPageRequest request) {
  final offset = int.tryParse(request.cursor ?? '') ?? 0;
  final safeOffset = offset.clamp(0, sortedItems.length);
  final end = (safeOffset + request.limit).clamp(0, sortedItems.length);
  final items = sortedItems.sublist(safeOffset, end);
  final nextCursor = end < sortedItems.length ? end.toString() : null;
  return RepositoryPage<T>(
    items: List<T>.unmodifiable(items),
    nextCursor: nextCursor,
  );
}

/// Top-level helper that performs the `_taskOverlapsWindow` operation for this file.
/// Keeping the helper private makes the surrounding flow easier to read while preventing unrelated libraries from depending on implementation detail.
bool _taskOverlapsWindow(Task task, SchedulingWindow window) {
  final start = task.scheduledStart;
  final end = task.scheduledEnd;
  if (start == null || end == null) {
    return false;
  }
  return TimeInterval(start: start, end: end).overlaps(window.interval);
}

/// Top-level helper that performs the `_compareTaskIds` operation for this file.
/// Keeping the helper private makes the surrounding flow easier to read while preventing unrelated libraries from depending on implementation detail.
int _compareTaskIds(Task left, Task right) => left.id.compareTo(right.id);

/// Top-level helper that performs the `_compareScheduledTasks` operation for this file.
/// Keeping the helper private makes the surrounding flow easier to read while preventing unrelated libraries from depending on implementation detail.
int _compareScheduledTasks(Task left, Task right) {
  final leftStart = left.scheduledStart;
  final rightStart = right.scheduledStart;
  if (leftStart != null && rightStart != null) {
    final startComparison = leftStart.compareTo(rightStart);
    if (startComparison != 0) {
      return startComparison;
    }
  }
  return left.id.compareTo(right.id);
}

/// Top-level helper that performs the `_compareBacklogCandidates` operation for this file.
/// Keeping the helper private makes the surrounding flow easier to read while preventing unrelated libraries from depending on implementation detail.
int _compareBacklogCandidates(Task left, Task right) {
  final createdComparison = left.createdAt.compareTo(right.createdAt);
  if (createdComparison != 0) {
    return createdComparison;
  }
  return left.id.compareTo(right.id);
}

/// Top-level helper that performs the `_compareProjects` operation for this file.
/// Keeping the helper private makes the surrounding flow easier to read while preventing unrelated libraries from depending on implementation detail.
int _compareProjects(ProjectProfile left, ProjectProfile right) {
  final nameComparison = left.name.compareTo(right.name);
  if (nameComparison != 0) {
    return nameComparison;
  }
  return left.id.compareTo(right.id);
}

/// Top-level helper that performs the `_compareLockedBlocks` operation for this file.
/// Keeping the helper private makes the surrounding flow easier to read while preventing unrelated libraries from depending on implementation detail.
int _compareLockedBlocks(LockedBlock left, LockedBlock right) {
  final nameComparison = left.name.compareTo(right.name);
  if (nameComparison != 0) {
    return nameComparison;
  }
  return left.id.compareTo(right.id);
}

/// Top-level helper that performs the `_compareLockedOverrides` operation for this file.
/// Keeping the helper private makes the surrounding flow easier to read while preventing unrelated libraries from depending on implementation detail.
int _compareLockedOverrides(
  LockedBlockOverride left,
  LockedBlockOverride right,
) {
  final dateComparison = left.date.compareTo(right.date);
  if (dateComparison != 0) {
    return dateComparison;
  }
  final createdComparison = left.createdAt.compareTo(right.createdAt);
  if (createdComparison != 0) {
    return createdComparison;
  }
  return left.id.compareTo(right.id);
}

/// Top-level helper that performs the `_compareActivities` operation for this file.
/// Keeping the helper private makes the surrounding flow easier to read while preventing unrelated libraries from depending on implementation detail.
int _compareActivities(TaskActivity left, TaskActivity right) {
  final occurredComparison = left.occurredAt.compareTo(right.occurredAt);
  if (occurredComparison != 0) {
    return occurredComparison;
  }
  return left.id.compareTo(right.id);
}

/// Top-level helper that performs the `_compareNoticeAcknowledgements` operation for this file.
/// Keeping the helper private makes the surrounding flow easier to read while preventing unrelated libraries from depending on implementation detail.
int _compareNoticeAcknowledgements(
  NoticeAcknowledgementRecord left,
  NoticeAcknowledgementRecord right,
) {
  final acknowledgedComparison =
      left.acknowledgedAt.compareTo(right.acknowledgedAt);
  if (acknowledgedComparison != 0) {
    return acknowledgedComparison;
  }
  return left.noticeId.compareTo(right.noticeId);
}

/// Top-level helper that performs the `_requiredTrimmed` operation for this file.
/// Keeping the helper private makes the surrounding flow easier to read while preventing unrelated libraries from depending on implementation detail.
String _requiredTrimmed(String value, String name) {
  final trimmed = value.trim();
  if (trimmed.isEmpty) {
    throw ArgumentError.value(value, name, 'Value is required.');
  }
  return trimmed;
}
