package org.raddatz.familienarchiv.person.relationship;

import org.springframework.data.jpa.repository.JpaRepository;
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 PersonRelationshipRepository extends JpaRepository<PersonRelationship, UUID> {

    /**
     * Bulk fetch for the network endpoint — pulls only edges of the given types.
     * The service filters by family_member afterwards.
     */
    @Query("SELECT r FROM PersonRelationship r " +
           "JOIN FETCH r.person " +
           "JOIN FETCH r.relatedPerson " +
           "WHERE r.relationType IN :types")
    List<PersonRelationship> findAllByRelationTypeIn(@Param("types") Collection<RelationType> types);

    /** Used for the circular-PARENT_OF check in {@code addRelationship}. */
    boolean existsByPersonIdAndRelatedPersonIdAndRelationType(
            UUID personId, UUID relatedPersonId, RelationType relationType);

    /**
     * All edges incident on {@code personId} (either side) restricted to the given types.
     * Used by the inference service to load a person's local subgraph for BFS.
     */
    @Query("SELECT r FROM PersonRelationship r " +
           "WHERE (r.person.id = :personId OR r.relatedPerson.id = :personId) " +
           "AND r.relationType IN :types")
    List<PersonRelationship> findAllByPersonIdOrRelatedPersonIdAndRelationTypeIn(
            @Param("personId") UUID personId,
            @Param("types") Collection<RelationType> types);

    /**
     * All edges incident on {@code personId} (either side), all types.
     * Used by the "direct relationships" listings (person edit, side panel).
     */
    @Query("SELECT r FROM PersonRelationship r " +
           "JOIN FETCH r.person " +
           "JOIN FETCH r.relatedPerson " +
           "WHERE r.person.id = :personId OR r.relatedPerson.id = :personId")
    List<PersonRelationship> findAllByPersonIdOrRelatedPersonId(@Param("personId") UUID personId);
}
