package org.raddatz.familienarchiv.geschichte;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.util.Collection;
import java.util.List;
import java.util.UUID;

@Repository
public interface GeschichteRepository extends JpaRepository<Geschichte, UUID>, JpaSpecificationExecutor<Geschichte> {

    /**
     * Returns the grid projection. Never carries items (avoids lazy-init 500 under open-in-view:false).
     *
     * <p>Status clamp: callers must pass the effective status (PUBLISHED for readers,
     * raw status for BLOG_WRITE users). authorId restricts to own drafts when effective=DRAFT.
     *
     * <p>Person filter: personCount=0 disables the filter. When personCount>0, the story must
     * be associated with ALL person ids in personIds (AND-semantics via counting subquery).
     * Pass a non-empty personIds collection when personCount>0 — empty IN() is invalid SQL.
     */
    @Query("""
            SELECT g.id AS id, g.title AS title, g.status AS status, g.type AS type,
                   g.author AS author, g.publishedAt AS publishedAt, g.updatedAt AS updatedAt, g.body AS body
            FROM Geschichte g
            WHERE g.status = :effectiveStatus
              AND (:authorId IS NULL OR g.author.id = :authorId)
              AND (:personCount = 0 OR
                   (SELECT COUNT(DISTINCT p.id)
                    FROM Geschichte g2 JOIN g2.persons p
                    WHERE g2.id = g.id AND p.id IN :personIds) = :personCount)
              AND (:documentId IS NULL OR
                   EXISTS (SELECT 1 FROM JourneyItem ji
                           WHERE ji.geschichte = g AND ji.document.id = :documentId))
            ORDER BY COALESCE(g.publishedAt, g.updatedAt) DESC
            """)
    List<GeschichteSummary> findSummaries(
            @Param("effectiveStatus") GeschichteStatus effectiveStatus,
            @Param("authorId") UUID authorId,
            @Param("personIds") Collection<UUID> personIds,
            @Param("personCount") long personCount,
            @Param("documentId") UUID documentId);
}
