package arsenal

import (
	"fmt"
	"strconv"
	"strings"
	"time"

	"wartank/pkg/components/section"
	"wartank/pkg/types"
	"wartank/server/serv_bots/warbot/angar/base/arsenal/arsenalnet"
	"wartank/server/serv_bots/warbot/tank/tankstat/static_param"
)

/*
	Объект арсенала на базе
*/

// Арсенал -- объект арсенала на базе
type Арсенал struct {
	*section.Section
	бот        types.ИБот
	база       types.ИБаза
	сеть       *arsenalnet.ArsenalNet
	фугас      types.ИСтатПарам
	бронебойка types.ИСтатПарам
	кумулятив  types.ИСтатПарам
	ремка      types.ИСтатПарам
}

// НовАрсенал -- возвращает новый *Arsenal
func НовАрсенал(base types.ИБаза) (*Арсенал, error) {
	section, err := section.NewSection(base.Бот(), "Арсенал", `<span class="green2">Ремкомплект</span><br/>`)
	if err != nil {
		return nil, fmt.Errorf("NewArsenal(): in create ISection, err=\n\t%w", err)
	}

	фугас, ош := static_param.НовСтатПарам("fugas")
	if ош != nil {
		return nil, fmt.Errorf("NewArsenal(): при создании статистики фугасов, ош=\n\t%w", ош)
	}
	бронейбойки, ош := static_param.НовСтатПарам("armor")
	if ош != nil {
		return nil, fmt.Errorf("NewArsenal(): при создании статистики бронебоек, ош=\n\t%w", ош)
	}
	кумулятив, ош := static_param.НовСтатПарам("kumul")
	if ош != nil {
		return nil, fmt.Errorf("NewArsenal(): при создании статистики  кумулятивов, ош=\n\t%w", ош)
	}
	ремка, ош := static_param.НовСтатПарам("remka")
	if ош != nil {
		return nil, fmt.Errorf("NewArsenal(): при создании статистики  ремок, ош=\n\t%w", ош)
	}
	сам := &Арсенал{
		Section:    section,
		бот:        base.Бот(),
		база:       base,
		фугас:      фугас,
		бронебойка: бронейбойки,
		кумулятив:  кумулятив,
		ремка:      ремка,
	}
	{ // ArsenalNet
		сам.сеть, err = arsenalnet.НовАрсеналСеть(сам)
		if err != nil {
			return nil, fmt.Errorf("NewArsenal(): in create NetArsenal, err=\n\t%w", err)
		}
	}
	_ = types.ИАрсенал(сам)
	return сам, nil
}

func (сам *Арсенал) Run() error {

	go сам.run()
	return nil
}

// запускает обработку арсенала
func (sf *Арсенал) run() {
	// sf.getTime()
	for {
		select {
		case <-sf.бот.Кнт().Done():
			sf.ВремяОпрос().Стоп()
			return
		case <-sf.ВремяОпрос().КаналСиг():
			if sf.РежимТекущ().Получ() == "upgrade" {
				continue
			}
			// if err := sf.updateArsenal(); err != nil {
			// 	return fmt.Errorf("ArsenalNet.Run(): in update arsenal, err=\n\t%w", err)
			// }
			sf.makeArsenal()
		}
		time.Sleep(time.Second * 10)
	}
}

// Фугасы -- возвращает объект числа фугасов
func (sf *Арсенал) Фугасы() types.ИСтатПарам {
	return sf.фугас
}

// Бронебойки -- возвращает объект бронебойных снарядов
func (sf *Арсенал) Бронебойки() types.ИСтатПарам {
	return sf.бронебойка
}

// Кумулятивы -- возвращает объект бронебойных снарядов
func (sf *Арсенал) Кумулятивы() types.ИСтатПарам {
	return sf.кумулятив
}

// Ремки -- возвращает объект ремкомплектов
func (sf *Арсенал) Ремки() types.ИСтатПарам {
	return sf.ремка
}

// Обновляет состояние арсенала по требованию
func (sf *Арсенал) UpdateArsenal() (err error) {
	// _mt.Println("\tArsenalNet.updateArsenal()")
	if err := sf.сеть.UpdateLst(); err != nil {
		return fmt.Errorf("Arsenal.UpdateArsenal(): при обновлении lstArsenal, err=%w", err)
	}
	var (
		strOut     string
		lstArsenal = sf.СписПолучить()
	)
	{ // Найти маркер фугасного снаряда
		for _, strFugas := range lstArsenal {
			if strings.Contains(strFugas, `<span class="nwr"><img class="rico vm" src="/images/shells/HighExplosive.png" alt="Фугасный снаряд" title="Фугасный снаряд"/> `) {
				strOut = strFugas
				break
			}
		}
		lstFugas := strings.Split(strOut, `<span class="nwr"><img class="rico vm" src="/images/shells/HighExplosive.png" alt="Фугасный снаряд" title="Фугасный снаряд"/> `)
		strFugas := lstFugas[1]
		lstFugas = strings.Split(strFugas, ` &nbsp;&nbsp;</span>`)
		strFugas = lstFugas[0]
		iFugas, err := strconv.Atoi(strFugas)
		if err != nil {
			return fmt.Errorf("ArsenalNet.updateArsenal(): fugas(%v) not number, err=\n\t%w", strFugas, err)
		}
		sf.Фугасы().Уст(iFugas)
	}
	{ // Найти маркер бронебойного снаряда
		for _, strArmor := range lstArsenal {
			if strings.Contains(strArmor, `alt="Бронебойный снаряд"`) {
				strOut = strArmor
				break
			}
		}
		lstArmor := strings.Split(strOut, `<span class="nwr"><img class="rico vm" src="/images/shells/ArmorPiercing.png" alt="Бронебойный снаряд" title="Бронебойный снаряд"/> `)
		strArmor := lstArmor[1]
		lstArmor = strings.Split(strArmor, ` &nbsp;&nbsp;</span>`)
		strArmor = lstArmor[0]
		iArmor, err := strconv.Atoi(strArmor)
		if err != nil {
			return fmt.Errorf("ArsenalNet.updateArsenal(): armor(%v) not number, err=\n\t%w", strArmor, err)
		}
		sf.Бронебойки().Уст(iArmor)
	}
	{ // Найти маркер кумулятивного снаряда
		for _, strKumul := range lstArsenal {
			if strings.Contains(strKumul, `<span class="nwr"><img class="rico vm" src="/images/shells/HollowCharge.png" alt="Кумулятивный снаряд" title="Кумулятивный снаряд"/> `) {
				strOut = strKumul
				break
			}
		}
		lstKumul := strings.Split(strOut, `<span class="nwr"><img class="rico vm" src="/images/shells/HollowCharge.png" alt="Кумулятивный снаряд" title="Кумулятивный снаряд"/> `)
		strKumul := lstKumul[1]
		lstKumul = strings.Split(strKumul, ` &nbsp;&nbsp;</span>`)
		strKumul = lstKumul[0]
		iKumul, err := strconv.Atoi(strKumul)
		if err != nil {
			return fmt.Errorf("ArsenalNet.updateArsenal(): kumul(%v) not number, err=\n\t%w", strKumul, err)
		}
		sf.Кумулятивы().Уст(iKumul)
	}
	{ // Найти маркер ремкомплекта
		for ind, strRemka := range lstArsenal {
			if strings.Contains(strRemka, `<span class="nwr"><img class="rico vm" src="/images/shells/repairkit.gif"/> `) {
				strOut = lstArsenal[ind]
				break
			}
		}
		lstRemka := strings.Split(strOut, `<span class="nwr"><img class="rico vm" src="/images/shells/repairkit.gif"/> `)
		strRemka := lstRemka[1]
		lstRemka = strings.Split(strRemka, `</span>`)
		strRemka = lstRemka[0]
		iRemka, err := strconv.Atoi(strRemka)
		if err != nil {
			return fmt.Errorf("ArsenalNet.updateArsenal(): remka(%v) not number, err=\n\t%w", strRemka, err)
		}
		sf.Ремки().Уст(iRemka)
	}
	return nil
}

// Выбирает что надо делать, запускает процесс изготовления
func (sf *Арсенал) makeArsenal() {
	err := sf.сеть.UpdateLst()
	if err != nil {
		// log._rintf("ERRO Arsenal.Run(): при обновлении lstArsenal, err=\n\t%v\n", err)
		return
	}
	fnMakeRemka := func() {
		if err = sf.makeRemka(); err != nil {
			// log._rintf("ERRO ArsenalNet.makeArsenal(): in make remka, err=\n\t%v\n", err)
			return
		}
	}
	// _mt.Println("\tArsenalNet.makeArsenal()")
	{ // Контроль ремки по времени суток и минимальному количеству
		iRemka := sf.Ремки().Получ()
		if iRemka < 70 {
			fnMakeRemka()
			return
		}
	}
	{ // Контроль по числу снарядов. В равных долях без приоритетов
		iFugas := sf.Фугасы().Получ()
		iKumul := sf.Кумулятивы().Получ()
		iArmor := sf.Бронебойки().Получ()

		typeArmor := "fugas"
		typeVal := iFugas

		if iKumul < typeVal {
			typeArmor = "kumul"
			typeVal = iKumul
		}

		if iArmor < typeVal {
			typeArmor = "armor"
		}
		switch typeArmor {
		case "fugas": // Мало фугасов
			sf.makeFugas()
		case "kumul": // Мало кумулятивов
			sf.makeKumul()
		case "armor": // Мало бронебойных
			sf.makeArmor()
		default:
			// log._rintf("ERRO ArsenalNet.makeArsenal(): неизвестный тип арсенала(%v)", typeArmor)
		}
	}
}

// Создать бронебойные
func (sf *Арсенал) makeArmor() {
	var (
		strOut     string
		lstArsenal = sf.СписПолучить()
		isFind     bool
	)
	for ind, strArmor := range lstArsenal {
		if strings.Contains(strArmor, `<span class="green2">Бронебойный снаряд</span><br/>`) {
			strOut = lstArsenal[ind+10]
			isFind = true
			break
		}
	}
	if !isFind {
		return
	}
	if strOut == `<div class="clrb"></div>` { // Уже запущено производство
		return
	}
	if strOut == `</div></div></div></div></div></div></div></div>` { // Уже запущено производство
		return
	}
	// Получить ссылку на бронебойные
	lstArmor := strings.Split(strOut, `<a class="simple-but border" href="`)
	strLink := lstArmor[1]
	lstArmor = strings.Split(strLink, `"><span><span>Начать производство</span></span></a>`)
	strLink = "http://wartank.ru/production/" + lstArmor[0]
	if _, err := sf.сеть.Get(strLink); err != nil {
		// log._rintf("ERRO ArsenalNet.makeArmor(): in update lstArsenal,  err=\n\t%v\n", err)
		return
	}
	sf.РежимТекущ().РежимУст("бронебойные")
}

// Создать кумулятивные
func (sf *Арсенал) makeKumul() {
	var (
		strOut     string
		lstArsenal = sf.СписПолучить()
		isFind     bool
		ind        int
	)
	for ind, strOut = range lstArsenal {
		if strings.Contains(strOut, `<span class="green2">Кумулятивный снаряд</span><br/>`) {
			ind += 10
			strOut = lstArsenal[ind]
			isFind = true
			break
		}
	}
	if !isFind {
		return
	}
	if !strings.Contains(strOut, `>Начать производство<`) {
		return
	}
	// Получить ссылку на кумулятив
	lstKumul := strings.Split(strOut, `<a class="simple-but border" href="`)
	strLink := lstKumul[1]
	lstKumul = strings.Split(strLink, `"><span><span>Начать производство</span></span></a>`)
	strLink = "http://wartank.ru/production/" + lstKumul[0]
	if _, err := sf.сеть.Get(strLink); err != nil {
		// log._rintf("ERRO ArsenalNet.makeKumul(): in make product arsenal kumul , err=\n\t%v\n", err)
		return
	}
	sf.РежимТекущ().РежимУст("кумулятивы")
}

// Создать фугасы
func (sf *Арсенал) makeFugas() {
	var (
		lstArsenal = sf.СписПолучить()
		strOut     = ""
		isFind     bool
		ind        int
	)

	for ind, strOut = range lstArsenal {
		if strings.Contains(strOut, `<span class="green2">Фугасный снаряд</span><br/>`) {
			strOut = lstArsenal[ind+10]
			isFind = true
			break
		}
	}
	if !isFind {
		return
	}
	if !strings.Contains(strOut, `"><span><span>Начать производство</span></span></a>`) {
		return
	}
	// Получить ссылку на ремку
	lstKumul := strings.Split(strOut, `<a class="simple-but border" href="`)
	strLink := lstKumul[1]
	lstKumul = strings.Split(strLink, `"><span><span>Начать производство</span></span></a>`)
	strLink = "http://wartank.ru/production/" + lstKumul[0]
	if _, err := sf.сеть.Get(strLink); err != nil {
		// log._rintf("ERRO ArsenalNet.makeFugas(): in make request arsenal product, err=\n\t%v\n", err)
		return
	}
	sf.РежимТекущ().РежимУст("фугасы")
	// log._rintf("INFO Arsenal.makeFugas()\n")
}

// Создать ремку. Выполняется если подходят условия
func (sf *Арсенал) makeRemka() (err error) {
	// _mt.Println("\tArsenalNet.makeRemka()")
	var (
		strOut     = ""
		isFind     bool
		lstArsenal = sf.СписПолучить()
	)

	for ind, strRemka := range lstArsenal {
		if strings.Contains(strRemka, `<span class="green2">Ремкомплект</span><br/>`) {
			ind += 10
			strOut = lstArsenal[ind]
			isFind = true
			break
		}
	}
	if !isFind {
		return nil
	}
	// Получить ссылку на ремку
	lstRemka := strings.Split(strOut, `<a class="simple-but border" href="`)
	if len(lstRemka) < 2 { // Значит уже запущено в производство
		return
	}
	strLink := lstRemka[1]
	lstRemka = strings.Split(strLink, `"><span><span>Начать производство</span></span></a>`)
	strLink = "http://wartank.ru/production/Armory" + lstRemka[0]
	if _, err = sf.сеть.Get(strLink); err != nil {
		return fmt.Errorf("ArsenalNet.makeRemka(): in getpagebank product, err=\n\t%w", err)
	}
	sf.РежимТекущ().РежимУст("ремка")
	return nil
}
