package usecase

import (
	"context"

	"haixun-backend/internal/model/job/domain/entity"
	"haixun-backend/internal/model/job/domain/repository"
)

type CreateRunRequest struct {
	TemplateType string
	Scope        string
	ScopeID      string
	TenantID     string
	OwnerUID     string
	Payload      map[string]any
}

type CancelRunRequest struct {
	JobID  string
	Reason string
}

type ClaimNextRequest struct {
	WorkerType string
	WorkerID   string
}

type UpdateProgressRequest struct {
	JobID      string
	WorkerID   string
	Phase      string
	Summary    string
	Percentage int
	Steps      []entity.StepProgress
}

type CompleteRunRequest struct {
	JobID    string
	WorkerID string
	Result   map[string]any
}

type FailRunRequest struct {
	JobID    string
	WorkerID string
	Error    string
	Phase    string
}

type AcknowledgeCancelRequest struct {
	JobID    string
	WorkerID string
}

type UpsertTemplateRequest struct {
	Type              string
	Version           int
	Name              string
	Description       string
	Enabled           bool
	Repeatable        bool
	ConcurrencyPolicy string
	DedupeKeys        []string
	TimeoutSeconds    int
	CancelPolicy      entity.CancelPolicy
	RetryPolicy       entity.RetryPolicy
	Steps             []entity.TemplateStep
}

type CreateScheduleRequest struct {
	TemplateType    string
	Scope           string
	ScopeID         string
	Cron            string
	Timezone        string
	PayloadTemplate map[string]any
	Enabled         bool
}

type UpdateScheduleRequest struct {
	ID              string
	Cron            string
	Timezone        string
	PayloadTemplate map[string]any
	Enabled         *bool
}

type UseCase interface {
	ListTemplates(ctx context.Context) ([]*entity.Template, error)
	GetTemplate(ctx context.Context, templateType string) (*entity.Template, error)
	UpsertTemplate(ctx context.Context, req UpsertTemplateRequest) (*entity.Template, error)
	EnsureDemoTemplate(ctx context.Context) error
	EnsureStyle8DTemplate(ctx context.Context) error
	EnsureExpandGraphTemplate(ctx context.Context) error
	EnsurePlacementScanTemplate(ctx context.Context) error
	EnsureScanViralTemplate(ctx context.Context) error
	EnsureAnalyzeCopyMissionTemplate(ctx context.Context) error
	EnsureGenerateCopyMatrixTemplate(ctx context.Context) error
	EnsureGenerateCopyDraftTemplate(ctx context.Context) error

	CreateRun(ctx context.Context, req CreateRunRequest) (*entity.Run, error)
	GetRun(ctx context.Context, jobID string) (*entity.Run, error)
	ListRuns(ctx context.Context, filter repository.RunListFilter, page, pageSize int64) ([]*entity.Run, int64, int64, int64, int64, error)
	RequestCancel(ctx context.Context, req CancelRunRequest) (*entity.Run, error)
	RetryRun(ctx context.Context, jobID string) (*entity.Run, error)
	ListJobEvents(ctx context.Context, jobID string, limit int64) ([]*entity.Event, error)

	ClaimNext(ctx context.Context, req ClaimNextRequest) (*entity.Run, error)
	RefreshRunLock(ctx context.Context, jobID, workerID string, ttlSeconds int) error
	IsCancelRequested(ctx context.Context, jobID string) (bool, error)
	AcknowledgeCancel(ctx context.Context, req AcknowledgeCancelRequest) (*entity.Run, error)
	UpdateProgress(ctx context.Context, req UpdateProgressRequest) (*entity.Run, error)
	CompleteRun(ctx context.Context, req CompleteRunRequest) (*entity.Run, error)
	FailRun(ctx context.Context, req FailRunRequest) (*entity.Run, error)

	ListSchedules(ctx context.Context, scope, scopeID string, page, pageSize int64) ([]*entity.Schedule, int64, int64, int64, int64, error)
	GetSchedule(ctx context.Context, scheduleID string) (*entity.Schedule, error)
	CreateSchedule(ctx context.Context, req CreateScheduleRequest) (*entity.Schedule, error)
	UpdateSchedule(ctx context.Context, req UpdateScheduleRequest) (*entity.Schedule, error)
	EnableSchedule(ctx context.Context, scheduleID string) (*entity.Schedule, error)
	DisableSchedule(ctx context.Context, scheduleID string) (*entity.Schedule, error)
	DeleteSchedule(ctx context.Context, scheduleID string) error

	RunSchedulerTick(ctx context.Context, holder string) (int, error)
	RunMaintenance(ctx context.Context) (MaintenanceResult, error)
}

type MaintenanceResult struct {
	EnqueuedPending    int
	ReapedCancelGrace  int
	ReapedExpiredLocks int
}
