package batmas

import (
	"fmt"
	"log"
	"strings"

	"wartank/pkg/components/section"
	"wartank/pkg/types"
	"wartank/server/serv_bots/warbot/angar/batmas/batmasnet"
)

/*
	Битва мастеров. Работает примерно раз в сутки.
	Требуется три победы, потом нужно загрести золотишко.
	Между битвами надо удерживать рейтинг, чтобы не кидало к монстрам.
*/

// BatMas -- объект битвы мастеров
type BatMas struct {
	*section.Section
	server types.IServer
	bot    types.IServBot
	net    *batmasnet.BatMasNet
}

// NetBatMas -- возвращает новый *BatMas
func NewBatMas(server types.IServer, bot types.IServBot) (*BatMas, error) {
	{ // Предусловия
		if server == nil {
			return nil, fmt.Errorf("NewBatMas(): IServer == nil")
		}
		if bot == nil {
			return nil, fmt.Errorf("NewBatMas(): IServBot == nil")
		}
	}
	sf := &BatMas{
		server: server,
		bot:    bot,
	}
	return sf, nil
}

// Run -- запускает в работу битву мастеров
func (sf *BatMas) Run() error {
	var err error
	{ // ISection (ожидание)
		sf.Section, err = section.NewSection(sf.server, `/> Битва мастеров <`)
		if err != nil {
			return fmt.Errorf("BatMas.Run(): in create *Section, err=\n\t%w", err)
		}
	}
	{ // Net (ожидание)
		sf.net, err = batmasnet.NewBatMasNet(sf.server, sf.bot)
		if err != nil {
			return fmt.Errorf("BatMas.Run(): при создании BatMasNet, err=\n\t%w", err)
		}
	}
	_ = sf.goBatMas()
	go func() {
		for {
			select {
			case <-sf.server.Done():
				sf.CountDown().Stop()
				return
			case <-sf.CountDown().ChanSig():
				if !sf.goBatMas() { // Проверка на начало сражения
					continue
				}
			}
		}
	}()
	return nil
}

// Вычисляет нужно ли идти в битву мастеров
//
//	если нужно, то время проверять уже не надо
func (sf *BatMas) goBatMas() bool {
	sf.findTimeCount()
	if !sf.upBattle() {
		return false
	}
	countTime := sf.CountDown().Get()
	countTime -= 5
	if countTime > 25 {
		if err := sf.CountDown().Set(countTime); err != nil {
			log.Printf("ERRO BatMas.goBatMas(): при установке времени ожидания битвы мастеров(%v)\n\terr=%v\n", countTime, err)
		}
		return false
	}

	// Время меньше 25 сек, надо уточнять (тут возможна ошибка с экраном ожидания)
	if err := sf.net.UpdateLst("Битва мастеров"); err != nil {
		// log._rintf("ERRO Battle.goBattle().fnCountDown(): при обновлении lstBattle, err=\n\t%v\n", err)
		// Возможно времени уже не осталось
		return true
	}
	// Время ожидания вышло, надо начать атаку
	if err := sf.CountDown().Set(0); err != nil {
		log.Printf("ERRO BatMas.goBatMas(): при установке времени ожидания битвы мастеров(0)\n\terr=%v\n", err)
	}
	return false
}

// Ищет время до начала битвы мастеров
func (sf *BatMas) findTimeCount() {
	var (
		strOut    string
		lstBattle = sf.GetLst()
		isFind    bool
	)
	// Обновление через: 12:02:22
	for _, strOut = range lstBattle {
		if strings.Contains(strOut, `Обновление через: `) {
			isFind = true
			break
		}
	}
	if isFind { // Ждём начала битвы мастеров
		lstTime := strings.Split(strOut, `Обновление через: `)
		strTime := lstTime[1]
		lstTime = strings.Split(strTime, ` (`)
		strTime = lstTime[0]

		if err := sf.CountDown().Parse(strTime); err != nil {
			log.Printf("WARN BatMas.findTimeCount(): при установке времени ожидания битвы мастеров(%v)\n\terr=%v\n", strTime, err)
		}
	}
}

// При необходимости даёт команду на участие в битве мастеров,
//
//	вызывается только если есть награда
func (sf *BatMas) upBattle() bool {
	if err := sf.net.UpdateLst("Битва мастеров"); err != nil {
		// log._rintf("ERRO BatMas.upBattle(): при обновлении lstBattle, err=\n\t%v\n", err)
		return false
	}
	// log.Error("BatMas.upBattle(): доделать")
	// var (
	// 	strOut    string
	// 	lstBattle = sf.GetLst()
	// 	isFind    bool
	// )
	// for _, strOut = range lstBattle {
	// 	if strings.Contains(strOut, `>Взвод, подъем! В атаку!<`) {
	// 		isFind = true
	// 		break
	// 	}
	// }
	// if isFind {
	// 	lstUp := strings.Split(strOut, `<a class="simple-but border" href="`)
	// 	linkUp := lstUp[1]
	// 	lstUp = strings.Split(linkUp, `"><span><span>Взвод, подъем! В атаку!</span></span></a>`)
	// 	linkUp = "http://wartank.ru/" + lstUp[0]
	// 	lstBattle, err := sf.net.Get(linkUp)
	// 	if err != nil {
	// 		log.WithError(err).Error("Battle.upBattle(): при выполнении GET-команды на подъём в атаку")
	// 		return false
	// 	}
	// 	if err = sf.Update(lstBattle); err != nil {
	// 		log.WithError(err).Error("Battle.upBattle(): при обновлении lstBattle")
	// 	}
	// }
	return false
}
