package service

import (
	"fmt"
	"strings"
	"time"

	"metis/pkg/facts"
)

func (a *App) syncScratchAnnotations(record SnapshotRecord) error {
	scratch := record.Snapshot.USBScratch
	if scratch == nil {
		return nil
	}
	annotations := scratchHealthAnnotations(scratch, record.CollectedAt)
	if len(annotations) == 0 {
		return nil
	}
	return patchNodeAnnotations(record.Node, annotations)
}

func scratchHealthAnnotations(scratch *facts.USBScratch, observedAt time.Time) map[string]string {
	status, detail := scratchStatusDetail(scratch)
	selector := ""
	if scratch.UUID != "" {
		selector = "UUID=" + scratch.UUID
	} else if scratch.Label != "" {
		selector = "LABEL=" + scratch.Label
	}
	managedPaths := make([]string, 0, len(scratch.BindTargets))
	for _, target := range scratch.BindTargets {
		if strings.TrimSpace(target.Path) != "" {
			managedPaths = append(managedPaths, target.Path)
		}
	}
	annotations := map[string]string{}
	for _, family := range []string{"usb-scratch", "astraios"} {
		prefix := "maintenance.bstein.dev/" + family
		annotations[prefix+"-status"] = status
		annotations[prefix+"-detail"] = detail
		annotations[prefix+"-mountpoint"] = scratch.Mountpoint
		annotations[prefix+"-managed-paths"] = strings.Join(managedPaths, "_")
		annotations[prefix+"-last-observed"] = observedAt.UTC().Format(time.RFC3339)
		if selector != "" {
			annotations[prefix+"-selector"] = selector
		}
	}
	return annotations
}

func scratchStatusDetail(scratch *facts.USBScratch) (string, string) {
	if scratch == nil {
		return "missing", "no-scratch-snapshot"
	}
	failures := []string{}
	if !scratch.MountHealthy {
		failures = append(failures, "mount-unhealthy")
	}
	if scratch.UUID != "" && !scratch.UUIDHealthy {
		failures = append(failures, "uuid-mismatch")
	}
	if scratch.Label != "" && !scratch.LabelHealthy {
		failures = append(failures, "label-mismatch")
	}
	if !scratch.BindHealthy {
		failures = append(failures, "bind-mount-incomplete")
	}
	if len(failures) == 0 {
		return "ok", "healthy"
	}
	return "error", strings.Join(failures, ",")
}

func annotationSyncEvent(node string, err error) Event {
	return Event{
		Time:    time.Now().UTC(),
		Kind:    "sentinel.annotation",
		Summary: fmt.Sprintf("Could not sync scratch annotations for %s", node),
		Details: map[string]any{
			"node":  node,
			"error": err.Error(),
		},
	}
}
