package org.raddatz.familienarchiv.person;

import io.swagger.v3.oas.annotations.media.Schema;

import java.util.List;

/**
 * Paged result for the /api/persons list endpoint.
 *
 * <p>Hand-written to mirror {@code document/DocumentSearchResult} field-for-field so the
 * frontend sees one paged shape across the app. Deliberately NOT Spring {@code Page<T>}
 * (unstable serialized shape across Spring versions, noisy in OpenAPI) and deliberately
 * NOT a reuse of the document DTO (would couple two feature modules — duplication beats
 * coupling here).
 */
public record PersonSearchResult(
        @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
        List<PersonSummaryDTO> 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
) {
    /**
     * Paged factory: derives {@code totalPages} from the full match count and the page size.
     * A zero count yields zero pages so the frontend hides the pagination control.
     */
    public static PersonSearchResult paged(List<PersonSummaryDTO> slice, int pageNumber, int pageSize, long totalElements) {
        int totalPages = pageSize == 0 ? 0 : (int) ((totalElements + pageSize - 1) / pageSize);
        return new PersonSearchResult(slice, totalElements, pageNumber, pageSize, totalPages);
    }

    /**
     * Non-paged factory for the legacy {@code sort=documentCount} top-N dashboard path.
     * That query returns the <em>complete</em> result in one shot — there is no further page
     * to fetch — so the envelope reports reality rather than pretending to be a slice of a
     * larger set: {@code totalElements} equals the number of rows actually returned,
     * {@code pageSize} equals that same count, and {@code totalPages} is 1 (or 0 when empty).
     * This avoids the earlier ambiguity where {@code totalElements} looked like a paged total.
     */
    public static PersonSearchResult topN(List<PersonSummaryDTO> all) {
        int count = all.size();
        int totalPages = count == 0 ? 0 : 1;
        return new PersonSearchResult(all, count, 0, count, totalPages);
    }
}
