package jobs

import (
	"context"
	"log"

	"github.com/hibiken/asynq"
	"github.com/redis/go-redis/v9"
)

// QueueClient wraps asynq client for enqueueing jobs
type QueueClient struct {
	client *asynq.Client
}

// NewQueueClient creates a new queue client
func NewQueueClient(redisAddr, redisPassword string, redisDB int) (*QueueClient, error) {
	redisOpt := asynq.RedisClientOpt{
		Addr:     redisAddr,
		Password: redisPassword,
		DB:       redisDB,
	}
	
	client := asynq.NewClient(redisOpt)
	
	// Test connection
	rdb := redis.NewClient(&redis.Options{
		Addr:     redisAddr,
		Password: redisPassword,
		DB:       redisDB,
	})
	defer rdb.Close()
	
	if err := rdb.Ping(context.Background()).Err(); err != nil {
		return nil, err
	}
	
	log.Printf("Queue client connected to Redis at %s", redisAddr)
	
	return &QueueClient{
		client: client,
	}, nil
}

// EnqueueSendOTPEmail enqueues a send OTP email job
func (q *QueueClient) EnqueueSendOTPEmail(email, otp string) error {
	task, err := NewSendOTPEmailTask(email, otp)
	if err != nil {
		return err
	}
	
	info, err := q.client.Enqueue(task)
	if err != nil {
		return err
	}
	
	log.Printf("Enqueued email job: ID=%s, Queue=%s, Type=%s", info.ID, info.Queue, info.Type)
	return nil
}

// Close closes the queue client
func (q *QueueClient) Close() error {
	return q.client.Close()
}

// NewQueueServer creates a new queue server for processing jobs
func NewQueueServer(redisAddr, redisPassword string, redisDB int) *asynq.Server {
	redisOpt := asynq.RedisClientOpt{
		Addr:     redisAddr,
		Password: redisPassword,
		DB:       redisDB,
	}
	
	return asynq.NewServer(
		redisOpt,
		asynq.Config{
			// Number of concurrent workers
			Concurrency: 10,
			// Queues to process with priority
			Queues: map[string]int{
				"emails": 10, // High priority for emails
				"default": 5,
			},
			// Error handler
			ErrorHandler: asynq.ErrorHandlerFunc(func(ctx context.Context, task *asynq.Task, err error) {
				log.Printf("Job error: type=%s, payload=%s, error=%v", task.Type(), string(task.Payload()), err)
			}),
			// Logger
			Logger: &queueLogger{},
		},
	)
}

// queueLogger implements asynq.Logger interface
type queueLogger struct{}

func (l *queueLogger) Debug(args ...interface{}) {
	log.Println("[DEBUG]", args)
}

func (l *queueLogger) Info(args ...interface{}) {
	log.Println("[INFO]", args)
}

func (l *queueLogger) Warn(args ...interface{}) {
	log.Println("[WARN]", args)
}

func (l *queueLogger) Error(args ...interface{}) {
	log.Println("[ERROR]", args)
}

func (l *queueLogger) Fatal(args ...interface{}) {
	log.Fatal(args...)
}

