
package uptimemonitoring

import (
	"encoding/json"
	"fmt"
	"net/http"
	"time"

	"service-operation/pocketbase"
)

// UptimeClient handles uptime service operations
type UptimeClient struct {
	pbClient *pocketbase.PocketBaseClient
}

// MetricRecord represents a metric record from any collection
type MetricRecord struct {
	ID           string    `json:"id"`
	ServiceID    string    `json:"service_id"`
	Status       string    `json:"status"`
	ResponseTime int       `json:"response_time"`
	ErrorMessage string    `json:"error_message"` // Added missing ErrorMessage field
	Timestamp    time.Time `json:"timestamp"`
	Created      time.Time `json:"created"`
}

// NewUptimeClient creates a new uptime client
func NewUptimeClient(pbClient *pocketbase.PocketBaseClient) *UptimeClient {
	return &UptimeClient{
		pbClient: pbClient,
	}
}

// GetServices retrieves all services for monitoring
func (uc *UptimeClient) GetServices() ([]UptimeService, error) {
	url := fmt.Sprintf("%s/api/collections/services/records", uc.pbClient.GetBaseURL())
	
	resp, err := http.Get(url)
	if err != nil {
		return nil, fmt.Errorf("failed to fetch services: %v", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("failed to fetch services, status: %d", resp.StatusCode)
	}

	var response struct {
		Items []UptimeService `json:"items"`
	}

	if err := json.NewDecoder(resp.Body).Decode(&response); err != nil {
		return nil, fmt.Errorf("failed to decode services: %v", err)
	}

	// log.Printf("✅ Fetched %d services for monitoring", len(response.Items))
	return response.Items, nil
}

// GetLatestMetricRecord gets the latest metric record for a service from specified collection
func (uc *UptimeClient) GetLatestMetricRecord(serviceID, collection string) ([]MetricRecord, error) {
	url := fmt.Sprintf("%s/api/collections/%s/records?filter=service_id='%s'&sort=-timestamp&perPage=1", 
		uc.pbClient.GetBaseURL(), collection, serviceID)
	
	// log.Printf("🔍 [METRICS-QUERY] Getting latest record for service %s from %s", serviceID, collection)
	
	resp, err := http.Get(url)
	if err != nil {
		return nil, fmt.Errorf("failed to fetch metric record: %v", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("failed to fetch metric record, status: %d", resp.StatusCode)
	}

	var response struct {
		Items []struct {
			ID           string `json:"id"`
			ServiceID    string `json:"service_id"`
			Status       string `json:"status"`
			ResponseTime int    `json:"response_time"`
			ErrorMessage string `json:"error_message"` // Added missing ErrorMessage field
			Timestamp    string `json:"timestamp"`
			Created      string `json:"created"`
		} `json:"items"`
	}

	if err := json.NewDecoder(resp.Body).Decode(&response); err != nil {
		return nil, fmt.Errorf("failed to decode metric record: %v", err)
	}

	var records []MetricRecord
	for _, item := range response.Items {
		timestamp, _ := time.Parse(time.RFC3339, item.Timestamp)
		created, _ := time.Parse(time.RFC3339, item.Created)
		
		records = append(records, MetricRecord{
			ID:           item.ID,
			ServiceID:    item.ServiceID,
			Status:       item.Status,
			ResponseTime: item.ResponseTime,
			ErrorMessage: item.ErrorMessage, // Include ErrorMessage in the record
			Timestamp:    timestamp,
			Created:      created,
		})
	}

	// log.Printf("📊 [METRICS-RESULT] Found %d records for service %s in %s", len(records), serviceID, collection)
	return records, nil
}