package connector_events

import (
	"context"
	"fmt"
)

// LoadSourceProjectionPayloads loads exactly the claimed WorkItem's persisted
// input range. No clock or terminal history participates in membership.
func (s *Service) LoadSourceProjectionPayloads(ctx context.Context, workID string) ([]*ConnectorEvent, error) {
	if s.workqueue == nil {
		return nil, fmt.Errorf("connector events: WorkItem repository is required")
	}
	bounds, err := s.workqueue.GetSourceProjectionRange(ctx, workID)
	if err != nil {
		return nil, err
	}
	selected, err := s.loadByID(ctx, bounds.EventID)
	if err != nil {
		return nil, err
	}
	rows, err := s.db.QueryContext(ctx, `SELECT e.EnqueueOrdinal,
       e.Id, e.Namespace, e.InstalledPackId, e.EventKind, e.IdempotencyKey, e.Status,
       e.QueueClass, e.Payload, e.RetryCount, e.LastError, e.LastErrorAt,
       e.ClaimedBy, e.ClaimedAt, e.ClaimToken, e.ProcessedAt, e.ReplayedAt, e.ReplayOfId,
       e.RouteVersion, e.CompanionPackInstallId, e.CompanionFlowVersionId,
       e.SourceLaneKey, e.DeliveryId, e.DeliverySequence, e.CreatedDate, e.LastModifiedDate
  FROM _System_ConnectorEvent e
 WHERE e.Namespace = ?
   AND e.InstalledPackId = ?
   AND LOWER(TRIM(e.EventKind)) = LOWER(TRIM(?))
   AND COALESCE(e.RouteVersion, 0) = ?
   AND COALESCE(e.CompanionPackInstallId, '') = ?
   AND COALESCE(e.CompanionFlowVersionId, '') = ?
   AND e.SourceLaneKey = ?

 AND e.EnqueueOrdinal BETWEEN ? AND ? ORDER BY e.EnqueueOrdinal,e.Id`,
		selected.Namespace, bounds.Identity.InstalledPackID, bounds.Identity.EventKind, bounds.Identity.RouteVersion,
		bounds.Identity.CompanionPackInstallID, bounds.Identity.CompanionFlowVersionID, bounds.Identity.SourceLaneKey,
		bounds.InputStartOrdinal, bounds.InputEndOrdinal)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	out := []*ConnectorEvent{}
	for rows.Next() {
		var ordinal int64
		e, err := scanOneWithLeading(rows, &ordinal)
		if err != nil {
			return nil, err
		}
		out = append(out, &e)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	if len(out) == 0 || out[len(out)-1].ID != bounds.EventID {
		return nil, ErrEventNotFound
	}
	return out, nil
}
