package netstat

import (
	"fmt"
	// "log"
	"strconv"
	"strings"

	"wartank/pkg/types"
)

/*
	Исходник предоставляет тип для парсинга статистики уровня танка и сервера.
*/

// NetStat -- статистика уровня танка и сервера
type NetStat struct {
	server types.IServer
	bot    types.IServBot
}

// NewNetStat -- возвращает новый *NetStat
func NewNetStat(server types.IServer, bot types.IServBot) (*NetStat, error) {
	if server == nil {
		return nil, fmt.Errorf("NewNetStat(): IServer == nil")
	}
	if bot == nil {
		return nil, fmt.Errorf("NewNetStat(): IServBot == nil")
	}
	sf := &NetStat{
		server: server,
		bot:    bot,
	}
	return sf, nil
}

func (sf *NetStat) Update() (err error) {
	// _mt.Println("\n===NetStat.Update()===")
	sf.findLevelTank()
	if err = sf.findLevelProgress(); err != nil {
		return fmt.Errorf("NetStat.Update(): in find level progress, err=\n\t%w", err)
	}
	if err = sf.findAtack(); err != nil {
		return fmt.Errorf("NetStat.Update(): in find atack, err=\n\t%w", err)
	}
	if err = sf.findArmor(); err != nil {
		return fmt.Errorf("NetStat.Update(): in find woll, err=\n\t%w", err)
	}
	if err = sf.findFyne(); err != nil {
		return fmt.Errorf("NetStat.Update(): in find woll, err=\n\t%w", err)
	}
	if err = sf.findHard(); err != nil {
		return fmt.Errorf("NetStat.Update(): in find body, err=\n\t%w", err)
	}
	if err = sf.findPower(); err != nil {
		return fmt.Errorf("NetStat.Update(): in find power, err=\n\t%w", err)
	}
	if err = sf.findOnline(); err != nil {
		return fmt.Errorf("NetStat.Update(): in find online, err=\n\t%w", err)
	}
	return nil
}

// Ищет в теле текста ангара мощность танка
func (sf *NetStat) findPower() (err error) {
	// _mt.Println("\tNetStat.findPower()")
	lstAngar := sf.bot.Angar().GetLst()
	if len(lstAngar) == 0 {
		// log._rintf("WARN NetStat.findPower(): lstAngar is empty\n")
		return
	}
	var strOut string
	for _, strPower := range lstAngar {
		if strings.Contains(strPower, `/images/icons/power.png?2`) {
			strOut = strPower
			break
		}
	}
	// Выделить мощность
	lstPower := strings.Split(strOut, `<img src="/images/icons/power.png?2" height="14" width="14"> <span class="green2">Танковая мощь: `)
	strPower := lstPower[1]
	lstPower = strings.Split(strPower, `</span>`)
	strPower = lstPower[0]
	iPower, err := strconv.Atoi(strPower)
	if err != nil {
		return fmt.Errorf("NetStat.findPower(): power(%v) not number, err=\n\t%w", strPower, err)
	}
	sf.bot.Tank().TankStat().Power().Set(iPower)
	return nil
}

// Ищет в теле текста ангара прочность танка
func (sf *NetStat) findHard() (err error) {
	var (
		strOut   string
		lstAngar = sf.bot.Angar().GetLst()
		isFind   bool
	)
	if len(lstAngar) == 0 {
		// log._rintf("WARN NetStat.findHard(): lstAngar пустой\n")
		return
	}
	for _, strOut = range lstAngar {
		if strings.Contains(strOut, `/images/icons/durability.png?1`) {
			isFind = true
			break
		}
	}
	if !isFind {
		return
	}
	// Выделить прочность
	lstHard := strings.Split(strOut, `<img width="14" height="14" src="/images/icons/durability.png?1" alt="Прочность" title="Прочность"/> Прочность <span class="green2">`)
	strHard := lstHard[1]
	lstHard = strings.Split(strHard, `</span><br/>`)
	strHard = lstHard[0]
	iHard, err := strconv.Atoi(strHard)
	if err != nil {
		return fmt.Errorf("NetStat.findHard(): hard(%v) not number, err=\n\t%w", strHard, err)
	}
	sf.bot.Tank().TankStat().Hard().Set(iHard)
	return nil
}

// Ищет в теле текста ангара точность танка
func (sf *NetStat) findFyne() (err error) {
	// _mt.Println("\tNetStat.findFyne()")
	var (
		strOut   string
		lstAngar = sf.bot.Angar().GetLst()
		isFind   bool
	)
	if len(lstAngar) == 0 {
		// log._rintf("WARN NetStat.findFyne(): lstAngar пустой\n")
		return
	}
	for _, strOut = range lstAngar {
		if strings.Contains(strOut, `/images/icons/accuracy.png?1`) {
			isFind = true
			break
		}
	}
	if !isFind {
		return nil
	}
	// Выделить броню
	lstFyne := strings.Split(strOut, `<img width="14" height="14" src="/images/icons/accuracy.png?1" alt="Точность" title="Точность"/> Точность <span class="green2">`)
	strFyne := lstFyne[1]
	lstFyne = strings.Split(strFyne, `</span><br/>`)
	strFyne = lstFyne[0]
	iFyne, err := strconv.Atoi(strFyne)
	if err != nil {
		return fmt.Errorf("NetStat.findFyne(): fyne(%v) not number, err=\n\t%w", strFyne, err)
	}
	sf.bot.Tank().TankStat().Fyne().Set(iFyne)
	return nil
}

// Ищет в теле текста ангара броню танка
func (sf *NetStat) findArmor() (err error) {
	// _mt.Println("\tNetStat.findArmor()")

	var (
		strOut   string
		lstAngar = sf.bot.Angar().GetLst()
		isFind   bool
	)
	if len(lstAngar) == 0 {
		return nil
	}
	for _, strOut = range lstAngar {
		if strings.Contains(strOut, `/images/icons/armor.png?1`) {
			isFind = true
			break
		}
	}
	if !isFind {
		return
	}
	// Выделить броню
	lstArmor := strings.Split(strOut, `<img width="14" height="14" src="/images/icons/armor.png?1" alt="Броня" title="Броня"/> Броня <span class="green2">`)
	strArmor := lstArmor[1]
	lstArmor = strings.Split(strArmor, `</span><br/>`)
	strArmor = lstArmor[0]
	iArmor, err := strconv.Atoi(strArmor)
	if err != nil {
		return fmt.Errorf("NetStat.findArmor(): armor(%v) not number, err=\n\t%w", strArmor, err)
	}
	sf.bot.Tank().TankStat().Armor().Set(iArmor)
	return nil
}

// Ищет в теле текста ангара уровень танка
func (sf *NetStat) findLevelTank() {
	// _mt.Println("\tNetStat.findLevelTank()")
	lstAngar := sf.bot.Angar().GetLst()
	if len(lstAngar) == 0 {
		// log._rintf("ERRO NetStat.findLevelTank(): пустой lstAngar")
		return
	}
	var strOut string
	for _, strLevel := range lstAngar {
		if strings.Contains(strLevel, "/images/icons/level.png?2") {
			strOut = strLevel
			break
		}
	}
	// Выделить уровень
	lstLevel := strings.Split(strOut, `<td><div class="value-block lh1"><span><span><img height="14" width="14" src="/images/icons/level.png?2"/> `)
	strLevel := lstLevel[1]
	lstLevel = strings.Split(strLevel, `</span></span></div></td>`)
	strLevel = lstLevel[0]
	iLevel, err := strconv.Atoi(strLevel)
	if err != nil {
		// log._rintf("ERRO NetStat.findLevelTank(): level(%v) не число, err=\n\t%v\n", strLevel, err)
		return
	}
	sf.bot.Angar().Level().Set(iLevel)
}

// Ищет в теле текста ангара прогресс уровня танка танка
func (sf *NetStat) findLevelProgress() error {
	// _mt.Println("\tNetStat.findLevelProgress()")
	lstAngar := sf.bot.Angar().GetLst()
	if len(lstAngar) == 0 {
		// log._rintf("WARN NetStat.findLevelProgress(): lstAngar пустой\n")
		return nil
	}
	var strOut string
	for _, strProg := range lstAngar {
		if strings.Contains(strProg, `class="progr"`) {
			strOut = strProg
			break
		}
	}
	// Выделить прогресс
	lstProg := strings.Split(strOut, `<td class="progr"><div class="scale-block"><div class="scale" style="width:`)
	strProg := lstProg[1]
	lstProg = strings.Split(strProg, `%;">&nbsp;</div></div></td>`)
	strProg = lstProg[0]
	iProg, err := strconv.Atoi(strProg)
	if err != nil {
		return fmt.Errorf("NetStat.findLevelProgress(): progress(%v) not number, err=\n\t%w", strProg, err)
	}
	sf.bot.Angar().Progress().Set(iProg)
	return nil
}

// Ищет в теле текста ангара силу атаки танка
func (sf *NetStat) findAtack() (err error) {
	var (
		strOut   string
		lstAngar = sf.bot.Angar().GetLst()
		isFind   bool
	)
	for _, strOut = range lstAngar {
		if strings.Contains(strOut, `/images/icons/attack.png?1`) {
			isFind = true
			break
		}
	}
	if !isFind {
		return nil
	}
	// Выделить атаку
	lstAtack := strings.Split(strOut, `<img width="14" height="14" src="/images/icons/attack.png?1" alt="Атака" title="Атака"/> Атака <span class="green2">`)
	strAtack := lstAtack[1]
	lstAtack = strings.Split(strAtack, `</span><br/>`)
	strAtack = lstAtack[0]
	iAtack, err := strconv.Atoi(strAtack)
	if err != nil {
		return fmt.Errorf("NetStat.findAtack(): atack(%v) not number, err=\n\t%w", strAtack, err)
	}
	sf.bot.Tank().TankStat().Attack().Set(iAtack)
	return nil
}

// Ищет в теле текста ангара силу атаки танка
func (sf *NetStat) findOnline() (err error) {
	// _mt.Println("\tNetStat.findOnline()")
	lstAngar := sf.bot.Angar().GetLst()
	var strOut string
	for _, strAtack := range lstAngar {
		if strings.Contains(strAtack, `>Онлайн</a>: `) {
			strOut = strAtack
			break
		}
	}
	// Выделить число игроков онлайн
	lstAngar = strings.Split(strOut, `<span class="yellow1">`)
	if len(lstAngar) <= 1 {
		sf.server.CancelApp()
		return
	}
	strOnline := lstAngar[1]
	lstAngar = strings.Split(strOnline, `</span>`)
	strOnline = lstAngar[0]
	iOnline, err := strconv.Atoi(strOnline)
	if err != nil {
		return fmt.Errorf("NetStat.findOnline(): online(%v) not number, err=\n\t%w", iOnline, err)
	}
	sf.bot.Angar().Online().Set(iOnline)
	return nil
}
