package main

import (
	"fmt"
	"net/http"
	"net/url"
	"strings"
	"time"

	"github.com/PuerkitoBio/goquery"
)

func PerformGoogleTextSearch(query, safe, lang string, page int) ([]TextSearchResult, time.Duration, error) {
	const resultsPerPage = 10
	var results []TextSearchResult

	startTime := time.Now() // Start the timer

	// Build the search URL
	searchURL := buildSearchURL(query, safe, lang, page, resultsPerPage)

	// Create a new request
	req, err := http.NewRequest("GET", searchURL, nil)
	if err != nil {
		return nil, 0, fmt.Errorf("failed to create request: %v", err)
	}

	// Generate and set User-Agent header
	TextUserAgent, err := GetUserAgent("Google-Text-Search")
	if err != nil {
		return nil, 0, err
	}
	req.Header.Set("User-Agent", TextUserAgent)

	// Perform the request using proxy if MetaProxy is enabled
	var resp *http.Response
	if config.MetaProxyEnabled && metaProxyClient != nil {
		resp, err = metaProxyClient.Do(req)
	} else {
		client := &http.Client{}
		resp, err = client.Do(req)
	}

	if err != nil {
		return nil, 0, fmt.Errorf("making request: %v", err)
	}
	defer resp.Body.Close()

	// Check for HTTP status code
	if resp.StatusCode != http.StatusOK {
		return nil, 0, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
	}

	// Parse the HTML response
	doc, err := goquery.NewDocumentFromReader(resp.Body)
	if err != nil {
		return nil, 0, fmt.Errorf("loading HTML document: %v", err)
	}

	// Extract search results
	results = parseResults(doc)

	duration := time.Since(startTime) // Calculate the duration

	if len(results) == 0 {
		printDebug("No results found from Google Search")
	}

	return results, duration, nil
}

func buildSearchURL(query, safe, lang string, page, resultsPerPage int) string {
	safeParam := "&safe=off"
	if safe == "active" {
		safeParam = "&safe=active"
	}

	langParam := ""
	glParam := ""

	if lang != "" {
		// Use lang as the geolocation
		langParam = "&lr=lang_" + lang
		glParam = "&gl=" + lang
	} else {
		// Use default geolocation
		glParam = "&gl=us"
	}

	startIndex := (page - 1) * resultsPerPage
	udmParam := "&udm=14" // Add the required parameter

	// Build the URL string
	baseURL := "https://www.google.com/search?q=%s%s%s%s&start=%d%s"
	fullURL := fmt.Sprintf(baseURL, url.QueryEscape(query), safeParam, langParam, glParam, startIndex, udmParam)

	// Debug print
	printDebug("%s", fullURL)

	return fullURL
}

// func getRandomGeoLocation() (string, string) {
// 	countries := []string{"us", "ca", "gb", "fr", "de", "au", "in", "jp", "br", "za"}
// 	randomCountry := countries[rand.Intn(len(countries))]

// 	glParam := "&gl=" + randomCountry
// 	uuleParam := ""

// 	return glParam, uuleParam
// }

func parseResults(doc *goquery.Document) []TextSearchResult {
	var results []TextSearchResult

	doc.Find(".yuRUbf").Each(func(i int, s *goquery.Selection) {
		link := s.Find("a")
		href, exists := link.Attr("href")
		if !exists {
			printDebug("No href attribute found for result %d\n", i)
			return
		}

		header := link.Find("h3").Text()
		header = strings.TrimSpace(strings.TrimSuffix(header, "›"))

		description := ""
		descSelection := doc.Find(".VwiC3b").Eq(i)
		if descSelection.Length() > 0 {
			description = descSelection.Text()
		}

		result := TextSearchResult{
			URL:         href,
			Header:      header,
			Description: description,
		}
		results = append(results, result)
	})

	return results
}