package missions

import (
	"fmt"
	"strings"
	"time"

	"wartank/pkg/components/section"
	"wartank/pkg/types"
	"wartank/server/serv_bots/warbot/angar/missions/missionsnet"
)

/*
	Сканирует миссии на предмет забрать золотишко.
*/

// Missions -- забирает золотишко
type Missions struct {
	*section.Section
	bot    types.IServBot
	net    *missionsnet.MissionsNet
	server types.IServer
}

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

	return sf, nil
}

func (sf *Missions) Run() error {
	var err error
	{ // Section
		sf.Section, err = section.NewSection(sf.server, `<title>Миссии</title>`)
		if err != nil {
			return fmt.Errorf("Missions.Run(): in create *Section, err=\n\t%w", err)
		}
	}
	{ // SectionNet
		sf.net, err = missionsnet.NewMissionsNet(sf.server, sf.bot)
		if err != nil {
			return fmt.Errorf("Missions.Run(): in create *SectionNet, err=\n\t%w", err)
		}
	}
	go sf.run()
	return nil
}

// обрабатывает конвой
func (sf *Missions) run() {
	defer func() {
		sf.CountDown().Stop()
	}()
	time.Sleep(time.Second * 15)
	for { // Время истекло
		select {
		case <-sf.server.Done():
			sf.CountDown().Stop()
			return
		case <-sf.CountDown().ChanSig():
			if err := sf.net.UpdateLst("Missions.run()"); err != nil {
				// log._rintf("ERRO Missions.run(): при обновлении lstMissions, err=\n\t%v\n", err)
				return
			}
			sf.checkAvard()
		}
		time.Sleep(time.Second * 30)
		if err := sf.CountDown().Set(1); err != nil {
			panic(fmt.Errorf("Missions.run(): при установке CountDown, err=\n\t%w", err))
		}
	}
}

// Забирает всё самое вкусное
func (sf *Missions) checkAvard() {
	sf.battleDefence()
	sf.battleAttack()
	sf.battleWar()
	sf.battle5Fiting()
	sf.battle6win()
	sf.battle10Fiting()
	sf.battleDogFyting()
	sf.makeResource()
	sf.kill3tanks()
	sf.makeFuel()
	sf.upMan()
}

// Проверяет награду за уничтожить 3 танка в бою
func (sf *Missions) kill3tanks() {
	var (
		strOut      string
		lstMissions = sf.GetLst()
		isFind      bool
		ind         int
	)
	for ind, strOut = range lstMissions {
		if strings.Contains(strOut, `Уничтожь в бою 3 танка<br/>`) {
			isFind = true
			break
		}
	}
	if !isFind {
		return
	}
	// <a class="simple-but border" href="?70-1.ILinkListener-missions-cc-0-c-awardLink"><span><span>Получить награду</span></span></a>
	ind += 23
	strOut = lstMissions[ind]
	if !strings.Contains(strOut, `>Получить награду<`) {
		return
	}
	lstLink := strings.Split(strOut, `<a class="simple-but border" href="`)
	strLink := lstLink[1]
	lstLink = strings.Split(strLink, `"><span><span>Получить награду</span></span></a>`)
	strLink = "http://wartank.ru/missions/" + lstLink[0]
	lstMissions, err := sf.net.Get(strLink)
	if err != nil {
		// log._rintf("ERRO Missions.kill3tanks(): при выполнении GET-запроса, err=\n\t%v\n", err)
		return
	}
	if err := sf.Update(lstMissions); err != nil {
		// log._rintf("ERRO Missions.kill3tanks(): при обновлении lstMissions, err=\n\t%v\n", err)
		return
	}
}

// Проверяет награду оборонительного сражения
func (sf *Missions) battleDefence() {
	var (
		strOut      string
		lstMissions = sf.GetLst()
		isFind      bool
		ind         int
	)
	for ind, strOut = range lstMissions {
		if strings.Contains(strOut, `Проведи одно оборонительное сражение<br/>`) {
			isFind = true
			break
		}
	}
	if !isFind {
		return
	}
	// <a class="simple-but border" href="?70-1.ILinkListener-missions-cc-0-c-awardLink"><span><span>Получить награду</span></span></a>
	ind += 23
	strOut = lstMissions[ind]
	if !strings.Contains(strOut, `>Получить награду<`) {
		return
	}
	lstLink := strings.Split(strOut, `<a class="simple-but border" href="`)
	strLink := lstLink[1]
	lstLink = strings.Split(strLink, `"><span><span>Получить награду</span></span></a>`)
	strLink = "http://wartank.ru/missions/" + lstLink[0]
	lstMissions, err := sf.net.Get(strLink)
	if err != nil {
		// log._rintf("ERRO Missions.battleDefence(): при выполнении GET-запроса, err=\n\t%v\n", err)
		return
	}
	if err := sf.Update(lstMissions); err != nil {
		// log._rintf("ERRO Missions.battleDefence(): при обновлении lstMissions, err=\n\t%v\n", err)
		return
	}
}

// Проверяет награду за одну войну
func (sf *Missions) battleWar() {
	var (
		strOut      string
		lstMissions = sf.GetLst()
		isFind      bool
		ind         int
	)
	for ind, strOut = range lstMissions {
		if strings.Contains(strOut, `Проведи одну войну<br/>`) {
			isFind = true
			break
		}
	}
	if !isFind {
		return
	}
	// <a class="simple-but border" href="?70-1.ILinkListener-missions-cc-0-c-awardLink"><span><span>Получить награду</span></span></a>
	ind += 23
	strOut = lstMissions[ind]
	if !strings.Contains(strOut, `>Получить награду<`) {
		return
	}
	lstLink := strings.Split(strOut, `<a class="simple-but border" href="`)
	strLink := lstLink[1]
	lstLink = strings.Split(strLink, `"><span><span>Получить награду</span></span></a>`)
	strLink = "http://wartank.ru/missions/" + lstLink[0]
	lstMissions, err := sf.net.Get(strLink)
	if err != nil {
		// log._rintf("ERRO Missions.battleWar(): при выполнении GET-запроса, err=\n\t%v\n", err)
		return
	}
	if err := sf.Update(lstMissions); err != nil {
		// log._rintf("ERRO Missions.battleWar(): при обновлении lstMissions, err=\n\t%v\n", err)
		return
	}
}

// Проверяет награду наступательного сражения
func (sf *Missions) battleAttack() {
	var (
		strOut      string
		lstMissions = sf.GetLst()
		isFind      bool
		ind         int
	)
	for ind, strOut = range lstMissions {
		if strings.Contains(strOut, `Проведи одно наступательное сражение<br/>`) {
			isFind = true
			break
		}
	}
	if !isFind {
		return
	}
	// <a class="simple-but border" href="?70-1.ILinkListener-missions-cc-0-c-awardLink"><span><span>Получить награду</span></span></a>
	ind += 23
	strOut = lstMissions[ind]
	if !strings.Contains(strOut, `>Получить награду<`) {
		return
	}
	lstLink := strings.Split(strOut, `<a class="simple-but border" href="`)
	strLink := lstLink[1]
	lstLink = strings.Split(strLink, `"><span><span>Получить награду</span></span></a>`)
	strLink = "http://wartank.ru/missions/" + lstLink[0]
	lstMissions, err := sf.net.Get(strLink)
	if err != nil {
		// log._rintf("ERRO Missions.battleAttack(): при выполнении GET-запроса, err=\n\t%v\n", err)
		return
	}
	if err := sf.Update(lstMissions); err != nil {
		// log._rintf("ERRO Missions.battleAttack(): при обновлении lstMissions, err=\n\t%v\n", err)
		return
	}
}

// Проверяет награду за схватку
func (sf *Missions) battleDogFyting() {
	var (
		strOut      string
		lstMissions = sf.GetLst()
		isFind      bool
		ind         int
	)
	for ind, strOut = range lstMissions {
		if strings.Contains(strOut, `Проведи одну схватку<br/>`) {
			isFind = true
			break
		}
	}
	if !isFind {
		return
	}
	// <a class="simple-but border" href="?70-1.ILinkListener-missions-cc-0-c-awardLink"><span><span>Получить награду</span></span></a>
	ind += 23
	strOut = lstMissions[ind]
	if !strings.Contains(strOut, `>Получить награду<`) {
		return
	}
	lstLink := strings.Split(strOut, `<a class="simple-but border" href="`)
	strLink := lstLink[1]
	lstLink = strings.Split(strLink, `"><span><span>Получить награду</span></span></a>`)
	strLink = "http://wartank.ru/missions/" + lstLink[0]
	lstMissions, err := sf.net.Get(strLink)
	if err != nil {
		// log._rintf("ERRO Missions.battleDogFyting(): при выполнении GET-запроса, err=\n\t%v\n", err)
		return
	}
	if err := sf.Update(lstMissions); err != nil {
		// log._rintf("ERRO Missions.battleDogFyting(): при обновлении lstMissions, err=\n\t%v\n", err)
		return
	}
}

// Проверяет награду за ресурсы
func (sf *Missions) makeResource() {
	var (
		strOut      string
		lstMissions = sf.GetLst()
		isFind      bool
		ind         int
	)
	for ind, strOut = range lstMissions {
		if strings.Contains(strOut, `Произведи на базе 10 ресурсов<br/>`) {
			isFind = true
			break
		}
	}
	if !isFind {
		return
	}
	// <a class="simple-but border" href="?70-1.ILinkListener-missions-cc-0-c-awardLink"><span><span>Получить награду</span></span></a>
	ind += 23
	strOut = lstMissions[ind]
	if !strings.Contains(strOut, `>Получить награду<`) {
		return
	}
	lstLink := strings.Split(strOut, `<a class="simple-but border" href="`)
	strLink := lstLink[1]
	lstLink = strings.Split(strLink, `"><span><span>Получить награду</span></span></a>`)
	strLink = "http://wartank.ru/missions/" + lstLink[0]
	lstMissions, err := sf.net.Get(strLink)
	if err != nil {
		// log._rintf("ERRO Missions.makeResource(): при выполнении GET-запроса, err=\n\t%v\n", err)
		return
	}
	if err := sf.Update(lstMissions); err != nil {
		// log._rintf("ERRO Missions.makeResource(): при обновлении lstMissions, err=\n\t%v\n", err)
		return
	}
}

// Проверяет награду за ресурсы
func (sf *Missions) upMan() {
	var (
		strOut      string
		lstMissions = sf.GetLst()
		isFind      bool
		ind         int
	)
	for ind, strOut = range lstMissions {
		if strings.Contains(strOut, `Прокачай экипаж на 100 опыта экипажа<br/>`) {
			isFind = true
			break
		}
	}
	if !isFind {
		return
	}
	// <a class="simple-but border" href="?70-1.ILinkListener-missions-cc-0-c-awardLink"><span><span>Получить награду</span></span></a>
	ind += 23
	strOut = lstMissions[ind]
	if !strings.Contains(strOut, `>Получить награду<`) {
		return
	}
	lstLink := strings.Split(strOut, `<a class="simple-but border" href="`)
	strLink := lstLink[1]
	lstLink = strings.Split(strLink, `"><span><span>Получить награду</span></span></a>`)
	strLink = "http://wartank.ru/missions/" + lstLink[0]
	lstMissions, err := sf.net.Get(strLink)
	if err != nil {
		// log._rintf("ERRO Missions.upMan(): при выполнении GET-запроса, err=\n\t%v\n", err)
		return
	}
	if err := sf.Update(lstMissions); err != nil {
		// log._rintf("ERRO Missions.upMan(): при обновлении lstMissions, err=\n\t%v\n", err)
		return
	}
	// log._rintf("INFO Missions.upMan(): награда получена\n")
}

// Проверяет награду за топливо
func (sf *Missions) makeFuel() {
	var (
		strOut      string
		lstMissions = sf.GetLst()
		isFind      bool
		ind         int
	)
	for ind, strOut = range lstMissions {
		if strings.Contains(strOut, `Получи топливо в дивизии<br/>`) {
			isFind = true
			break
		}
	}
	if !isFind {
		return
	}
	// <a class="simple-but border" href="?157-1.ILinkListener-missions-cc-0-c-awardLink"><span><span>Получить награду</span></span></a>
	ind += 19
	strOut = lstMissions[ind]
	if !strings.Contains(strOut, `>Получить награду</`) {
		return
	}
	lstLink := strings.Split(strOut, `<a class="simple-but border" href="`)
	strLink := lstLink[1]
	lstLink = strings.Split(strLink, `"><span><span>Получить награду</span></span></a>`)
	strLink = "http://wartank.ru/missions/" + lstLink[0]
	lstMissions, err := sf.net.Get(strLink)
	if err != nil {
		// log._rintf("ERRO Missions.makeFuel(): при выполнении GET-запроса, err=\n\t%v\n", err)
		return
	}
	if err := sf.Update(lstMissions); err != nil {
		// log._rintf("ERRO Missions.makeFuel(): при обновлении lstMissions, err=\n\t%v\n", err)
		return
	}
	// log._rintf("INFO Missions.makeFuel(): награда получена")
}

// Проверяет награду 5 боёв
func (sf *Missions) battle5Fiting() {
	var (
		strOut      string
		lstMissions = sf.GetLst()
		isFind      bool
		ind         int
	)
	for ind, strOut = range lstMissions {
		if strings.Contains(strOut, `Проведи 5 боев<br/>`) {
			isFind = true
			break
		}
	}
	if !isFind {
		return
	}
	// <a class="simple-but border" href="?113-1.ILinkListener-missions-cc-0-c-awardLink"><span><span>Получить награду</span></span></a>
	ind += 23
	strOut = lstMissions[ind]
	if !strings.Contains(strOut, `>Получить награду<`) {
		return
	}
	lstLink := strings.Split(strOut, `<a class="simple-but border" href="`)
	strLink := lstLink[1]
	lstLink = strings.Split(strLink, `"><span><span>Получить награду</span></span></a>`)
	strLink = "http://wartank.ru/missions/" + lstLink[0]
	lstMissions, err := sf.net.Get(strLink)
	if err != nil {
		// log._rintf("ERRO Missions.battle5Fiting(): при выполнении GET-запроса, err=\n\t%v\n", err)
		return
	}
	if err := sf.Update(lstMissions); err != nil {
		// log._rintf("ERRO Missions.battle5Fiting(): при обновлении lstMissions, err=\n\t%v\n", err)
		return
	}
}

// Проверяет награду 10 боёв
func (sf *Missions) battle10Fiting() {
	var (
		strOut      string
		lstMissions = sf.GetLst()
		isFind      bool
		ind         int
	)
	for ind, strOut = range lstMissions {
		if strings.Contains(strOut, `Уничтожь в бою 10 танков<br/>`) {
			isFind = true
			break
		}
	}
	if !isFind {
		return
	}
	// <a class="simple-but border" href="?113-1.ILinkListener-missions-cc-0-c-awardLink"><span><span>Получить награду</span></span></a>
	ind += 23
	strOut = lstMissions[ind]
	if !strings.Contains(strOut, `>Получить награду<`) {
		return
	}
	lstLink := strings.Split(strOut, `<a class="simple-but border" href="`)
	strLink := lstLink[1]
	lstLink = strings.Split(strLink, `"><span><span>Получить награду</span></span></a>`)
	strLink = "http://wartank.ru/missions/" + lstLink[0]
	lstMissions, err := sf.net.Get(strLink)
	if err != nil {
		// log._rintf("ERRO Missions.battle10Fiting(): при выполнении GET-запроса, err=\n\t%v\n", err)
		return
	}
	if err := sf.Update(lstMissions); err != nil {
		// log._rintf("ERRO Missions.battle10Fiting(): при обновлении lstMissions, err=\n\t%v\n", err)
		return
	}
}

// Проверяет награду за 6 побед подряд
func (sf *Missions) battle6win() {
	var (
		strOut      string
		lstMissions = sf.GetLst()
		isFind      bool
		ind         int
	)
	for ind, strOut = range lstMissions {
		if strings.Contains(strOut, `Победи 6 раз подряд<br/>`) {
			isFind = true
			break
		}
	}
	if !isFind {
		return
	}
	// <a class="simple-but border" href="?113-1.ILinkListener-missions-cc-0-c-awardLink"><span><span>Получить награду</span></span></a>
	ind += 25
	strOut = lstMissions[ind]
	if !strings.Contains(strOut, `>Получить награду<`) {
		return
	}
	lstLink := strings.Split(strOut, `<a class="simple-but border" href="`)
	strLink := lstLink[1]
	lstLink = strings.Split(strLink, `"><span><span>Получить награду</span></span></a>`)
	strLink = "http://wartank.ru/missions/" + lstLink[0]
	lstMissions, err := sf.net.Get(strLink)
	if err != nil {
		// log._rintf("ERRO Missions.battle6win(): при выполнении GET-запроса, err=\n\t%v\n", err)
		return
	}
	if err := sf.Update(lstMissions); err != nil {
		// log._rintf("ERRO Missions.battle6win(): при обновлении lstMissions, err=\n\t%v\n", err)
		return
	}
}
