package agentapi

// DiskVerdict is the customer-facing disk-health verdict derived from a SmartSummary (v0.169.0).
// It is the SHARED source of truth for both the "Lemezek állapota" dashboard card and the 6-hourly
// degradation check — one pure function so the chip and the alert can never disagree.
type DiskVerdict int

const (
	// DiskVerdictUnknown — no SMART data (nil / UNKNOWN / old agent). Renders "Nincs adat"; NEVER
	// alarms and NEVER participates in degradation transitions (excluded both directions).
	DiskVerdictUnknown DiskVerdict = iota
	DiskVerdictOK                  // "Rendben"        — PASSED, all counters clean
	DiskVerdictWarn                // "Figyelmeztetés" — PASSED but a wear/relocation counter is non-zero (or NVMe ≥90%)
	DiskVerdictFail                // "Hiba"           — FAILING
)

// percentageUsedWarn is the NVMe wear threshold (inclusive) at which a still-PASSED disk warns.
const percentageUsedWarn = 90

// DiskVerdictFor maps a SmartSummary to a verdict per the v0.169.0 rules:
//
//	FAILING                                             → Hiba
//	PASSED + any(reallocated>0, pending>0, offline_unc>0,
//	             critical_warning>0, media_errors>0,
//	             percentage_used >= 90)                 → Figyelmeztetés
//	PASSED otherwise                                    → Rendben
//	nil / UNKNOWN / empty                               → Nincs adat
func DiskVerdictFor(s *SmartSummary) DiskVerdict {
	if s == nil || s.Health == "" || s.Health == SmartUnknown {
		return DiskVerdictUnknown
	}
	if s.Health == SmartFailing {
		return DiskVerdictFail
	}
	// Health == PASSED (or any non-empty non-FAILING value we treat as passing): inspect the counters.
	if positive(s.ReallocatedSectors) || positive(s.PendingSectors) || positive(s.OfflineUncorrectable) ||
		positive(s.CriticalWarning) || positive(s.MediaErrors) || atLeast(s.PercentageUsed, percentageUsedWarn) {
		return DiskVerdictWarn
	}
	return DiskVerdictOK
}

// Label is the exact Hungarian customer copy for the verdict (shared by the card chip and the email).
func (v DiskVerdict) Label() string {
	switch v {
	case DiskVerdictOK:
		return "Rendben"
	case DiskVerdictWarn:
		return "Figyelmeztetés"
	case DiskVerdictFail:
		return "Hiba"
	default:
		return "Nincs adat"
	}
}

// DegradedAttributes returns the human-readable Hungarian names of the attribute(s) that pushed a
// PASSED disk to Figyelmeztetés (empty for OK/Fail/Unknown) — for the alert body. FAILING is a
// whole-disk verdict with no single triggering counter, so it returns nil there.
func DegradedAttributes(s *SmartSummary) []string {
	if s == nil {
		return nil
	}
	var out []string
	if positive(s.ReallocatedSectors) {
		out = append(out, "áthelyezett szektorok")
	}
	if positive(s.PendingSectors) {
		out = append(out, "függőben lévő szektorok")
	}
	if positive(s.OfflineUncorrectable) {
		out = append(out, "javíthatatlan szektorok")
	}
	if positive(s.CriticalWarning) {
		out = append(out, "kritikus figyelmeztetés")
	}
	if positive(s.MediaErrors) {
		out = append(out, "adathordozó-hibák")
	}
	if atLeast(s.PercentageUsed, percentageUsedWarn) {
		out = append(out, "elhasználódás")
	}
	return out
}

func positive(p *int) bool       { return p != nil && *p > 0 }
func atLeast(p *int, n int) bool { return p != nil && *p >= n }
