-- name: ListEntityRelations :many
SELECT se.slug AS source_slug, te.slug AS target_slug, r.type, r.attributes,
       r.valid_from, r.valid_to
FROM relationships r
JOIN entities se ON se.id = r.source_id
JOIN entities te ON te.id = r.target_id
WHERE r.valid_to IS NULL
  AND ((sqlc.arg('direction')::text IN ('out','both') AND r.source_id = sqlc.arg('id'))
    OR (sqlc.arg('direction')::text IN ('in','both')  AND r.target_id = sqlc.arg('id')))
  AND (sqlc.narg('rel_type')::text IS NULL OR r.type = sqlc.narg('rel_type'))
ORDER BY r.type, se.slug, te.slug;

-- name: ListGraphEdges :many
SELECT se.slug AS source_slug, te.slug AS target_slug, r.type, r.attributes,
       r.valid_from, r.valid_to
FROM relationships r
JOIN entities se ON se.id = r.source_id
JOIN entities te ON te.id = r.target_id
WHERE r.valid_to IS NULL
  AND r.source_id = ANY(sqlc.arg('ids')::uuid[])
  AND r.target_id = ANY(sqlc.arg('ids')::uuid[])
  AND (sqlc.narg('rel_types')::text[] IS NULL OR r.type = ANY(sqlc.narg('rel_types')::text[]))
ORDER BY r.type, se.slug, te.slug;

-- name: EndCurrentRelationship :execrows
UPDATE relationships SET valid_to = now()
WHERE source_id = $1 AND target_id = $2 AND type = $3 AND valid_to IS NULL;

-- name: InsertRelationshipIfAbsent :execrows
-- Idempotent relationship insert (the create_relationship surface): no-op if
-- an active edge of the same source/target/type already exists. Replaces the
-- raw INSERT...WHERE NOT EXISTS used in entity_tools.go.
INSERT INTO relationships (source_id, target_id, type, attributes, valid_from)
SELECT sqlc.arg('source_id'), sqlc.arg('target_id'), sqlc.arg('type'),
       sqlc.arg('attributes')::jsonb, now()
WHERE NOT EXISTS (
    SELECT 1 FROM relationships
    WHERE source_id = sqlc.arg('source_id')
      AND target_id = sqlc.arg('target_id')
      AND type = sqlc.arg('type')
      AND valid_to IS NULL
);
