package audit

import (
	"context"
	"database/sql"
	"fmt"
	"time"
)

// EventTimeExecutor is the active-transaction read surface used to obtain the
// database ordering token shared by audit facts and history-tracking intervals.
type EventTimeExecutor interface {
	QueryRowContext(context.Context, string, ...interface{}) *sql.Row
}

// EventTimeProvider is the narrow deterministic seam used by transaction
// adapters that do not expose database/sql directly.
type EventTimeProvider interface {
	CurrentEventTime(context.Context) (time.Time, error)
}

// CurrentEventTime reads one microsecond UTC ordering token from the caller's
// active transaction. Callers must fail closed rather than substitute a host
// clock because temporal eligibility compares this value with DB boundaries.
func CurrentEventTime(ctx context.Context, tx interface{}) (time.Time, error) {
	if provider, ok := tx.(EventTimeProvider); ok && provider != nil {
		eventAt, err := provider.CurrentEventTime(ctx)
		if err != nil {
			return time.Time{}, fmt.Errorf("read audit event time: %w", err)
		}
		return eventAt.UTC(), nil
	}
	exec, ok := tx.(EventTimeExecutor)
	if !ok || exec == nil {
		return time.Time{}, fmt.Errorf("audit event time requires an active transaction executor")
	}
	var eventAt time.Time
	if err := exec.QueryRowContext(ctx, "SELECT UTC_TIMESTAMP(6)").Scan(&eventAt); err != nil {
		return time.Time{}, fmt.Errorf("read audit event time: %w", err)
	}
	return eventAt.UTC(), nil
}
