package task

import (
	"context"
	"fmt"
	"time"

	"git.huangwc.com/pig/pig-farm-controller/internal/domain/plan"
	"git.huangwc.com/pig/pig-farm-controller/internal/infra/logs"
	"git.huangwc.com/pig/pig-farm-controller/internal/infra/models"
)

type DelayTaskParams struct {
	DelayDuration float32 `json:"delay_duration"`
}

// DelayTask 是一个用于模拟延迟的 Task 实现
type DelayTask struct {
	ctx           context.Context
	executionTask *models.TaskExecutionLog
	duration      time.Duration
}

func NewDelayTask(ctx context.Context, executionTask *models.TaskExecutionLog) plan.Task {
	return &DelayTask{
		ctx:           ctx,
		executionTask: executionTask,
	}
}

// Execute 执行延迟任务，等待指定的时间
func (d *DelayTask) Execute(ctx context.Context) error {
	taskCtx, logger := logs.Trace(ctx, d.ctx, "Execute")
	if err := d.parseParameters(taskCtx); err != nil {
		return err
	}

	logger.Infof("任务 %v: 开始延迟 %v...", d.executionTask.TaskID, d.duration)
	time.Sleep(d.duration)
	logger.Infof("任务 %v: 延迟结束。", d.executionTask.TaskID)
	return nil
}

func (d *DelayTask) parseParameters(ctx context.Context) error {
	logger := logs.TraceLogger(ctx, d.ctx, "parseParameters")
	if d.executionTask.Task.Parameters == nil {
		logger.Errorf("任务 %v: 缺少参数", d.executionTask.TaskID)
		return fmt.Errorf("任务 %v: 参数不全", d.executionTask.TaskID)
	}

	var params DelayTaskParams
	err := d.executionTask.Task.ParseParameters(&params)
	if err != nil {
		logger.Errorf("任务 %v: 解析参数失败: %v", d.executionTask.TaskID, err)
		return fmt.Errorf("任务 %v: 解析参数失败: %v", d.executionTask.TaskID, err)
	}

	if params.DelayDuration <= 0 {
		logger.Errorf("任务 %v: 参数 delay_duration 缺失或无效 (必须大于0)", d.executionTask.TaskID)
		return fmt.Errorf("任务 %v: 参数 delay_duration 缺失或无效 (必须大于0)", d.executionTask.TaskID)
	}

	d.duration = time.Duration(params.DelayDuration) * time.Second

	return nil
}

func (d *DelayTask) OnFailure(ctx context.Context, executeErr error) {
	logger := logs.TraceLogger(ctx, d.ctx, "OnFailure")
	logger.Errorf("任务 %v: 执行失败: %v", d.executionTask.TaskID, executeErr)
}

func (d *DelayTask) ResolveDeviceIDs(ctx context.Context) ([]uint32, error) {
	return []uint32{}, nil
}
