package repo

import (
	"database/sql"
	"fmt"

	"github.com/jobs-scraper/internal/pkg/domain"
	"github.com/lib/pq"
)

type JobAnalysisResultRepository struct {
	db *sql.DB
}

func NewJobAnalysisResultRepository(db *sql.DB) *JobAnalysisResultRepository {
	return &JobAnalysisResultRepository{db: db}
}

func (r *JobAnalysisResultRepository) SaveAnalysisResult(result *domain.JobAnalysisResult) error {
	query := `
		INSERT INTO job_analysis_results (job_id, analysis_result, match_score, key_skills, missing_skills, recommendations)
		VALUES ($1, $2, $3, $4, $5, $6)
		RETURNING id, analyzed_at
	`
	
	err := r.db.QueryRow(
		query,
		result.JobID,
		result.AnalysisResult,
		result.MatchScore,
		pq.Array(result.KeySkills),
		pq.Array(result.MissingSkills),
		result.Recommendations,
	).Scan(&result.ID, &result.AnalyzedAt)
	
	if err != nil {
		return fmt.Errorf("error saving job analysis result: %v", err)
	}
	
	return nil
}

func (r *JobAnalysisResultRepository) GetAnalysisResultByJobID(jobID int64) (*domain.JobAnalysisResult, error) {
	query := `
		SELECT id, job_id, analysis_result, match_score, key_skills, missing_skills, recommendations, analyzed_at
		FROM job_analysis_results
		WHERE job_id = $1
		ORDER BY analyzed_at DESC
		LIMIT 1
	`
	
	var result domain.JobAnalysisResult
	err := r.db.QueryRow(query, jobID).Scan(
		&result.ID,
		&result.JobID,
		&result.AnalysisResult,
		&result.MatchScore,
		pq.Array(&result.KeySkills),
		pq.Array(&result.MissingSkills),
		&result.Recommendations,
		&result.AnalyzedAt,
	)
	
	if err == sql.ErrNoRows {
		return nil, fmt.Errorf("no analysis result found for job ID %d", jobID)
	}
	
	if err != nil {
		return nil, fmt.Errorf("error querying job analysis result: %v", err)
	}
	
	return &result, nil
}

func (r *JobAnalysisResultRepository) GetAllAnalysisResults() ([]domain.JobAnalysisResult, error) {
	query := `
		SELECT id, job_id, analysis_result, match_score, key_skills, missing_skills, recommendations, analyzed_at
		FROM job_analysis_results
		ORDER BY analyzed_at DESC
	`
	
	rows, err := r.db.Query(query)
	if err != nil {
		return nil, fmt.Errorf("error querying job analysis results: %v", err)
	}
	defer rows.Close()
	
	var results []domain.JobAnalysisResult
	for rows.Next() {
		var result domain.JobAnalysisResult
		err := rows.Scan(
			&result.ID,
			&result.JobID,
			&result.AnalysisResult,
			&result.MatchScore,
			pq.Array(&result.KeySkills),
			pq.Array(&result.MissingSkills),
			&result.Recommendations,
			&result.AnalyzedAt,
		)
		if err != nil {
			return nil, fmt.Errorf("error scanning job analysis result: %v", err)
		}
		results = append(results, result)
	}
	
	if err := rows.Err(); err != nil {
		return nil, fmt.Errorf("error iterating over job analysis result rows: %v", err)
	}
	
	return results, nil
}

func (r *JobAnalysisResultRepository) GetAnalysisResultsByMatchScore(minScore int) ([]domain.JobAnalysisResult, error) {
	query := `
		SELECT id, job_id, analysis_result, match_score, key_skills, missing_skills, recommendations, analyzed_at
		FROM job_analysis_results
		WHERE match_score >= $1
		ORDER BY match_score DESC, analyzed_at DESC
	`
	
	rows, err := r.db.Query(query, minScore)
	if err != nil {
		return nil, fmt.Errorf("error querying job analysis results by match score: %v", err)
	}
	defer rows.Close()
	
	var results []domain.JobAnalysisResult
	for rows.Next() {
		var result domain.JobAnalysisResult
		err := rows.Scan(
			&result.ID,
			&result.JobID,
			&result.AnalysisResult,
			&result.MatchScore,
			pq.Array(&result.KeySkills),
			pq.Array(&result.MissingSkills),
			&result.Recommendations,
			&result.AnalyzedAt,
		)
		if err != nil {
			return nil, fmt.Errorf("error scanning job analysis result: %v", err)
		}
		results = append(results, result)
	}
	
	if err := rows.Err(); err != nil {
		return nil, fmt.Errorf("error iterating over job analysis result rows: %v", err)
	}
	
	return results, nil
}
