package repository

import (
	"context"
	"time"

	"code.cubecraftcreations.com/CubeCraft-Creations/Control-Center/go-backend/internal/models"
	"github.com/jackc/pgx/v5"
	"github.com/jackc/pgx/v5/pgxpool"
)

// TaskRepository provides PostgreSQL-backed CRUD for task_logs.
type TaskRepository struct {
	pool *pgxpool.Pool
}

// NewTaskRepository returns a repository wired to the given connection pool.
func NewTaskRepository(pool *pgxpool.Pool) *TaskRepository {
	return &TaskRepository{pool: pool}
}

// Create inserts a new task into the task_logs table.
func (r *TaskRepository) Create(ctx context.Context, t models.Task) (models.Task, error) {
	now := time.Now().UTC()
	if t.CreatedAt.IsZero() {
		t.CreatedAt = now
	}
	if t.UpdatedAt.IsZero() {
		t.UpdatedAt = now
	}

	err := r.pool.QueryRow(ctx, `
		INSERT INTO task_logs (agent_id, task, status, started_at)
		VALUES ($1, $2, $3, $4)
		RETURNING id, agent_id, task, status, started_at, completed_at, error_message
	`, t.AgentID, t.Title, string(t.Status), t.CreatedAt).Scan(
		&t.ID, &t.AgentID, &t.Title, &t.Status, &t.CreatedAt,
		nil, nil,
	)
	if err != nil {
		return t, err
	}

	// Rebuild the Description since task_logs only stores the title as "task".
	t.Description = t.Title
	return t, nil
}

// ListRecent returns the most recent tasks, newest first.
func (r *TaskRepository) ListRecent(ctx context.Context) ([]models.Task, error) {
	rows, err := r.pool.Query(ctx, `
		SELECT id, agent_id, task, status, started_at, completed_at, error_message
		FROM task_logs
		ORDER BY started_at DESC
	`)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	return pgx.CollectRows(rows, func(row pgx.CollectableRow) (models.Task, error) {
		var t models.Task
		var completedAt *time.Time
		var errMsg *string

		if err := row.Scan(&t.ID, &t.AgentID, &t.Title, &t.Status,
			&t.CreatedAt, &completedAt, &errMsg); err != nil {
			return t, err
		}

		t.Description = t.Title
		t.UpdatedAt = t.CreatedAt
		if completedAt != nil {
			t.UpdatedAt = *completedAt
		}
		return t, nil
	})
}

// Count returns the total number of tasks.
func (r *TaskRepository) Count(ctx context.Context) (int, error) {
	var n int
	err := r.pool.QueryRow(ctx, `SELECT COUNT(*) FROM task_logs`).Scan(&n)
	return n, err
}
