package epics

import (
	"encoding/json"
	"fmt"
	"log/slog"
	"net/http"
	"strings"
	"time"
)

// cfChannel is the JSON structure returned by the Channel Finder Service.
type cfChannel struct {
	Name       string       `json:"name"`
	Owner      string       `json:"owner"`
	Properties []cfProperty `json:"properties"`
	Tags       []cfTag      `json:"tags"`
}

type cfProperty struct {
	Name  string `json:"name"`
	Value string `json:"value"`
	Owner string `json:"owner"`
}

type cfTag struct {
	Name  string `json:"name"`
	Owner string `json:"owner"`
}

// queryChannelFinder fetches channels from CFS matching the given query string.
func queryChannelFinder(cfURL, query string) ([]cfChannel, error) {
	if cfURL == "" {
		return nil, nil
	}

	url := strings.TrimRight(cfURL, "/") + "/resources/channels"
	if query != "" {
		if strings.Contains(query, "=") || strings.Contains(query, "~") {
			// Query is already a structured filter (e.g. area=L1)
			url += "?" + query
		} else {
			// Query is just a PV name pattern
			url += "?~name=*" + query + "*"
		}
	}

	client := &http.Client{Timeout: 10 * time.Second}
	slog.Info("CFS query", "url", url)
	resp, err := client.Get(url)
	if err != nil {
		return nil, fmt.Errorf("CFS request failed: %w", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("CFS returned status %d", resp.StatusCode)
	}

	var channels []cfChannel
	if err := json.NewDecoder(resp.Body).Decode(&channels); err != nil {
		return nil, fmt.Errorf("CFS response parse error: %w", err)
	}
	slog.Info("CFS results", "count", len(channels))

	return channels, nil
}
