package db

import (
	"encoding/json"
	"log"
	"strings"

	"crypto-miner-server/internal/models"
)

func decodeTags(raw string) []string {
	raw = strings.TrimSpace(raw)
	if raw == "" || raw == "[]" {
		return []string{}
	}
	var tags []string
	if err := json.Unmarshal([]byte(raw), &tags); err != nil {
		log.Printf("[db] decodeTags: corrupt tags JSON ignored (%v): %q", err, raw)
		return []string{}
	}
	return tags
}

func encodeTags(tags []string) string {
	if len(tags) == 0 {
		return "[]"
	}
	b, _ := json.Marshal(tags)
	return string(b)
}

func (d *Database) scanAgent(row interface {
	Scan(dest ...any) error
}) (*models.Agent, error) {
	a := &models.Agent{}
	var notes, tagsRaw string
	err := row.Scan(
		&a.ID, &a.Name, &a.Wallet, &a.IP, &a.Version, &a.Status,
		&a.CPUCores, &a.MemoryGB, &a.LastSeen, &a.CreatedAt,
		&a.Hashrate15s, &a.Hashrate1m, &a.Hashrate15m,
		&a.SharesTotal, &a.SharesGood, &a.SharesBad,
		&a.CPUUsagePct, &a.MemoryUsagePct, &a.UptimeSeconds,
		&notes, &tagsRaw, &a.Platform, &a.Arch, &a.OSVersion, &a.Hostname, &a.MacAddress,
	)
	if err != nil {
		return nil, err
	}
	a.Notes = notes
	a.Tags = decodeTags(tagsRaw)
	return a, nil
}

const agentSelectCols = `id, name, wallet, ip, version, status, cpu_cores, memory_gb, last_seen, created_at,
		hashrate_15s, hashrate_1m, hashrate_15m, shares_total, shares_good, shares_bad,
		cpu_usage_pct, memory_usage_pct, uptime_seconds, notes, tags, platform, arch, os_version, hostname, mac_address`

func (d *Database) UpdateAgentMeta(id, notes string, tags []string) error {
	_, err := d.Exec(`UPDATE agents SET notes = ?, tags = ? WHERE id = ?`, notes, encodeTags(tags), id)
	return err
}
