package entity

import (
	"time"

	"github.com/tidbcloud/serverless-service/internal/domain/constant"
	"gorm.io/datatypes"
)

type Export struct {
	ID            string                    `gorm:"column:id;type:varchar(255);not null;primaryKey"`
	State         constant.ExportState      `gorm:"column:state;type:enum('preparing','running','succeed','canceled','failed','deleted');null"`
	FileType      constant.ExportFileType   `gorm:"column:file_type;type:enum('SQL','CSV','PARQUET');not null;default:'SQL'"`
	TargetType    constant.ExportTargetType `gorm:"column:target_type;type:enum('LOCAL','S3','GCS','Azure','OSS');not null"`
	S3BucketURI   string                    `gorm:"column:s3_bucket_uri;type:varchar(255);null"`
	S3AccessKeyID string                    `gorm:"column:s3_access_key_id;type:varchar(255);null"`
	S3RoleArn     string                    `gorm:"column:s3_role_arn;type:varchar(2048);null"`
	S3Endpoint    string                    `gorm:"column:s3_endpoint;type:varchar(255);null"`
	LocalURL      string                    `gorm:"column:local_url;null"`
	CSVFormat     datatypes.JSON            `gorm:"column:csv_format;type:json;null"`
	CreatedAt     *time.Time                `gorm:"column:created_at;type:timestamp;not null;autoCreateTime;index:idx_created_at"`
	UpdatedAt     *time.Time                `gorm:"column:updated_at;type:timestamp;null;default:null;autoUpdateTime"`
	DeletedAt     *time.Time                `gorm:"column:deleted_at;type:timestamp;null"`
	TenantID      string                    `gorm:"column:tenant_id;type:varchar(255);not null"`
	// ProjectID stores the OriginalProjectId (stable, not changed during project migration).
	// It is used for Infra CR interaction only (e.g., namespace, labels, annotations).
	// DO NOT use this for events, RPC, HTTP responses, or any user-facing APIs.
	// For those cases, always use cluster.ProjectId to get the latest project id.
	ProjectID       string                        `gorm:"column:project_id;type:varchar(255);not null"`
	ClusterID       string                        `gorm:"column:cluster_id;type:varchar(255);not null;index:idx_cluster_id"`
	ProxyEndpoint   string                        `gorm:"column:proxy_endpoint;type:varchar(1024);null"`
	ClusterStatusID uint64                        `gorm:"column:cluster_status_id;type:bigint(20) NULL DEFAULT NULL"`
	CreatedBy       string                        `gorm:"column:created_by;type:varchar(255);not null"`
	Filter          string                        `gorm:"column:filter;type:varchar(255);null"`
	MeteringStatus  constant.ExportMeteringStatus `gorm:"column:metering_status;type:enum('running','pending','succeed');default:pending"`
	CloudProvider   string                        `gorm:"column:cloud_provider;type:varchar(255);not null"`
	Region          string                        `gorm:"column:region;type:varchar(255);not null"`
	Kubernetes      string                        `gorm:"column:kubernetes;type:varchar(255);not null"`
	CompletedAt     *time.Time                    `gorm:"column:completed_at;type:timestamp;null"`
	Reason          string                        `gorm:"column:reason;null"`
	Compression     constant.Compression          `gorm:"column:compression;type:enum('none','gzip','zstd','snappy');default:'gzip'"`
	MeteringTimes   uint32                        `gorm:"column:metering_times;type:int;not null;default:0"`
	SnapshotTime    *time.Time                    `gorm:"column:snapshot_time;type:timestamp;null"`
	ExpiredAt       *time.Time                    `gorm:"column:expired_at;type:timestamp;null"`
	SQL             string                        `gorm:"column:sql;type:text;null"`
	Where           string                        `gorm:"column:where;type:text;null"`
	Partitions      []string                      `gorm:"column:partitions;type:json;serializer:json;null"`
	TableFilters    []byte                        `gorm:"column:table_filters;type:blob;null"`
	ColumnSelectors []ColumnSelector              `gorm:"column:column_selectors;type:json;serializer:json;null"`
	Name            string                        `gorm:"column:name;type:varchar(255);not null"`
	GCSURI          string                        `gorm:"column:gcs_uri;type:varchar(1024);null"`
	AzBlobURI       string                        `gorm:"column:az_blob_uri;type:varchar(1024);null"`
	ParquetFormat   datatypes.JSON                `gorm:"column:parquet_format;type:json;null"`
	OSSURI          string                        `gorm:"column:oss_uri;type:varchar(1024);null"`
	OSSAccessKeyID  string                        `gorm:"column:oss_access_key_id;type:varchar(255);null"`
	// CreatePayload is encrypted before it is persisted.
	CreatePayload string `gorm:"column:encrypted_create_payload;type:text"                                                  json:"-"`
}

func (Export) TableName() string {
	return "exports"
}

func (e *Export) GetKubernetes() string {
	if e.Kubernetes == "" {
		return DefaultKubernetesName(e.Region)
	}
	return e.Kubernetes
}

func (e *Export) GetCloudProvider() string {
	if e.CloudProvider == "" {
		return DefaultCloudProvider
	}
	return e.CloudProvider
}

type ExportFilter struct {
	TenantID         string
	ClusterID        string
	PageSize         *int32
	Offset           *int64
	State            constant.ExportState
	States           []constant.ExportState
	HasClusterStatus *bool
	IncludeDeleted   bool
	CreatedAtAfter   *time.Time
	OrderBy          string
	NameLike         string
}

type ExportStateCount struct {
	State constant.ExportState
	Count int
}
