package store

import (
	"context"
	"fmt"

	"github.com/jackc/pgx/v5"
)

// DeleteUser permanently removes a user and all of their data. It runs through
// withUser so RLS confines every statement to the calling user's own rows.
//
// Deleting the users row cascades (ON DELETE CASCADE) to videos, summaries
// (→ sink_deliveries), video_connections, and the user_identities map —
// referential-integrity cascades bypass RLS, so a user's child rows are removed
// even though the deleting connection is scoped. Transcripts are NOT removed:
// since ADR-021 they are shared public content keyed by (provider,
// provider_video_id) with no user_id, so another user may still reference the
// same row — a user deletion must not strip shared caption content. summary_actions and login_events
// are the exceptions: each carries a user_id but has NO foreign key to users
// (migrations 002 and 010), so the cascade does not reach them; they are deleted
// explicitly in the same scoped transaction. Deleting an absent user is a no-op
// (idempotent).
//
// This is tapir-side only (decision 2026-06-03): it removes all tapir data; the
// Dex login identity is left untouched — a later login simply re-enters
// registration. The user's secrets (OAuth tokens) live in the SecretStore, not
// the DB, and are removed by the caller (the account handler).
func (s *Store) DeleteUser(ctx context.Context, userID string) error {
	return s.withUser(ctx, userID, func(tx pgx.Tx) error {
		if _, err := tx.Exec(ctx,
			`DELETE FROM summary_actions WHERE user_id = $1`, userID); err != nil {
			return fmt.Errorf("store: delete summary_actions: %w", err)
		}
		if _, err := tx.Exec(ctx,
			`DELETE FROM login_events WHERE user_id = $1`, userID); err != nil {
			return fmt.Errorf("store: delete login_events: %w", err)
		}
		if _, err := tx.Exec(ctx,
			`DELETE FROM users WHERE id = $1`, userID); err != nil {
			return fmt.Errorf("store: delete user: %w", err)
		}
		return nil
	})
}

// DisplayName returns the user's registered display name (empty if unset). Scoped
// by user_id via withUser, like every read in this package.
func (s *Store) DisplayName(ctx context.Context, userID string) (string, error) {
	var name string
	if err := s.withUser(ctx, userID, func(tx pgx.Tx) error {
		return tx.QueryRow(ctx,
			`SELECT COALESCE(display_name, '') FROM users WHERE id = $1`, userID).Scan(&name)
	}); err != nil {
		return "", fmt.Errorf("store: display name: %w", err)
	}
	return name, nil
}
