package roadmap

import (
	"context"
	"encoding/json"
	"time"

	"github.com/google/uuid"
	"github.com/jackc/pgx/v5"
)

// ============================================================================
// Import Job Operations
// ============================================================================

// CreateImportJob creates a new import job
func (s *Store) CreateImportJob(ctx context.Context, job *ImportJob) error {
	job.ID = uuid.New()
	job.CreatedAt = time.Now().UTC()
	job.UpdatedAt = job.CreatedAt
	if job.Status == "" {
		job.Status = "pending"
	}

	parsedItems, _ := json.Marshal(job.ParsedItems)

	_, err := s.pool.Exec(ctx, `
		INSERT INTO roadmap_import_jobs (
			id, tenant_id, roadmap_id,
			filename, format, file_size, content_type,
			status, error_message,
			total_rows, valid_rows, invalid_rows, imported_items,
			parsed_items,
			created_at, updated_at, completed_at, created_by
		) VALUES (
			$1, $2, $3,
			$4, $5, $6, $7,
			$8, $9,
			$10, $11, $12, $13,
			$14,
			$15, $16, $17, $18
		)
	`,
		job.ID, job.TenantID, job.RoadmapID,
		job.Filename, string(job.Format), job.FileSize, job.ContentType,
		job.Status, job.ErrorMessage,
		job.TotalRows, job.ValidRows, job.InvalidRows, job.ImportedItems,
		parsedItems,
		job.CreatedAt, job.UpdatedAt, job.CompletedAt, job.CreatedBy,
	)

	return err
}

// GetImportJob retrieves an import job by ID
func (s *Store) GetImportJob(ctx context.Context, id uuid.UUID) (*ImportJob, error) {
	var job ImportJob
	var format string
	var parsedItems []byte

	err := s.pool.QueryRow(ctx, `
		SELECT
			id, tenant_id, roadmap_id,
			filename, format, file_size, content_type,
			status, error_message,
			total_rows, valid_rows, invalid_rows, imported_items,
			parsed_items,
			created_at, updated_at, completed_at, created_by
		FROM roadmap_import_jobs WHERE id = $1
	`, id).Scan(
		&job.ID, &job.TenantID, &job.RoadmapID,
		&job.Filename, &format, &job.FileSize, &job.ContentType,
		&job.Status, &job.ErrorMessage,
		&job.TotalRows, &job.ValidRows, &job.InvalidRows, &job.ImportedItems,
		&parsedItems,
		&job.CreatedAt, &job.UpdatedAt, &job.CompletedAt, &job.CreatedBy,
	)

	if err == pgx.ErrNoRows {
		return nil, nil
	}
	if err != nil {
		return nil, err
	}

	job.Format = ImportFormat(format)
	json.Unmarshal(parsedItems, &job.ParsedItems)

	return &job, nil
}

// UpdateImportJob updates an import job
func (s *Store) UpdateImportJob(ctx context.Context, job *ImportJob) error {
	job.UpdatedAt = time.Now().UTC()

	parsedItems, _ := json.Marshal(job.ParsedItems)

	_, err := s.pool.Exec(ctx, `
		UPDATE roadmap_import_jobs SET
			roadmap_id = $2,
			status = $3, error_message = $4,
			total_rows = $5, valid_rows = $6, invalid_rows = $7, imported_items = $8,
			parsed_items = $9,
			updated_at = $10, completed_at = $11
		WHERE id = $1
	`,
		job.ID, job.RoadmapID,
		job.Status, job.ErrorMessage,
		job.TotalRows, job.ValidRows, job.InvalidRows, job.ImportedItems,
		parsedItems,
		job.UpdatedAt, job.CompletedAt,
	)

	return err
}

// ============================================================================
// Statistics
// ============================================================================

// GetRoadmapStats returns statistics for a roadmap
func (s *Store) GetRoadmapStats(ctx context.Context, roadmapID uuid.UUID) (*RoadmapStats, error) {
	stats := &RoadmapStats{
		ByStatus:     make(map[string]int),
		ByPriority:   make(map[string]int),
		ByCategory:   make(map[string]int),
		ByDepartment: make(map[string]int),
	}

	// Total count
	s.pool.QueryRow(ctx,
		"SELECT COUNT(*) FROM roadmap_items WHERE roadmap_id = $1",
		roadmapID).Scan(&stats.TotalItems)

	// By status
	rows, err := s.pool.Query(ctx,
		"SELECT status, COUNT(*) FROM roadmap_items WHERE roadmap_id = $1 GROUP BY status",
		roadmapID)
	if err == nil {
		defer rows.Close()
		for rows.Next() {
			var status string
			var count int
			rows.Scan(&status, &count)
			stats.ByStatus[status] = count
		}
	}

	// By priority
	rows, err = s.pool.Query(ctx,
		"SELECT priority, COUNT(*) FROM roadmap_items WHERE roadmap_id = $1 GROUP BY priority",
		roadmapID)
	if err == nil {
		defer rows.Close()
		for rows.Next() {
			var priority string
			var count int
			rows.Scan(&priority, &count)
			stats.ByPriority[priority] = count
		}
	}

	// By category
	rows, err = s.pool.Query(ctx,
		"SELECT category, COUNT(*) FROM roadmap_items WHERE roadmap_id = $1 GROUP BY category",
		roadmapID)
	if err == nil {
		defer rows.Close()
		for rows.Next() {
			var category string
			var count int
			rows.Scan(&category, &count)
			stats.ByCategory[category] = count
		}
	}

	// By department
	rows, err = s.pool.Query(ctx,
		"SELECT COALESCE(department, 'Unassigned'), COUNT(*) FROM roadmap_items WHERE roadmap_id = $1 GROUP BY department",
		roadmapID)
	if err == nil {
		defer rows.Close()
		for rows.Next() {
			var dept string
			var count int
			rows.Scan(&dept, &count)
			stats.ByDepartment[dept] = count
		}
	}

	// Overdue items
	s.pool.QueryRow(ctx,
		"SELECT COUNT(*) FROM roadmap_items WHERE roadmap_id = $1 AND planned_end < NOW() AND status NOT IN ('COMPLETED', 'DEFERRED')",
		roadmapID).Scan(&stats.OverdueItems)

	// Upcoming items (next 7 days)
	s.pool.QueryRow(ctx,
		"SELECT COUNT(*) FROM roadmap_items WHERE roadmap_id = $1 AND planned_end BETWEEN NOW() AND NOW() + INTERVAL '7 days' AND status NOT IN ('COMPLETED', 'DEFERRED')",
		roadmapID).Scan(&stats.UpcomingItems)

	// Total effort
	s.pool.QueryRow(ctx,
		"SELECT COALESCE(SUM(effort_days), 0) FROM roadmap_items WHERE roadmap_id = $1",
		roadmapID).Scan(&stats.TotalEffortDays)

	// Progress
	completedCount := stats.ByStatus[string(ItemStatusCompleted)]
	if stats.TotalItems > 0 {
		stats.Progress = (completedCount * 100) / stats.TotalItems
	}

	return stats, nil
}
