package db

import (
	"database/sql"
	"time"

	"crypto-miner-server/internal/models"

	"github.com/google/uuid"
)

func (d *Database) ListFleetTasks() ([]*models.FleetTask, error) {
	rows, err := d.Query(`SELECT id, name, enabled, trigger, interval_hours, cron_time, action, command, target, created_at, updated_at FROM fleet_tasks ORDER BY created_at`)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	return scanFleetTasks(rows)
}

func (d *Database) GetFleetTask(id string) (*models.FleetTask, error) {
	row := d.QueryRow(`SELECT id, name, enabled, trigger, interval_hours, cron_time, action, command, target, created_at, updated_at FROM fleet_tasks WHERE id = ?`, id)
	return scanFleetTaskRow(row)
}

func (d *Database) UpsertFleetTask(t *models.FleetTask) error {
	if t.ID == "" {
		t.ID = uuid.New().String()
	}
	now := time.Now()
	if t.CreatedAt.IsZero() {
		t.CreatedAt = now
	}
	t.UpdatedAt = now
	_, err := d.Exec(`INSERT INTO fleet_tasks (id, name, enabled, trigger, interval_hours, cron_time, action, command, target, created_at, updated_at)
		VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
		ON CONFLICT(id) DO UPDATE SET
			name = excluded.name,
			enabled = excluded.enabled,
			trigger = excluded.trigger,
			interval_hours = excluded.interval_hours,
			cron_time = excluded.cron_time,
			action = excluded.action,
			command = excluded.command,
			target = excluded.target,
			updated_at = excluded.updated_at`,
		t.ID, t.Name, boolToInt(t.Enabled), t.Trigger, t.IntervalHours, t.CronTime, t.Action, t.Command, t.Target, t.CreatedAt, t.UpdatedAt,
	)
	return err
}

func (d *Database) DeleteFleetTask(id string) error {
	_, err := d.Exec(`DELETE FROM fleet_tasks WHERE id = ?`, id)
	return err
}

func (d *Database) RecordFleetTaskRun(agentID, taskID string) error {
	_, err := d.Exec(`INSERT INTO fleet_task_runs (agent_id, task_id, last_run_at) VALUES (?, ?, ?)
		ON CONFLICT(agent_id, task_id) DO UPDATE SET last_run_at = excluded.last_run_at`,
		agentID, taskID, time.Now(),
	)
	return err
}

func (d *Database) LastFleetTaskRun(agentID, taskID string) (time.Time, bool) {
	var ts time.Time
	err := d.QueryRow(`SELECT last_run_at FROM fleet_task_runs WHERE agent_id = ? AND task_id = ?`, agentID, taskID).Scan(&ts)
	if err != nil {
		return time.Time{}, false
	}
	return ts, true
}

func scanFleetTaskRow(row *sql.Row) (*models.FleetTask, error) {
	t := &models.FleetTask{}
	var enabled int
	err := row.Scan(&t.ID, &t.Name, &enabled, &t.Trigger, &t.IntervalHours, &t.CronTime, &t.Action, &t.Command, &t.Target, &t.CreatedAt, &t.UpdatedAt)
	if err != nil {
		return nil, err
	}
	t.Enabled = enabled == 1
	return t, nil
}

func scanFleetTasks(rows *sql.Rows) ([]*models.FleetTask, error) {
	var out []*models.FleetTask
	for rows.Next() {
		t := &models.FleetTask{}
		var enabled int
		if err := rows.Scan(&t.ID, &t.Name, &enabled, &t.Trigger, &t.IntervalHours, &t.CronTime, &t.Action, &t.Command, &t.Target, &t.CreatedAt, &t.UpdatedAt); err != nil {
			return nil, err
		}
		t.Enabled = enabled == 1
		out = append(out, t)
	}
	return out, rows.Err()
}
