package cloud.nstart.terravault.ordinis.domain.record;

import java.time.OffsetDateTime;
import java.util.List;
import java.util.UUID;

/**
 * Native SQL для record-level dependents lookup: "какие active записи в
 * source dictionary ссылаются на target record через JSONB
 * {@code data->>source_field == target_value}".
 *
 * <p>Используется {@code LineageIndexService.findRecordDependents} в Phase 1.
 * Phase 2 переносит этот lookup на materialized view с UNIQUE INDEX(id) для
 * REFRESH CONCURRENTLY — пока живём с прямым JSONB query (acceptable для
 * {@code <}5k records SLO).
 *
 * <p>Interface вместо concrete класса — JDK 25 + Mockito inline-mock не работает
 * на concrete classes (см. memo "JDK 25 + Mockito subclass mock-maker incompat").
 * Default impl {@link DependentsQueryJdbc} автоинджектится через @Component.
 */
public interface DependentsQuery {

  /**
   * Active records в source_dict где {@code data->>source_field == value}.
   * Возвращает paginated slice + total count (один call для UI: count first,
   * потом page если total > 0).
   *
   * <p>NULL-значения в source_field автоматически исключены SQL'ом
   * (NULL != value никогда не true).
   *
   * <p>Order by created_at DESC чтобы newest dependents видны первыми
   * (admin debug pattern).
   *
   * @param sourceDictionaryId source dict (referencing)
   * @param sourceField        JSONB key в source data что хранит ref value
   * @param targetValue        фактическое значение target field в target record
   * @param at                 момент времени — обычно now()
   * @param limit              page size (caller должен ограничить ≤ 200)
   * @param offset             page offset (≥ 0)
   * @return slice records sorted by created_at DESC
   */
  List<DependentRow> findActive(
      UUID sourceDictionaryId,
      String sourceField,
      String targetValue,
      OffsetDateTime at,
      int limit,
      int offset);

  /**
   * Total count active dependents — отдельный query без LIMIT/OFFSET для
   * pagination header. Faster чем {@code SELECT COUNT(*)} над основным
   * results когда LIMIT/OFFSET идёт в отдельном request.
   */
  long countActive(
      UUID sourceDictionaryId,
      String sourceField,
      String targetValue,
      OffsetDateTime at);

  /**
   * Lightweight projection — лишний JSONB data в payload не нужен на этом
   * endpoint, экономим bandwidth.
   */
  record DependentRow(
      UUID id,
      UUID dictionaryId,
      String businessKey,
      OffsetDateTime validFrom,
      OffsetDateTime validTo,
      OffsetDateTime createdAt) {}
}
