package postgres

import (
	"context"
	"fmt"
	"time"
)

type Card struct {
	ID               string
	PublicID         string
	CardType         string
	Title            string
	Subtitle         *string
	CoverURL         *string
	DisplaySlot      string
	DisplayPriority  int
	EntryChannelID   *string
	EventPublicID    *string
	EventDisplayName *string
	EventSummary     *string
	HTMLURL          *string
}

func (s *Store) ListCardsForEntry(ctx context.Context, tenantID string, entryChannelID *string, slot string, now time.Time, limit int) ([]Card, error) {
	if limit <= 0 || limit > 100 {
		limit = 20
	}
	if slot == "" {
		slot = "home_primary"
	}

	rows, err := s.pool.Query(ctx, `
		SELECT
			c.id,
			c.card_public_id,
			c.card_type,
			c.title,
			c.subtitle,
			c.cover_url,
			c.display_slot,
			c.display_priority,
			c.entry_channel_id,
			e.event_public_id,
			e.display_name,
			e.summary,
			c.html_url
		FROM cards c
		LEFT JOIN events e ON e.id = c.event_id
		WHERE c.tenant_id = $1
		  AND ($2::uuid IS NULL OR c.entry_channel_id = $2 OR c.entry_channel_id IS NULL)
		  AND c.display_slot = $3
		  AND c.status = 'active'
		  AND (c.starts_at IS NULL OR c.starts_at <= $4)
		  AND (c.ends_at IS NULL OR c.ends_at >= $4)
		ORDER BY
		  CASE WHEN $2::uuid IS NOT NULL AND c.entry_channel_id = $2 THEN 0 ELSE 1 END,
		  c.display_priority DESC,
		  c.created_at ASC
		LIMIT $5
	`, tenantID, entryChannelID, slot, now, limit)
	if err != nil {
		return nil, fmt.Errorf("list cards for entry: %w", err)
	}
	defer rows.Close()

	var cards []Card
	for rows.Next() {
		var card Card
		if err := rows.Scan(
			&card.ID,
			&card.PublicID,
			&card.CardType,
			&card.Title,
			&card.Subtitle,
			&card.CoverURL,
			&card.DisplaySlot,
			&card.DisplayPriority,
			&card.EntryChannelID,
			&card.EventPublicID,
			&card.EventDisplayName,
			&card.EventSummary,
			&card.HTMLURL,
		); err != nil {
			return nil, fmt.Errorf("scan card: %w", err)
		}
		cards = append(cards, card)
	}
	if err := rows.Err(); err != nil {
		return nil, fmt.Errorf("iterate cards: %w", err)
	}
	return cards, nil
}
