package websearch

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

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

	endpoint = strings.NewReplacer(
		"{query}", url.QueryEscape(query),
		"{count}", fmt.Sprintf("%d", count),
	).Replace(endpoint)

	reqURL, err := url.Parse(endpoint)
	if err != nil {
		return nil, err
	}
	if !strings.Contains(provider.BaseURL, "{query}") {
		q := reqURL.Query()
		q.Set(queryParamName(provider), query)
		if !strings.Contains(provider.BaseURL, "{count}") {
			q.Set("count", fmt.Sprintf("%d", count))
		}
		reqURL.RawQuery = q.Encode()
	}

	req, err := http.NewRequestWithContext(ctx, http.MethodGet, reqURL.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)
		switch {
		case header != "":
			if strings.EqualFold(header, "Authorization") {
				req.Header.Set(header, "Bearer "+apiKey)
			} else {
				req.Header.Set(header, apiKey)
			}
		case strings.Contains(reqURL.RawQuery, "api_key="):
			// key already in URL
		default:
			q := reqURL.Query()
			q.Set("api_key", apiKey)
			reqURL.RawQuery = q.Encode()
			req.URL = reqURL
		}
	}

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

	root, err := decodeJSONBody(body)
	if err != nil {
		return nil, err
	}
	items, ok := resultsArray(root, provider.ResultsPath)
	if !ok {
		return []Result{}, nil
	}

	descField := strings.TrimSpace(provider.DescField)
	if descField == "" {
		descField = "description"
	}

	limit := count
	if len(items) < limit {
		limit = len(items)
	}
	results := make([]Result, 0, limit)
	for _, item := range items[:limit] {
		title := jsonFieldString(item, provider.TitleField)
		link := jsonFieldString(item, provider.URLField)
		desc := jsonFieldString(item, descField)
		if title == "" && link == "" {
			continue
		}
		results = append(results, Result{
			Title:       title,
			URL:         link,
			Description: desc,
		})
	}
	return results, nil
}
