package main

import (
	"log"
	"os"
	"os/signal"
	"syscall"
	"time"

	"gordenko.dev/dima/flashscore"
	fsmodel "gordenko.dev/dima/flashscore/model"
	"gordenko.dev/dima/qx"
	"gordenko.dev/dima/tipper/daemon"
	"gordenko.dev/dima/tipper/model"
	"gordenko.dev/dima/web"
	"gordenko.dev/dima/web/api"
	"gordenko.dev/dima/web/router"
	"gordenko.dev/dima/ws"

	_ "github.com/go-sql-driver/mysql"
)

const (
	port    = 33465
	baseDir = "/home/ubuntu/ht"
	dsn     = "user:password@/tipper"
)

func main() {
	logger := log.New(os.Stdout, "", log.LstdFlags)

	db, err := qx.Open("mysql", dsn)
	if err != nil {
		log.Fatalf("qx.Open: %s\n", err)
	}
	defer db.Close()

	tipperModel := model.New(db)
	flashscoreModel := fsmodel.New(db)

	wsServer, err := ws.NewPublicServer(ws.PublicServerOptions{
		Logger:                log.New(os.Stdout, "ws: ", log.LstdFlags),
		LostConnectionTimeout: time.Duration(60*60*24) * time.Second,
	})
	if err != nil {
		log.Fatalf("ws.NewPublicServer: %s\n", err)
	}

	d, err := daemon.New(daemon.Options{
		Logger:            logger,
		FlashscoreAPIAddr: "http://localhost:7767/api",
		OnexbetWsURL:      "ws://localhost:7772/ws",
		OnexbetAPIURL:     "http://localhost:7772/api",
		FlashscoreModel:   flashscoreModel,
		TipperModel:       tipperModel,
		SportIDs: []int{
			flashscore.Football,
			flashscore.Handball,
			flashscore.Tennis,
		},
	})
	if err != nil {
		log.Fatalf("daemon.New: %s\n", err)
	}

	publicAPI, err := api.NewAPI(api.Options{
		Logger: log.New(os.Stdout, "api: ", log.LstdFlags),
	})
	if err != nil {
		log.Fatalf("api.NewAPI: %s\n", err)
	}

	publicAPI.PublicFunc("setTipResult", d.SetTipResultManual)
	publicAPI.PublicFunc("listSportTips", d.ListSportTips)
	publicAPI.PublicFunc("listTeamZones", flashscoreModel.ListTeamZones)
	publicAPI.PublicFunc("listTeamsByZone", flashscoreModel.ListTeamsByZone)
	publicAPI.PublicFunc("listTeamAliases", flashscoreModel.ListTeamAliases)
	publicAPI.PublicFunc("addTeamAlias", flashscoreModel.AddTeamAlias)
	publicAPI.PublicFunc("removeTeamAlias", flashscoreModel.RemoveTeamAlias)

	publicAPI.PublicFunc("listStrategies", tipperModel.ListStrategies)
	publicAPI.PublicFunc("listStrategyRatedChampStats", tipperModel.ListStrategyRatedChampStats)
	publicAPI.PublicFunc("getStrategyRatedHistory", tipperModel.GetStrategyRatedHistory)

	publicAPI.PublicFunc("listStrategiesReports", tipperModel.ListStrategiesReports)
	publicAPI.PublicFunc("listStrategies", tipperModel.ListStrategies)
	publicAPI.PublicFunc("listStrategyChampStats", tipperModel.ListStrategyChampStats)
	publicAPI.PublicFunc("getStrategyHistory", tipperModel.GetStrategyHistory)
	publicAPI.PublicFunc("getSportRatedReport", tipperModel.GetSportRatedReport)

	publicAPI.PublicFunc("searchMatchCandidates", d.SearchMatchCandidates)
	publicAPI.PublicFunc("searchMatchCandidatesByTeamName", d.SearchMatchCandidatesByTeamName)
	publicAPI.PublicFunc("addTeamsAliases", d.AddTeamsAliases)

	r := router.New()
	r.HandleFunc("/football", pageFootball)
	r.HandleFunc("/handball", pageHandball)
	r.HandleFunc("/tennis", pageTennis)
	r.HandleFunc("/football-by-days", d.PageFootballByDays)
	r.HandleFunc("/handball-by-days", d.PageHandballByDays)
	r.HandleFunc("/tennis-by-days", d.PageTennisByDays)
	r.HandleFunc("/aliases", pageAliases)
	r.HandleFunc("/stats", pageStats)
	r.HandleFunc("/matches", d.PageMatches)
	//r.HandleFunc("/watch", d.PageWatch)
	//r.HandleFunc("/unwatch", d.PageUnwatch)
	r.HandleFunc("/listRatedChamps", d.ListRatedChamps)
	r.HandleFunc("/", pageIndex)
	r.HandleFunc("/best-strategies", pageStrategies)
	//
	r.Handle("/api", publicAPI)
	r.Handle("/ws", wsServer)

	app, err := web.NewApp(web.AppOptions{
		Port:        port,
		Router:      r,
		BaseDir:     baseDir,
		TemplateDir: "templates",
		StaticDirs: map[string]string{
			"static": "static",
		},
	})
	if err != nil {
		log.Fatalf("web.NewApp: %s\n", err)
	}

	go app.Run()
	go d.Run()

	sigs := make(chan os.Signal, 1)
	signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)

	<-sigs

	logger.Println("daemon stopped.")
}

/*
var topChamps = map[string]bool{
	"/england/premier-league":       true,
	"/germany/bundesliga":           true,
	"/italy/serie-a":                true,
	"/spain/laliga":                 true,
	"/portugal/primeira-liga":       true,
	"/switzerland/super-league":     true,
	"/turkey/super-lig":             true,
	"/faroe-islands/premier-league": true,
	"/usa/mls":                      true,
}

// Топ чемпы
var myIgnoreChamps = map[string]bool{
	"/england/premier-league":   true,
	"/germany/bundesliga":       true,
	"/spain/laliga":             true,
	"/portugal/primeira-liga":   true,
	"/switzerland/super-league": true,
	"/turkey/super-lig":         true,
	//"/faroe-islands/premier-league": true,
	"/usa/mls": true,
}

func acceptedChamps(champs map[string]bool) func(string) bool {
	return func(champID string) bool {
		return champs[champID]
	}
}

func nonAcceptedChamps(champs map[string]bool) func(string) bool {
	return func(champID string) bool {
		return !champs[champID]
	}
}
*/
