package websearch

import (
	"fmt"
	"strings"
)

type ProviderType string

const (
	ProviderBrave      ProviderType = "brave"
	ProviderBing       ProviderType = "bing"
	ProviderDuckDuckGo ProviderType = "duckduckgo"
	ProviderSearXNG    ProviderType = "searxng"
	ProviderCustom     ProviderType = "custom"
)

type Provider struct {
	ID          string       `json:"id"`
	Name        string       `json:"name"`
	Type        ProviderType `json:"type"`
	APIKey      string       `json:"api_key,omitempty"`
	BaseURL     string       `json:"base_url,omitempty"`
	QueryParam  string       `json:"query_param,omitempty"`
	AuthHeader  string       `json:"auth_header,omitempty"`
	ResultsPath string       `json:"results_path,omitempty"`
	TitleField  string       `json:"title_field,omitempty"`
	URLField    string       `json:"url_field,omitempty"`
	DescField   string       `json:"description_field,omitempty"`
}

type Settings struct {
	DefaultProviderID string     `json:"default_provider_id"`
	Providers         []Provider `json:"providers"`
}

func ResolveProvider(settings Settings) (Provider, error) {
	providerID := strings.TrimSpace(settings.DefaultProviderID)
	if providerID != "" {
		for _, p := range settings.Providers {
			if p.ID == providerID && providerConfigured(p) {
				return p, nil
			}
		}
	}
	for _, p := range settings.Providers {
		if providerConfigured(p) {
			return p, nil
		}
	}
	return Provider{}, fmt.Errorf("no search provider configured")
}

func providerConfigured(p Provider) bool {
	switch p.Type {
	case ProviderBrave, ProviderBing:
		return strings.TrimSpace(p.APIKey) != ""
	case ProviderDuckDuckGo:
		return true
	case ProviderSearXNG:
		return strings.TrimSpace(p.BaseURL) != ""
	case ProviderCustom:
		return strings.TrimSpace(p.BaseURL) != "" &&
			strings.TrimSpace(p.ResultsPath) != "" &&
			strings.TrimSpace(p.TitleField) != "" &&
			strings.TrimSpace(p.URLField) != ""
	default:
		return strings.TrimSpace(string(p.Type)) != "" && strings.TrimSpace(p.APIKey) != ""
	}
}

func queryParamName(provider Provider) string {
	if name := strings.TrimSpace(provider.QueryParam); name != "" {
		return name
	}
	return "q"
}
