package worker

import (
	"context"
	"encoding/json"
	"errors"
	"kra/internal/biz/system"
	taskbiz "kra/internal/biz/task"

	"kra/internal/config"
	taskmodule "kra/internal/modules/task"
	platformtask "kra/pkg/task"
)

// TaskMethods owns the dependency-bearing built-in task handlers.
type TaskMethods struct {
	tasks       *taskbiz.TaskUsecase
	maintenance *system.MaintenanceUsecase
	media       *system.MediaUsecase
	runtime     *config.Store
}

func NewTaskMethods(tasks *taskbiz.TaskUsecase, maintenance *system.MaintenanceUsecase, media *system.MediaUsecase, runtime *config.Store) *TaskMethods {
	return &TaskMethods{tasks: tasks, maintenance: maintenance, media: media, runtime: runtime}
}

func (methods *TaskMethods) RegisterTasks(registry *platformtask.Registry) {
	if methods == nil || registry == nil {
		return
	}
	descriptions := map[string]string{}
	for _, task := range taskmodule.TimedTasks() {
		descriptions[task.MethodName] = task.Description
	}
	registry.Register(platformtask.Method{
		Name: taskbiz.TaskMethodClearDB, Description: descriptions[taskbiz.TaskMethodClearDB], Run: func(ctx context.Context, _ json.RawMessage) error {
			if ctx == nil {
				ctx = context.Background()
			}
			if methods.maintenance == nil || methods.tasks == nil {
				return errors.New("ClearDB 任务依赖未就绪")
			}
			if err := methods.maintenance.CleanupExpired(ctx); err != nil {
				return err
			}
			return methods.tasks.CleanupTaskLogs(ctx)
		},
	})
	registry.Register(platformtask.Method{
		Name: taskbiz.TaskMethodUploads, Description: descriptions[taskbiz.TaskMethodUploads], Run: func(ctx context.Context, _ json.RawMessage) error {
			if ctx == nil {
				ctx = context.Background()
			}
			if methods.media == nil {
				return errors.New("CleanStaleUploads 任务依赖未就绪")
			}
			ttl := 24
			var admin *config.Admin
			if methods.runtime != nil {
				if snapshot := methods.runtime.Snapshot(); snapshot != nil {
					admin = snapshot.Admin
				}
			}
			if admin != nil && admin.Media != nil && admin.Media.SessionTTL > 0 {
				ttl = admin.Media.SessionTTL
			}
			return methods.media.CleanupStale(ctx, ttl)
		},
	})
}
