package onexbet

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

	"gordenko.dev/dima/httpreq"
)

// champFilter - на входе имя чемпионата, на выходе true - если чемпионат удовлетворяет,
// false - если игнорируем
func SearchMatchCandidates(home, away string, sportID OnexbetSport) (candidates []MatchCandidate, err error) {
	var (
		lineSearchURL     string
		liveSearchURL     string
		requiredSportName string
		champFilter       func(string) bool
	)

	switch sportID {
	case Football:
		lineSearchURL = stdLineSearchURL
		liveSearchURL = stdLiveSearchURL
		requiredSportName = "football"
		champFilter = FootballChampFilter

	case Handball:
		lineSearchURL = stdLineSearchURL
		liveSearchURL = stdLiveSearchURL
		requiredSportName = "handball"
		champFilter = HandballChampFilter

	case Tennis:
		lineSearchURL = tennisLineSearchURL
		liveSearchURL = tennisLiveSearchURL
		requiredSportName = "tennis"
		champFilter = TennisChampFilter
	}

	// 2 запроса к Line и Live матчам
	homeLineMatches, err := SearchTeamMatches(lineSearchURL, home)
	if err != nil {
		// log
	}

	homeLiveMatches, err := SearchTeamMatches(liveSearchURL, home)
	if err != nil {
		// log
	}

	awayLineMatches, err := SearchTeamMatches(lineSearchURL, away)
	if err != nil {
		// log
	}

	awayLiveMatches, err := SearchTeamMatches(liveSearchURL, away)
	if err != nil {
		// log
	}

	lists := [][]MatchCandidate{
		homeLineMatches,
		homeLiveMatches,
		awayLineMatches,
		awayLiveMatches,
	}

	requiredSportName = strings.ToLower(requiredSportName)

	candidates = filterMatchesBySportAndChamps(lists, requiredSportName, champFilter)
	return
}

// champFilter - на входе имя чемпионата, на выходе true - если чемпионат удовлетворяет,
// false - если игнорируем
func SearchTeamCandidates(team string, sportID OnexbetSport) (candidates []MatchCandidate, err error) {
	var (
		lineSearchURL     string
		liveSearchURL     string
		requiredSportName string
		champFilter       func(string) bool
	)

	switch sportID {
	case Football:
		lineSearchURL = stdLineSearchURL
		liveSearchURL = stdLiveSearchURL
		requiredSportName = "football"
		champFilter = FootballChampFilter

	case Handball:
		lineSearchURL = stdLineSearchURL
		liveSearchURL = stdLiveSearchURL
		requiredSportName = "handball"
		champFilter = HandballChampFilter

	case Tennis:
		lineSearchURL = tennisLineSearchURL
		liveSearchURL = tennisLiveSearchURL
		requiredSportName = "tennis"
		champFilter = TennisChampFilter
	}

	// 2 запроса к Line и Live матчам
	teamLineMatches, err := SearchTeamMatches(lineSearchURL, team)
	if err != nil {
		// log
	}

	teamLiveMatches, err := SearchTeamMatches(liveSearchURL, team)
	if err != nil {
		// log
	}

	lists := [][]MatchCandidate{
		teamLineMatches,
		teamLiveMatches,
	}

	candidates = filterMatchesBySportAndChamps(lists, requiredSportName, champFilter)
	return
}

func filterMatchesBySportAndChamps(lists [][]MatchCandidate, requiredSportName string, champFilter func(string) bool) (candidates []MatchCandidate) {
	// Для отсева матчей дубликатов
	matchIDs := make(map[string]bool)

	requiredSportName = strings.ToLower(requiredSportName)

	for _, list := range lists {
		for _, match := range list {
			if !matchIDs[match.MatchID] {
				sportName := strings.ToLower(match.Sport)

				if !strings.Contains(sportName, requiredSportName) {
					continue
				}

				if requiredSportName == "football" {
					// Доп проверка на Американский футбол
					if strings.Contains(sportName, "american football") {
						continue
					}
				}

				if champFilter != nil {
					if !champFilter(match.ChampName) {
						continue
					}
				}

				// FIX - добавить проверку для тенниса по / и ()

				candidates = append(candidates, match)
				matchIDs[match.MatchID] = true
			}
		}
	}
	return
}

func SearchTeamMatches(searchURL string, teamName string) (matches []MatchCandidate, err error) {
	if teamName == "" {
		err = fmt.Errorf("Empty teamName")
		return
	}

	if searchURL == "" {
		err = fmt.Errorf("Empty searchURL")
		return
	}

	// 2 запроса к Line и Live матчам

	params := url.Values{}
	params.Set("text", teamName)
	params.Set("limit", "50")
	params.Set("mode", "4")
	params.Set("partner", defaultPartnerID)
	params.Set("lng", "en")
	params.Set("userId", "0")

	queryString := params.Encode()

	req, err := http.NewRequest("GET", searchURL+"?"+queryString, nil)
	if err != nil {
		return
	}

	resp, err := httpreq.Send(req, 10*time.Second)
	if err != nil {
		err = fmt.Errorf("httpreq.Send: %s", err)
		return
	}

	var result searchResponse

	err = json.Unmarshal(resp.Body, &result)
	if err != nil {
		return
	}

	for _, match := range result.Value {
		matches = append(matches, MatchCandidate{
			Sport:     match.Sport,
			ChampName: match.ChampName,
			StartTime: match.StartTime,
			Home:      match.Home,
			Away:      match.Away,
			MatchID:   match.MatchID,
		})
	}
	return
}
