package cron

import (
	"database/sql"
	"encoding/json"
	"log"
	"os"

	"github.com/jobs-scraper/infrastructure/rabbitmq"
	"github.com/jobs-scraper/internal/domain"
	"github.com/jobs-scraper/internal/repo"
	"github.com/jobs-scraper/internal/services"
)

type JobAnalyzer struct {
	db                 *sql.DB
	jobRepo            *repo.JobRepository
	jobDescriptionRepo *repo.JobDescriptionRepository
	openRouterService  services.OpenRouterService
	rmq                *rabbitmq.RabbitMQClient
}

func NewJobAnalyzer(db *sql.DB) *JobAnalyzer {
	apiKey := os.Getenv("OPENROUTER_API_KEY")
	model := os.Getenv("CV_AI_MODEL")

	jobRepo := repo.NewJobRepository(db)
	jobDescriptionRepo := repo.NewJobDescriptionRepository(db)
	openRouterService := services.NewOpenRouterService(model, apiKey)

	rmq, err := rabbitmq.NewRabbitMQClient()
	if err != nil {
		log.Printf("Warning: Failed to create RabbitMQ client: %v", err)
	}

	return &JobAnalyzer{
		db:                 db,
		jobRepo:            jobRepo,
		jobDescriptionRepo: jobDescriptionRepo,
		openRouterService:  openRouterService,
		rmq:                rmq,
	}
}

func (ja *JobAnalyzer) AnalyzeJobs() error {
	// Get jobs that need analysis (status = created)
	jobs, err := ja.jobRepo.GetJobsByStatus(domain.JobStatusCreated)
	if err != nil {
		return err
	}

	log.Printf("Found %d jobs to analyze", len(jobs))

	// Read CV file
	cv, err := os.ReadFile("cv.txt")
	if err != nil {
		return err
	}

	for _, job := range jobs {
		if err := ja.analyzeJob(job, string(cv)); err != nil {
			log.Printf("Error analyzing job %d: %v", job.ID, err)
			// Update job status to error
			if updateErr := ja.jobRepo.UpdateJobStatus(job.ID, domain.JobStatusError); updateErr != nil {
				log.Printf("Error updating job status to error: %v", updateErr)
			}
			continue
		}

		// Update job status to analyzed
		if err := ja.jobRepo.UpdateJobStatus(job.ID, domain.JobStatusAnalyzed); err != nil {
			log.Printf("Error updating job status to analyzed: %v", err)
		}

		log.Printf("Successfully analyzed job %d", job.ID)
	}

	return nil
}

func (ja *JobAnalyzer) analyzeJob(job domain.Job, cv string) error {
	// Get job description
	jobDescription, jobCriteria, err := ja.jobDescriptionRepo.GetJobDescriptionByJobID(job.ID)
	if err != nil {
		return err
	}

	// Analyze job with CV
	result, err := ja.openRouterService.AnalyzeJobDescription(cv, domain.JobDescription{
		JobID:       job.ID,
		Description: jobDescription,
		Criteria:    jobCriteria,
	})

	if err != nil {
		return err
	}

	log.Printf("Analysis result for job %d: Recommendation=%s, Score=%d", job.ID, result.Recommendation, result.ConfidenceScore)

	// Publish CV analysis message to RabbitMQ if available
	if ja.rmq != nil {
		message := rabbitmq.CvAnalyzeMessage{
			JobID: job.ID,
		}
		
		if err := ja.publishCvAnalysisMessage(message); err != nil {
			log.Printf("Warning: Failed to publish CV analysis message: %v", err)
		}
	}

	return nil
}

func (ja *JobAnalyzer) publishCvAnalysisMessage(message rabbitmq.CvAnalyzeMessage) error {
	data, err := json.Marshal(message)
	if err != nil {
		return err
	}

	return ja.rmq.Publish(rabbitmq.CvAnalyzeQueue, rabbitmq.CvAnalyzeExchange, data)
}
