package taskqueuemocker

import (
	"context"
	"fmt"

	"github.com/tidbcloud/metrics-integration/pipeline/internal/otel_collector/extension/taskqueue"

	"go.opentelemetry.io/collector/component"
	"go.opentelemetry.io/collector/consumer"
	"go.opentelemetry.io/collector/pdata/pmetric"
	"go.uber.org/zap"
)

type tailtracerReceiver struct {
	host         component.Host
	cancel       context.CancelFunc
	logger       *zap.Logger
	nextConsumer consumer.Metrics
	config       *Config
}

func (tailtracerRcvr *tailtracerReceiver) Start(ctx context.Context, host component.Host) error {
	tailtracerRcvr.host = host
	ctx, tailtracerRcvr.cancel = context.WithCancel(ctx)

	tailtracerRcvr.logger.Info("get extension id", zap.Any("extension_id", tailtracerRcvr.config.TaskQueueExtID))
	taskQueueExt, ok := host.GetExtensions()[tailtracerRcvr.config.TaskQueueExtID]
	if !ok {
		return fmt.Errorf("failed to get taskqueue extension")
	}

	tq, ok := taskQueueExt.(taskqueue.TaskQueueExtension)
	if !ok {
		return fmt.Errorf("taskqueue extension is not of TaskQueue type")
	}

	//interval := time.Duration(15 * time.Second)
	go func() {
		for {
			select {
			case task := <-tq.Subscribe(ctx):
				// should wait until current time is after task.Timestamp
				// currentTime := time.Now()
				// if task.Timestamp.After(currentTime) {
				// 	timer := time.NewTimer(task.Timestamp.Sub(currentTime))
				// 	select {
				// 	case <-time.After(task.Timestamp.Sub(currentTime)):
				// 	case <-ctx.Done():
				// 		timer.Stop()
				// 		return
				// 	}
				// }
				taskCtx := taskqueue.InjectTaskIntoCtx(ctx, &task)

				// just a mock metric obj, used to trigger next step.
				pm := pmetric.NewMetrics()
				if err := tailtracerRcvr.nextConsumer.ConsumeMetrics(taskCtx, pm); err != nil {
					tailtracerRcvr.logger.Error("failed to consume metrics", zap.Error(err))
				}
			case <-ctx.Done():
				return
			}
		}
	}()

	return nil
}

func (tailtracerRcvr *tailtracerReceiver) Shutdown(ctx context.Context) error {
	if tailtracerRcvr.cancel != nil {
		tailtracerRcvr.cancel()
	}
	return nil
}
