package infra

import (
	"database/sql"
	"fmt"
)

// JobQueueCreate creates (or verifies) the jobs table and required indices in
// the given SQLite database, activates WAL mode, and returns a ready *JobQueue.
// tableName is typically "jobs" but can be any valid SQLite identifier.
//
// Schema created:
//
//	CREATE TABLE IF NOT EXISTS jobs (
//	    id TEXT PRIMARY KEY,
//	    type TEXT NOT NULL,
//	    payload TEXT NOT NULL DEFAULT '{}',
//	    status TEXT NOT NULL DEFAULT 'pending',
//	    priority INTEGER NOT NULL DEFAULT 0,
//	    attempts INTEGER NOT NULL DEFAULT 0,
//	    max_attempts INTEGER NOT NULL DEFAULT 3,
//	    scheduled_at TEXT NOT NULL,
//	    started_at TEXT,
//	    completed_at TEXT,
//	    result TEXT,
//	    error TEXT,
//	    created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now'))
//	);
func JobQueueCreate(db *sql.DB, tableName string) (*JobQueue, error) {
	if db == nil {
		return nil, fmt.Errorf("job_queue_create: db must not be nil")
	}
	if tableName == "" {
		tableName = "jobs"
	}

	// Enable WAL mode for concurrent read/write access.
	if _, err := db.Exec(`PRAGMA journal_mode=WAL`); err != nil {
		return nil, fmt.Errorf("job_queue_create: enable WAL: %w", err)
	}

	schema := fmt.Sprintf(`
CREATE TABLE IF NOT EXISTS %s (
    id TEXT PRIMARY KEY,
    type TEXT NOT NULL,
    payload TEXT NOT NULL DEFAULT '{}',
    status TEXT NOT NULL DEFAULT 'pending',
    priority INTEGER NOT NULL DEFAULT 0,
    attempts INTEGER NOT NULL DEFAULT 0,
    max_attempts INTEGER NOT NULL DEFAULT 3,
    scheduled_at TEXT NOT NULL,
    started_at TEXT,
    completed_at TEXT,
    result TEXT,
    error TEXT,
    created_at TEXT NOT NULL DEFAULT (strftime('%%Y-%%m-%%dT%%H:%%M:%%SZ', 'now'))
);
CREATE INDEX IF NOT EXISTS idx_%s_dequeue ON %s (status, priority DESC, scheduled_at ASC) WHERE status = 'pending';
CREATE INDEX IF NOT EXISTS idx_%s_status ON %s (status);
CREATE INDEX IF NOT EXISTS idx_%s_type ON %s (type);
`, tableName,
		tableName, tableName,
		tableName, tableName,
		tableName, tableName,
	)

	if _, err := db.Exec(schema); err != nil {
		return nil, fmt.Errorf("job_queue_create: create schema: %w", err)
	}

	return &JobQueue{DB: db, TableName: tableName}, nil
}
