package services

import (
	"context"

	"github.com/google/uuid"
	"go.uber.org/zap"
)

// JobEnqueuer interface pour éviter le cycle d'importation
// BE-SVC-003: Implement background job queue
type JobEnqueuer interface {
	EnqueueEmailJob(to, subject, body string)
	EnqueueEmailJobWithTemplate(to, subject, templateName string, templateData map[string]interface{})
	EnqueueThumbnailJob(inputPath, outputPath string, width, height int)
	EnqueueAnalyticsJob(eventName string, userID *uuid.UUID, payload map[string]interface{})
}

// JobService gère les jobs en arrière-plan
// BE-SVC-003: Implement background job queue
type JobService struct {
	logger      *zap.Logger
	jobEnqueuer JobEnqueuer
}

// Job types
const (
	TypeEmailSend         = "email:send"
	TypeThumbnailGenerate = "thumbnail:generate"
	TypeAnalyticsProcess  = "analytics:process"
	TypeWebhookDelivery   = "webhook:delivery"
)

// EmailPayload représente les données pour l'envoi d'email
type EmailPayload struct {
	To      string
	Subject string
	Body    string
}

// ThumbnailPayload représente les données pour la génération de miniatures
type ThumbnailPayload struct {
	TrackID  uint
	FileID   string
	FilePath string
}

// NewJobService crée un nouveau service de jobs
func NewJobService(logger *zap.Logger) *JobService {
	return &JobService{
		logger: logger,
	}
}

// SetJobEnqueuer définit le JobEnqueuer pour le service
// BE-SVC-003: Connect JobService to JobWorker
func (s *JobService) SetJobEnqueuer(jobEnqueuer JobEnqueuer) {
	s.jobEnqueuer = jobEnqueuer
}

// EnqueueEmail enfile un job d'envoi d'email
// BE-SVC-003: Implement background job queue for email sending
func (s *JobService) EnqueueEmail(ctx context.Context, payload *EmailPayload) error {
	if s.jobEnqueuer == nil {
		s.logger.Warn("JobEnqueuer not set, email job not enqueued",
			zap.String("to", payload.To),
			zap.String("subject", payload.Subject))
		return nil // Fail gracefully
	}

	s.logger.Info("Email job enqueued",
		zap.String("to", payload.To),
		zap.String("subject", payload.Subject))

	// Enqueue via JobEnqueuer (JobWorker)
	s.jobEnqueuer.EnqueueEmailJob(payload.To, payload.Subject, payload.Body)
	return nil
}

// EnqueueThumbnail enfile un job de génération de miniature
// BE-SVC-003: Implement background job queue for thumbnail generation
func (s *JobService) EnqueueThumbnail(ctx context.Context, payload *ThumbnailPayload) error {
	if s.jobEnqueuer == nil {
		s.logger.Warn("JobEnqueuer not set, thumbnail job not enqueued",
			zap.Uint("track_id", payload.TrackID))
		return nil // Fail gracefully
	}

	s.logger.Info("Thumbnail job enqueued",
		zap.Uint("track_id", payload.TrackID))

	// Enqueue via JobEnqueuer (assuming default dimensions)
	// Note: ThumbnailPayload uses uint for TrackID, but we need file paths
	// This is a simplified version - actual implementation may need adjustment
	if payload.FilePath != "" {
		// Default thumbnail size
		s.jobEnqueuer.EnqueueThumbnailJob(payload.FilePath, payload.FilePath+".thumb", 300, 300)
	}
	return nil
}
