package storage

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

// SavedSearch represents a user's saved search query (PROJ-42).
type SavedSearch struct {
	ID        int64     `json:"id"`
	UserID    int64     `json:"user_id"`
	TenantID  int64     `json:"tenant_id"`
	Name      string    `json:"name"`
	QueryJSON []byte    `json:"query"`
	CreatedAt time.Time `json:"created_at"`
}

// ListSavedSearches returns all saved searches for the given user and tenant.
func (s *Store) ListSavedSearches(ctx context.Context, userID, tenantID int64) ([]SavedSearch, error) {
	rows, err := s.db.Query(ctx, `
		SELECT id, user_id, tenant_id, name, query_json, created_at
		FROM saved_searches
		WHERE user_id = $1 AND tenant_id = $2
		ORDER BY created_at DESC
	`, userID, tenantID)
	if err != nil {
		return nil, fmt.Errorf("saved_searches: list: %w", err)
	}
	defer rows.Close()

	var result []SavedSearch
	for rows.Next() {
		var ss SavedSearch
		if err := rows.Scan(&ss.ID, &ss.UserID, &ss.TenantID, &ss.Name, &ss.QueryJSON, &ss.CreatedAt); err != nil {
			return nil, fmt.Errorf("saved_searches: scan: %w", err)
		}
		result = append(result, ss)
	}
	return result, rows.Err()
}

// CreateSavedSearch inserts a new saved search and returns it.
func (s *Store) CreateSavedSearch(ctx context.Context, userID, tenantID int64, name string, queryJSON []byte) (*SavedSearch, error) {
	ss := &SavedSearch{
		UserID:   userID,
		TenantID: tenantID,
		Name:     name,
		QueryJSON: queryJSON,
	}
	err := s.db.QueryRow(ctx, `
		INSERT INTO saved_searches (user_id, tenant_id, name, query_json)
		VALUES ($1, $2, $3, $4)
		RETURNING id, created_at
	`, userID, tenantID, name, queryJSON).Scan(&ss.ID, &ss.CreatedAt)
	if err != nil {
		return nil, fmt.Errorf("saved_searches: create: %w", err)
	}
	return ss, nil
}

// DeleteSavedSearch deletes a saved search. Ownership is enforced by requiring
// both userID and tenantID to match the row.
func (s *Store) DeleteSavedSearch(ctx context.Context, id, userID, tenantID int64) error {
	tag, err := s.db.Exec(ctx, `
		DELETE FROM saved_searches
		WHERE id = $1 AND user_id = $2 AND tenant_id = $3
	`, id, userID, tenantID)
	if err != nil {
		return fmt.Errorf("saved_searches: delete: %w", err)
	}
	if tag.RowsAffected() == 0 {
		return fmt.Errorf("saved_searches: not found or not owned by user")
	}
	return nil
}
