package report

import (
	"time"

	"gitea.dooplex.hu/admin/felhom-controller/internal/metrics"
)

// Report is the JSON payload pushed to the central hub.
type Report struct {
	Version           int              `json:"version"`
	CustomerID        string           `json:"customer_id"`
	CustomerName      string           `json:"customer_name"`
	ControllerVersion string           `json:"controller_version"`
	ControllerURL     string           `json:"controller_url,omitempty"`
	ConfigHash        string           `json:"config_hash,omitempty"`
	Timestamp         time.Time        `json:"timestamp"`
	ReportingDisabled bool             `json:"reporting_disabled,omitempty"`
	System            SystemReport     `json:"system"`
	Storage           []StorageReport  `json:"storage"`
	Containers        ContainerReport  `json:"containers"`
	Backup            BackupReport     `json:"backup"`
	Health            HealthReport     `json:"health"`
	Stacks            StacksReport     `json:"stacks"`
	AppTelemetry      []AppTelemetry          `json:"app_telemetry,omitempty"`
	GeoRestriction    *GeoRestrictionReport   `json:"geo_restriction,omitempty"`

	// DR recipe — the controller (customer + apps) half of the secret-free reconstruction recipe
	// (SPIKE-dr-recipe-2026-06-16). The hub assembles it with the agent's storage/guest/PBS half.
	DRRecipe *DRRecipeAppHalf `json:"dr_recipe,omitempty"`
}

// SystemReport holds host-level system info.
type SystemReport struct {
	Hostname           string  `json:"hostname"`
	OS                 string  `json:"os"`
	Kernel             string  `json:"kernel"`
	CPUModel           string  `json:"cpu_model"`
	CPUCores           int     `json:"cpu_cores"`
	UptimeSeconds      int64   `json:"uptime_seconds"`
	CPUPercent         float64 `json:"cpu_percent"`
	MemoryTotalMB      uint64  `json:"memory_total_mb"`
	MemoryUsedMB       uint64  `json:"memory_used_mb"`
	MemoryPercent      float64 `json:"memory_percent"`
	TemperatureCelsius float64 `json:"temperature_celsius"`
	LoadAvg1           float64 `json:"load_avg_1"`
	LoadAvg5           float64 `json:"load_avg_5"`
	LoadAvg15          float64 `json:"load_avg_15"`
}

// StorageReport holds disk usage for a mount point.
type StorageReport struct {
	Mount          string  `json:"mount"`
	Label          string  `json:"label,omitempty"`
	TotalGB        float64 `json:"total_gb"`
	UsedGB         float64 `json:"used_gb"`
	Percent        float64 `json:"percent"`
	Disconnected   bool    `json:"disconnected,omitempty"`
	Decommissioned bool    `json:"decommissioned,omitempty"`
	MigratedTo     string  `json:"migrated_to,omitempty"`
}

// ContainerReport holds aggregate and per-container status.
type ContainerReport struct {
	Total     int                     `json:"total"`
	Running   int                     `json:"running"`
	Stopped   int                     `json:"stopped"`
	Unhealthy int                     `json:"unhealthy"`
	List      []ContainerDetailReport `json:"list"`
}

// ContainerDetailReport holds per-container info.
type ContainerDetailReport struct {
	Name       string  `json:"name"`
	State      string  `json:"state"`
	CPUPercent float64 `json:"cpu_percent"`
	MemoryMB   float64 `json:"memory_mb"`
}

// BackupReport holds backup subsystem status.
type BackupReport struct {
	Enabled            bool       `json:"enabled"`
	LastDBDump         *time.Time `json:"last_db_dump,omitempty"`
	LastSnapshot       *time.Time `json:"last_snapshot,omitempty"`
	SnapshotCount      int        `json:"snapshot_count"`
	RepoSizeMB         int64      `json:"repo_size_mb"`
	LastIntegrityCheck *time.Time `json:"last_integrity_check,omitempty"`
	IntegrityOK        bool       `json:"integrity_ok"`
	// (ResticPassword removed 2026-06-16 — the live builder never set it post-slice-8C;
	// historically it leaked the restic password into the hub's plaintext report store.)
}

// HealthReport holds the aggregated health status.
type HealthReport struct {
	Status   string   `json:"status"`
	Issues   []string `json:"issues"`
	Warnings []string `json:"warnings"`
}

// StacksReport holds stack deployment status.
type StacksReport struct {
	Deployed  []string `json:"deployed"`
	Available []string `json:"available"`
}

// GeoRestrictionReport holds geo-restriction status for hub display.
type GeoRestrictionReport struct {
	Enabled          bool                            `json:"enabled"`
	AllowedCountries []string                        `json:"allowed_countries"`
	AppOverrides     map[string]GeoAppOverrideReport `json:"app_overrides,omitempty"`
	LastSync         string                          `json:"last_sync,omitempty"`
	LastSyncError    string                          `json:"last_sync_error,omitempty"`
}

// GeoAppOverrideReport holds per-app country override.
type GeoAppOverrideReport struct {
	AllowedCountries []string `json:"allowed_countries"`
}

// AppTelemetry holds per-app (per-stack) resource and log telemetry.
type AppTelemetry struct {
	AppName         string             `json:"app_name"`
	DisplayName     string             `json:"display_name"`
	Containers      []string           `json:"containers"`
	MemoryCurrentMB float64            `json:"memory_current_mb"`
	MemoryAvgMB     float64            `json:"memory_avg_mb"`
	MemoryPeakMB    float64            `json:"memory_peak_mb"`
	CPUAvgPercent   float64            `json:"cpu_avg_percent"`
	CatalogEstimate string             `json:"catalog_estimate"`
	CatalogLimit    string             `json:"catalog_limit"`
	LogErrors       int                `json:"log_errors"`
	LogWarnings     int                `json:"log_warnings"`
	Issues          []metrics.LogIssue `json:"issues,omitempty"`
}
