package orchestrator

import (
	"fmt"
	"time"

	"github.com/Fimeg/RedFlag/aggregator-agent/internal/system"
)

// StorageScanner scans disk usage metrics
type StorageScanner struct {
	agentVersion string
}

// NewStorageScanner creates a new storage scanner
func NewStorageScanner(agentVersion string) *StorageScanner {
	return &StorageScanner{
		agentVersion: agentVersion,
	}
}

// IsAvailable always returns true since storage scanning is always available
func (s *StorageScanner) IsAvailable() bool {
	return true
}

// ScanStorage collects disk usage information and returns proper storage metrics
func (s *StorageScanner) ScanStorage() ([]StorageMetric, error) {
	sysInfo, err := system.GetSystemInfo(s.agentVersion)
	if err != nil {
		return nil, fmt.Errorf("failed to get system info: %w", err)
	}

	if len(sysInfo.DiskInfo) == 0 {
		return nil, fmt.Errorf("no disk information available")
	}

	// Convert disk info to proper StorageMetric format
	var metrics []StorageMetric

	for _, disk := range sysInfo.DiskInfo {
		metric := StorageMetric{
			Mountpoint:     disk.Mountpoint,
			Filesystem:     disk.Filesystem,
			Device:         disk.Device,
			DiskType:       disk.DiskType,
			TotalBytes:     int64(disk.Total),
			UsedBytes:      int64(disk.Used),
			AvailableBytes: int64(disk.Available),
			UsedPercent:    disk.UsedPercent,
			IsRoot:         disk.IsRoot,
			IsLargest:      disk.IsLargest,
			Severity:       determineDiskSeverity(disk.UsedPercent),
			Metadata: map[string]interface{}{
				"agent_version": s.agentVersion,
				"collected_at":  time.Now().Format(time.RFC3339),
			},
		}
		metrics = append(metrics, metric)
	}

	return metrics, nil
}

// Name returns the scanner name
func (s *StorageScanner) Name() string {
	return "Disk Usage Reporter"
}

// --- Typed Scanner Implementation ---

// GetType returns the scanner type
func (s *StorageScanner) GetType() ScannerType {
	return ScannerTypeStorage
}

// ScanTyped returns typed results (new implementation)
func (s *StorageScanner) ScanTyped() (TypedScannerResult, error) {
	startTime := time.Now()
	defer func() {
		// Duration will be set at the end
	}()

	metrics, err := s.ScanStorage()
	if err != nil {
		return TypedScannerResult{
			ScannerName: s.Name(),
			ScannerType: ScannerTypeStorage,
			Error:       err,
			Status:      "failed",
			Duration:    time.Since(startTime).Milliseconds(),
		}, err
	}

	return TypedScannerResult{
		ScannerName: s.Name(),
		ScannerType: ScannerTypeStorage,
		StorageData: metrics,
		Status:      "success",
		Duration:    time.Since(startTime).Milliseconds(),
	}, nil
}

// determineDiskSeverity returns severity based on disk usage percentage
func determineDiskSeverity(usedPercent float64) string {
	switch {
	case usedPercent >= 95:
		return "critical"
	case usedPercent >= 90:
		return "important"
	case usedPercent >= 80:
		return "moderate"
	default:
		return "low"
	}
}
