package queue

import (
	"time"
)

// JobStatus represents the current state of a sync job
type JobStatus string

const (
	JobStatusQueued     JobStatus = "queued"
	JobStatusProcessing JobStatus = "processing"
	JobStatusCompleted  JobStatus = "completed"
	JobStatusFailed     JobStatus = "failed"
	JobStatusDLQ        JobStatus = "dlq"
)

// JobType represents the type of sync job
type JobType string

const (
	JobTypeCloudAccountSync JobType = "cloud_account_sync"
	JobTypeGoDaddySync      JobType = "godaddy_sync"
	JobTypeAssetRefresh     JobType = "asset_refresh"
	JobTypeEventDriven      JobType = "event_driven"
)

// Priority levels for job processing
type JobPriority int

const (
	PriorityLow    JobPriority = 1
	PriorityNormal JobPriority = 5
	PriorityHigh   JobPriority = 10
)

// SyncJobPayload represents the data for a sync job in the queue
type SyncJobPayload struct {
	JobID          string      `json:"job_id"`
	SyncJobID      *uint64     `json:"sync_job_id,omitempty"` // Database sync_job record ID
	CloudAccountID uint64      `json:"cloud_account_id"`
	JobType        JobType     `json:"job_type"`
	Priority       JobPriority `json:"priority"`
	RetryCount     int         `json:"retry_count"`
	MaxRetries     int         `json:"max_retries"`
	EnqueuedAt     time.Time   `json:"enqueued_at"`
	ProcessingAt   *time.Time  `json:"processing_at,omitempty"`
	LastError      string      `json:"last_error,omitempty"`

	// Optional metadata
	TriggeredBy *uint64                `json:"triggered_by,omitempty"`
	EventSource string                 `json:"event_source,omitempty"`
	Metadata    map[string]interface{} `json:"metadata,omitempty"`
}

// ShouldRetry determines if the job should be retried based on retry count
func (j *SyncJobPayload) ShouldRetry() bool {
	return j.RetryCount < j.MaxRetries
}

// NextRetryDelay calculates the exponential backoff delay
func (j *SyncJobPayload) NextRetryDelay() time.Duration {
	// Exponential backoff: 1min, 2min, 4min, 8min...
	// But cap at 15 minutes
	delayMinutes := 1 << uint(j.RetryCount) // 2^retryCount
	if delayMinutes > 15 {
		delayMinutes = 15
	}
	return time.Duration(delayMinutes) * time.Minute
}

// IncrementRetry increments the retry counter and updates last error
func (j *SyncJobPayload) IncrementRetry(err error) {
	j.RetryCount++
	if err != nil {
		j.LastError = err.Error()
	}
}
