package store

import (
	"context"
	"errors"
	"fmt"

	"github.com/jackc/pgx/v5"

	"git.d-ma.be/mathias/tapir/internal/domain"
)

// GetTranscript returns the shared, stored transcript for a video keyed by the
// cross-user dedup key (provider, providerVideoID), and whether one exists
// (ADR-021). It reads via the raw pool, NOT withUser: the table holds public
// content with no user_id and no RLS policy, so it is shared across users by
// construction. A stored SourceNone is a real hit (ok == true, HasText() ==
// false) — a known caption-less video, so the caller skips without re-fetching.
func (s *Store) GetTranscript(ctx context.Context, provider, providerVideoID string) (domain.Transcript, bool, error) {
	var source, lang, content string
	err := s.pool.QueryRow(ctx,
		`SELECT source, COALESCE(language, ''), COALESCE(content, '')
		   FROM transcripts WHERE provider = $1 AND provider_video_id = $2`,
		provider, providerVideoID).Scan(&source, &lang, &content)
	if errors.Is(err, pgx.ErrNoRows) {
		return domain.Transcript{}, false, nil
	}
	if err != nil {
		return domain.Transcript{}, false, fmt.Errorf("store: get transcript: %w", err)
	}
	return domain.Transcript{
		Source:   domain.TranscriptSource(source),
		Language: lang,
		Content:  content,
	}, true, nil
}

// SaveTranscript upserts the shared transcript for (provider, providerVideoID).
// Only terminal outcomes belong here: SourceCaptions (with text) or SourceNone
// (no captions). A transient SourceRateLimited is rejected so persistence never
// masks a 429 as a permanent absence — that stays a per-user retry (ADR-014).
// Last write wins on conflict (a later re-fetch may correct an entry). It writes
// via the raw pool, NOT withUser — public content, shared, non-RLS (ADR-021).
func (s *Store) SaveTranscript(ctx context.Context, provider, providerVideoID string, t domain.Transcript) error {
	switch t.Source {
	case domain.SourceCaptions, domain.SourceNone:
		// terminal — persist
	case domain.SourceRateLimited:
		return fmt.Errorf("store: refusing to persist transient rate-limited transcript for %s/%s", provider, providerVideoID)
	default:
		return fmt.Errorf("store: invalid transcript source %q", t.Source)
	}
	_, err := s.pool.Exec(ctx,
		`INSERT INTO transcripts (provider, provider_video_id, source, language, content)
		      VALUES ($1, $2, $3, NULLIF($4, ''), NULLIF($5, ''))
		 ON CONFLICT (provider, provider_video_id)
		 DO UPDATE SET source     = EXCLUDED.source,
		               language   = EXCLUDED.language,
		               content    = EXCLUDED.content,
		               fetched_at = NOW()`,
		provider, providerVideoID, string(t.Source), t.Language, t.Content)
	if err != nil {
		return fmt.Errorf("store: save transcript: %w", err)
	}
	return nil
}
