package httpapi

import (
	"context"
	"encoding/json"

	"github.com/dtoro/oikos/internal/httpapi/gen"
)

func (s *Server) QueryEvents(ctx context.Context, req gen.QueryEventsRequestObject) (gen.QueryEventsResponseObject, error) {
	limit := clampLimit(req.Params.Limit)
	var eventType, entityID, severity, correlationID *string
	if req.Params.Type != nil {
		eventType = req.Params.Type
	}
	if req.Params.EntityId != nil {
		entityID = req.Params.EntityId
	}
	if req.Params.Severity != nil {
		severity = req.Params.Severity
	}
	if req.Params.CorrelationId != nil {
		correlationID = req.Params.CorrelationId
	}

	rows, err := s.pool.Query(ctx, `
		SELECT id, ts, type, entity_id::text, severity, source, data, correlation_id
		FROM events
		WHERE ($1::text IS NULL OR type = $1)
		  AND ($2::text IS NULL OR entity_id::text = $2)
		  AND ($3::text IS NULL OR severity = $3)
		  AND ($4::text IS NULL OR correlation_id = $4)
		  AND ($5::timestamptz IS NULL OR ts >= $5)
		  AND ($6::timestamptz IS NULL OR ts <= $6)
		ORDER BY ts DESC
		LIMIT $7`,
		eventType, entityID, severity, correlationID, req.Params.From, req.Params.To, limit)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	items := []gen.Event{}
	for rows.Next() {
		var e gen.Event
		var dataBytes []byte
		var entID, corrID *string
		if err := rows.Scan(&e.Id, &e.Ts, &e.Type, &entID, &e.Severity, &e.Source, &dataBytes, &corrID); err != nil {
			return nil, err
		}
		e.EntityId = entID
		e.CorrelationId = corrID
		var data map[string]any
		if json.Unmarshal(dataBytes, &data) == nil {
			e.Data = &data
		}
		items = append(items, e)
	}
	return gen.QueryEvents200JSONResponse{Items: items}, rows.Err()
}