package httpapi

import (
	"context"
	"fmt"

	"github.com/dtoro/oikos/internal/core/domain"
	"github.com/dtoro/oikos/internal/core/app"
	"github.com/dtoro/oikos/internal/httpapi/gen"
)

func (s *Server) CreateRelationship(ctx context.Context, req gen.CreateRelationshipRequestObject) (gen.CreateRelationshipResponseObject, error) {
	if req.Body == nil {
		return nil, fmt.Errorf("%w: request body is required", domain.ErrInvalidInput)
	}

	// Resolve source and target entities for their types (edge validation).
	src, err := s.readModels.GetEntityBySlug(ctx, req.Body.Source)
	if err != nil {
		return nil, err
	}
	tgt, err := s.readModels.GetEntityBySlug(ctx, req.Body.Target)
	if err != nil {
		return nil, err
	}

	actorType, actor := actorInfo(ctx)
	created, err := s.relService.Create(ctx, app.CreateRelationshipCmd{
		SourceID:   src.Entity.ID,
		TargetID:   tgt.Entity.ID,
		SourceType: src.Entity.Type,
		TargetType: tgt.Entity.Type,
		Type:       req.Body.Type,
		Attributes: derefAttrs(req.Body.Attributes),
		ActorType:  actorType,
		Actor:      actor,
		Method:     "POST",
		Path:       "/api/v1/relationships",
	})
	if err != nil {
		return nil, err
	}

	rel := gen.Relationship{
		Source:    req.Body.Source,
		Target:    req.Body.Target,
		Type:      created.Type,
		ValidFrom: created.ValidFrom,
	}
	if req.Body.Attributes != nil {
		rel.Attributes = req.Body.Attributes
	}
	return gen.CreateRelationship201JSONResponse(rel), nil
}

func (s *Server) EndRelationship(ctx context.Context, req gen.EndRelationshipRequestObject) (gen.EndRelationshipResponseObject, error) {
	src, err := s.readModels.GetEntityBySlug(ctx, req.Params.Source)
	if err != nil {
		return nil, err
	}
	tgt, err := s.readModels.GetEntityBySlug(ctx, req.Params.Target)
	if err != nil {
		return nil, err
	}

	if err := s.relService.End(ctx, src.Entity.ID, tgt.Entity.ID, req.Params.RelType); err != nil {
		return nil, err
	}

	return gen.EndRelationship204Response{}, nil
}