package query

import (
	"context"
	"time"
)

// Status values for async query execution.
const (
	StatusQueued    = "QUEUED"
	StatusRunning   = "RUNNING"
	StatusSucceeded = "SUCCEEDED"
	StatusFailed    = "FAILED"
	StatusCancelled = "CANCELLED"
)

// OutputModeInline returns JSON pages; OutputModeExport writes to object storage.
const (
	OutputModeInline = "inline"
	OutputModeExport = "export"
)

// Engine is the multi-cloud SQL analytics backend.
// AWS uses Athena; GCP / Azure / AliCloud implement the same interface later.
type Engine interface {
	Name() string
	Submit(ctx context.Context, req *EngineSubmitRequest) (*Handle, error)
	Status(ctx context.Context, handle *Handle) (*ExecutionStatus, error)
	FetchPage(ctx context.Context, handle *Handle, nextToken string, maxRows int64) (*Page, error)
	// PresignResult returns a time-limited download URL for the full result artifact (e.g. Athena CSV on S3).
	PresignResult(ctx context.Context, handle *Handle, expires time.Duration) (*PresignedResult, error)
	Cancel(ctx context.Context, handle *Handle) error
}

// PresignedResult describes a downloadable query result object.
type PresignedResult struct {
	Format    string
	S3URI     string
	URL       string
	ExpiresAt time.Time
	Bytes     *int64
}

// EngineSubmitRequest is cloud-agnostic SQL execution input.
type EngineSubmitRequest struct {
	SQL                string
	Database           string
	OutputLocation     string
	WorkGroup          string
	ClientRequestToken string
}

// Handle identifies a running or finished query in the backend engine.
type Handle struct {
	EngineName  string
	ExecutionID string
}

// ExecutionStatus is a snapshot of query progress.
type ExecutionStatus struct {
	Status                    string
	StateChangeReason         string
	SubmittedAt               *time.Time
	CompletedAt               *time.Time
	ScannedBytes              int64 // Athena DataScannedInBytes (billing basis)
	EngineExecutionTimeMillis int64
	TotalExecutionTimeMillis  int64
	QueryQueueTimeMillis      int64
	QueryPlanningTimeMillis   int64
}

// Page is one result page.
type Page struct {
	Columns     []Column
	Rows        [][]any
	NextToken   string
	UpdateCount int64
}

// Column describes a result schema field.
type Column struct {
	Name string `json:"name"`
	Type string `json:"type,omitempty"`
}

// NotReadyError means the vendor engine is not implemented for this deployment.
type NotReadyError struct {
	Provider string
	Engine   string
}

func (e *NotReadyError) Error() string {
	return "query engine not ready for provider=" + e.Provider + " engine=" + e.Engine
}
