package org.raddatz.familienarchiv.document;

import io.swagger.v3.oas.annotations.media.Schema;
import org.springframework.data.domain.Pageable;

import java.util.List;

public record DocumentSearchResult(
        @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
        List<DocumentListItem> items,
        @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
        long totalElements,
        @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
        int pageNumber,
        @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
        int pageSize,
        @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
        int totalPages,
        /**
         * Total number of undated documents (meta_date IS NULL) matching the current
         * filter context (q/tags/sender/receiver/status) across ALL pages — not the
         * undated rows on the current page. Computed independently of the "Nur
         * undatierte" toggle so it never collapses to the page slice (issue #668).
         */
        @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
        long undatedCount
) {
    /**
     * Single-page convenience factory used by empty-result shortcuts and by tests that
     * don't care about paging. Treats the whole list as page 0 of itself. The undated
     * count defaults to 0 — the service overlays the real global count via
     * {@link #withUndatedCount(long)} before returning.
     */
    public static DocumentSearchResult of(List<DocumentListItem> items) {
        int size = items.size();
        return new DocumentSearchResult(items, size, 0, size, size == 0 ? 0 : 1, 0L);
    }

    /**
     * Paged factory used by the service when it has a real Pageable + full match count
     * (e.g. from Spring's Page&lt;T&gt; or from an in-memory sort-then-slice). The undated
     * count defaults to 0 — the service overlays the real global count via
     * {@link #withUndatedCount(long)} before returning.
     */
    public static DocumentSearchResult paged(List<DocumentListItem> slice, Pageable pageable, long totalElements) {
        int pageSize = pageable.getPageSize();
        int totalPages = pageSize == 0 ? 0 : (int) ((totalElements + pageSize - 1) / pageSize);
        return new DocumentSearchResult(slice, totalElements, pageable.getPageNumber(), pageSize, totalPages, 0L);
    }

    /**
     * Returns a copy with the global undated count overlaid, leaving every other
     * field untouched. Lets the service compute the count once and attach it to
     * whichever result shape the search path produced.
     */
    public DocumentSearchResult withUndatedCount(long undatedCount) {
        return new DocumentSearchResult(items, totalElements, pageNumber, pageSize, totalPages, undatedCount);
    }
}
