package websearch

import (
	"context"
	"encoding/json"
	"fmt"
	"net/http"
	"net/url"
	"strings"
)

type searxNGResponse struct {
	Results []struct {
		Title   string `json:"title"`
		URL     string `json:"url"`
		Content string `json:"content"`
	} `json:"results"`
}

func (c *Client) searchSearXNG(ctx context.Context, provider Provider, query string, count int) ([]Result, error) {
	base := strings.TrimRight(strings.TrimSpace(provider.BaseURL), "/")
	if base == "" {
		return nil, fmt.Errorf("searxng base url is required")
	}

	u, err := url.Parse(base + "/search")
	if err != nil {
		return nil, err
	}
	q := u.Query()
	q.Set(queryParamName(provider), query)
	q.Set("format", "json")
	q.Set("categories", "general")
	u.RawQuery = q.Encode()

	req, err := http.NewRequestWithContext(ctx, http.MethodGet, u.String(), nil)
	if err != nil {
		return nil, err
	}
	req.Header.Set("Accept", "application/json")
	if apiKey := strings.TrimSpace(provider.APIKey); apiKey != "" {
		header := strings.TrimSpace(provider.AuthHeader)
		if header == "" {
			header = "Authorization"
		}
		if strings.EqualFold(header, "Authorization") {
			req.Header.Set(header, "Bearer "+apiKey)
		} else {
			req.Header.Set(header, apiKey)
		}
	}

	body, status, err := c.doRequest(req)
	if err != nil {
		return nil, err
	}
	if status >= 400 {
		return nil, fmt.Errorf("searxng search failed (%d): %s", status, string(body))
	}

	var parsed searxNGResponse
	if err := json.Unmarshal(body, &parsed); err != nil {
		return nil, err
	}
	if len(parsed.Results) == 0 {
		return []Result{}, nil
	}

	limit := count
	if len(parsed.Results) < limit {
		limit = len(parsed.Results)
	}
	results := make([]Result, 0, limit)
	for _, item := range parsed.Results[:limit] {
		results = append(results, Result{
			Title:       strings.TrimSpace(item.Title),
			URL:         strings.TrimSpace(item.URL),
			Description: strings.TrimSpace(item.Content),
		})
	}
	return results, nil
}
