
package monitoring

import (
	"log"
	"strings"
	"time"

	"service-operation/operations"
	"service-operation/pocketbase"
	"service-operation/shared/savers"
	"service-operation/types"
)

func (ms *MonitoringService) performCheck(service pocketbase.Service) {
	// First, fetch the latest service status from PocketBase to ensure we have current data
	latestService, err := ms.pbClient.GetService(service.ID)
	if err != nil {
		log.Printf("Failed to fetch latest service status for %s: %v", service.Name, err)
		return
	}

	// Respect the service status - don't check paused services
	if latestService.Status == "paused" {
		return // Silently skip paused services
	}

	timeout := 10 * time.Second // Default timeout
	var result *types.OperationResult
	
	serviceType := strings.ToLower(latestService.ServiceType)
	
	// Single log message for check start
	//log.Printf("Checking %s (%s)", latestService.Name, serviceType)
	
	switch serviceType {
	case "ping", "icmp":
		pingOp := operations.NewPingOperation(timeout)
		host := latestService.Host
		if host == "" {
			host = latestService.URL
		}
		result, err = pingOp.Execute(host, 1) // Single ping for monitoring
		
	case "dns":
		dnsOp := operations.NewDNSOperation(timeout)
		host := latestService.Host
		if host == "" {
			host = latestService.Domain
		}
		// Default to A record, but could be made configurable
		queryType := "A"
		result, err = dnsOp.Execute(host, queryType)
		
	case "tcp":
		tcpOp := operations.NewTCPOperation(timeout)
		host := latestService.Host
		if host == "" {
			host = latestService.URL
		}
		port := latestService.Port
		if port <= 0 {
			port = 80 // Default port
		}
		result, err = tcpOp.Execute(host, port)
		
	case "http", "https":
		httpOp := operations.NewHTTPOperation(timeout)
		url := latestService.URL
		if url == "" {
			url = latestService.Host
		}
		result, err = httpOp.Execute(url, "GET")
		
	default:
		log.Printf("Unknown service type: %s for service %s", latestService.ServiceType, latestService.Name)
		return
	}

	// Determine status based on result
	status := "down"
	errorMessage := ""
	responseTime := int64(0)
	
	if err != nil {
		errorMessage = err.Error()
		log.Printf("❌ %s failed: %v", latestService.Name, err)
	} else if result != nil {
		responseTime = result.ResponseTime.Milliseconds()
		if result.Success {
			status = "up"
			//log.Printf("✅ %s: %.0fms", latestService.Name, float64(responseTime))
		} else {
			status = "down"
			errorMessage = result.Error
			log.Printf("❌ %s failed: %s", latestService.Name, errorMessage)
		}
	}

	// Only update service status if the service is not paused
	// Check one more time before updating to prevent race conditions
	currentService, err := ms.pbClient.GetService(latestService.ID)
	if err != nil {
		log.Printf("Failed to verify service status before update for %s: %v", latestService.Name, err)
		return
	}
	
	if currentService.Status == "paused" {
		return // Silently skip status update for paused services
	}

	// Update service status in PocketBase only if not paused
	if err := ms.pbClient.UpdateServiceStatus(latestService.ID, status, responseTime, errorMessage); err != nil {
		log.Printf("Failed to update service status for %s: %v", latestService.Name, err)
	}

	// Save metrics data with regional information
	if result != nil {
		regionName, agentID := ms.GetRegionalInfo()
		metricsSaver := savers.NewMetricsSaverWithRegion(ms.pbClient, regionName, agentID)
		metricsSaver.SaveMetricsForService(*latestService, result)
	}
}