// package fuel -- склад топлива
package fuel

import (
	"context"
	"log"
	"strconv"
	"strings"
	"time"
	"wartank/pkg/arena"
	"wartank/pkg/components/arena_net"
	"wartank/pkg/types"
	"wartank/server/serv_bots/warbot/stat_tank/static_param"
)

// СкладТоплива -- склад топлива
type СкладТоплива struct {
	types.ИАрена
	сеть         types.ИАренаСеть
	бот          types.ИБот
	база         types.ИБаза
	топливо      types.ИСтатПарам
	уровень      types.ИСтатПарам
	продуктВремя string          // Сколько осталось времени прямо сейчас
	кнт          context.Context // контекст шахты
	фнОтмена     func()          // Функция отмены шахты
}

// НовТопливо -- возвращает новой склад топлива
func НовСкладТоплива(база types.ИБаза) (*СкладТоплива, error) {
	кнт, фнОтмена := context.WithCancel(база.Контекст())
	сам := &СкладТоплива{
		бот:      база.Бот(),
		база:     база,
		топливо:  static_param.НовСтатПарам("топливо"),
		кнт:      кнт,
		фнОтмена: фнОтмена,
		уровень:  static_param.НовСтатПарам("уровень"),
	}
	аренаКонфиг := arena.АренаКонфиг{
		Бот_:         база.Бот(),
		АренаИмя_:    "Склад_топлива",
		СтрКонтроль_: `<span class="green2">Склад топлива - `,
		ФнПуск_:      сам.пуск,
		СтрУрл_:      "https://wartank.ru/angar",
	}
	сам.ИАрена = arena.НовАрена(аренаКонфиг)
	сам.сеть = arena_net.НовАренаСеть(сам, "https://wartank.ru/fuelStore")
	_ = types.ИБазаТопливо(сам)
	return сам, nil
}

func (сам *СкладТоплива) Пуск() error {
	go сам.пуск()
	return nil
}

// пуск -- запускает обработку шахты
func (сам *СкладТоплива) пуск() {
	time.Sleep(time.Second * 3)
	фнРабота := func() {
		defer time.Sleep(time.Minute * 30)
		for !сам.уровеньОбновить() {
		}
		сам.ускорениеПровер()
		сам.количествоПолучить()
	}
	for {
		select {
		case <-сам.кнт.Done():
			return
		case <-сам.ВремяОстат().КаналСиг():
		default:
			log.Printf("СкладТоплива.пуск()\n")
			фнРабота()
		}
	}
}

// Проверяет количество продукта в шахте
func (сам *СкладТоплива) количествоПолучить() {
	var (
		strOut      string
		еслиНайдено bool
	)
	lstMine := сам.сеть.ВебВоркер().Получ("https://wartank.ru/buildings")
	/*
		<img class="ico vm" src="/images/icons/fuel.png?2" alt="Топливо" title="Топливо"> 720
	*/
	for _, strOut = range lstMine {
		if strings.Contains(strOut, `src=" alt="Топливо" title="Топливо"`) {
			еслиНайдено = true
			break
		}
	}
	if !еслиНайдено {
		return
	}
	_число := strings.TrimPrefix(strOut, `<img class="ico vm" src="/images/icons/fuel.png?2" alt="Топливо" title="Топливо"> `)
	iNum, err := strconv.Atoi(_число)
	if err != nil {
		log.Printf("СкладТоплива.количествоПолучить(): кол-во топлива (%v) не число, err=\n\t%v\n", _число, err)
		return
	}
	сам.топливо.Уст(iNum)
}

// Проверяет ускорение строительства
func (сам *СкладТоплива) ускорениеПровер() {
	списСтр := сам.сеть.ВебВоркер().Получ("http://wartank.ru/buildings")
	// <span class="green2">Склад топлива -
	var (
		еслиНайти = false
		стр       string
	)
	for _, стр = range списСтр {
		if strings.Contains(стр, `<span class="green2">Склад топлива - `) {
			еслиНайти = true
			break
		}
	}
	if !еслиНайти {
		return
	}
}

// Обновляет текущий уровень шахты (может быть не построена)
func (сам *СкладТоплива) уровеньОбновить() bool {
	списСтр := сам.сеть.ВебВоркер().Получ("http://wartank.ru/buildings")
	// <span class="green2">Склад топлива -
	var (
		еслиНайти = false
		стр       = ""
	)
	for _, стр = range списСтр {
		if strings.Contains(стр, `<span class="green2">Склад топлива - `) {
			еслиНайти = true
			break
		}
	}
	if !еслиНайти {
		return false
	}
	// <span class="green2">Склад топлива - 0</span><br/>
	_стр := strings.TrimPrefix(стр, `<span class="green2">Склад топлива - `)
	_стр = strings.TrimSuffix(_стр, `</span><br/>`)
	иУровень, ош := strconv.Atoi(_стр)
	if ош != nil {
		log.Printf("СкладТоплива.уровеньОбновить(): строка уровня сбойная, стр=%q, ош=\n\t%v\n", стр, ош)
		return false
	}
	сам.уровень.Уст(иУровень)
	switch иУровень {
	case 0: // склад топлива надо построить
		for !сам.построить() {
		}
	default: // Может можно проапгрейдить
		счёт := 5
		for !сам.проапгрейдить() {
			счёт--
			if счёт == 0 {
				break
			}
		}
	}

	return true
}

// Пытается проапгрейдить топливный склад
func (сам *СкладТоплива) проапгрейдить() bool {
	time.Sleep(time.Millisecond * 1000)
	var (
		еслиНайти = false
		списСтр   []string
		стр       = ""
	)
	фнКупить := func() bool {
		defer time.Sleep(time.Millisecond * 1000)
		списСтр = сам.сеть.ВебВоркер().Получ("https://wartank.ru/building-upgrade/FuelStorage")
		for _, стр = range списСтр {
			// <a class="simple-but border mb5" href="FuelStorage?5-1.ILinkListener-upgradeLink-link">
			if strings.Contains(стр, `ILinkListener-upgradeLink-link`) {
				еслиНайти = true
				break
			}
		}
		if !еслиНайти {
			return true
		}
		// Пробуем улучшить шахту
		_стр := strings.TrimPrefix(стр, "<a class=\"simple-but border mb5\" href=\"")
		_стр = strings.TrimSuffix(_стр, "\">")
		// https://wartank.ru/building-upgrade/FuelStorage?4-1.ILinkListener-upgradeLink-link
		// <a class="simple-but border mb5" href="FuelStorage?50-1.ILinkListener-upgradeLink-link">
		ссылка := "https://wartank.ru/building-upgrade/" + _стр
		списСтр = сам.сеть.ВебВоркер().Получ(ссылка)
		// Проверить, что постройка состоялась
		for _, стр := range списСтр {
			if strings.Contains(стр, "ILinkListener-upgradeLink-link") {
				log.Printf("СкладТоплива.проапгрейдить().фнКупить(): покупка склада топлива не прошла\n\tlink=%v\n\tстр=\n\t%v\n", ссылка, стр)
				return false // Покупка не оплачена
			}
		}
		log.Printf("+++++СкладТоплива.проапгрейдить().фнКупить(): покупка склада топлива прошла\n")
		return true
	}

	фнПодтверждение := func() bool {
		for _, стр = range списСтр {
			// <a class="simple-but border w50 mXa mb10" w:id="confirmLink" href="../wicket/page?7-1.ILinkListener-confirmLink"><span><span>да, подтверждаю</span></span></a>
			if strings.Contains(стр, `ILinkListener-confirmLink`) {
				еслиНайти = true
				break
			}
		}
		if !еслиНайти {
			return true
		}
		// Пробуем построить шахту
		_стр := strings.TrimPrefix(стр, `<a class="simple-but border w50 mXa mb10" w:id="confirmLink" href="..`)
		_стр = strings.TrimSuffix(_стр, `"><span><span>да, подтверждаю</span></span></a>`)
		// https://wartank.ru/wicket/page?6-1.ILinkListener-confirmLink
		ссылка := "https://wartank.ru" + _стр
		списСтр = сам.сеть.ВебВоркер().Получ(ссылка)
		// Проверить, что постройка состоялась
		for _, стр := range списСтр {
			if strings.Contains(стр, "<title>Вы сделали слишком большую паузу</title>") {
				log.Printf("СкладТоплива.проапгрейдить().фнПодтверждение(): подтверждение покупка склада топлива не прошла\n\tlink=%v\n\tстр=\n\t%v\n", ссылка, стр)
				return false // Покупка не оплачена
			}
		}
		log.Printf("+++++СкладТоплива.проапгрейдить().фнПодтверждение(): подтверждение покупка склада топлива прошла\n")
		return true
	}

	фнКомплекс := func() {
		count := 5
		for count > 0 {
			if фнКупить() {
				if фнПодтверждение() {
					break
				}
			}
			count--
		}
	}
	фнКомплекс()
	return true
}

// Строит шахту при нулевом уровне
func (сам *СкладТоплива) построить() bool {
	time.Sleep(time.Millisecond * 1000)
	// <td style="width:50%;padding-left:1px;"><a class="simple-but border mb5" href="building-upgrade/FuelStorage"><span><span>Построить</span></span></a></td>
	var (
		еслиНайти = false
		списСтр   []string
		стр       = ""
	)
	фнКупить := func() bool {
		defer time.Sleep(time.Millisecond * 1000)
		списСтр = сам.сеть.ВебВоркер().Получ("https://wartank.ru/building-upgrade/FuelStorage")
		for _, стр = range списСтр {
			// <a class="simple-but border mb5" href="FuelStorage?71-1.ILinkListener-upgradeLink-link">
			if strings.Contains(стр, `ILinkListener-upgradeLink-link`) {
				еслиНайти = true
				break
			}
		}
		if !еслиНайти {
			return true
		}
		// Пробуем построить шахту
		_стр := strings.TrimPrefix(стр, "<a class=\"simple-but border mb5\" href=\"")
		_стр = strings.TrimSuffix(_стр, "\">")
		// https://wartank.ru/building-upgrade/FuelStorage?49-1.ILinkListener-upgradeLink-link
		// <a class="simple-but border mb5" href="FuelStorage?50-1.ILinkListener-upgradeLink-link">
		// https://wartank.ru/building-upgrade/FuelStorage?72-1.ILinkListener-upgradeLink-link
		ссылка := "https://wartank.ru/building-upgrade/" + _стр
		списСтр = сам.сеть.ВебВоркер().Получ(ссылка)
		// Проверить, что постройка состоялась
		for _, стр := range списСтр {
			if strings.Contains(стр, "ILinkListener-upgradeLink-link") {
				log.Printf("СкладТоплива.построить().фнКупить(): покупка склада топлива не прошла\n\tlink=%v\n\tстр=\n\t%v\n", ссылка, стр)
				return false // Покупка не оплачена
			}
		}
		log.Printf("+++++СкладТоплива.построить().фнКупить(): покупка склада топлива прошла\n")
		return true
	}

	фнПодтверждение := func() bool {
		for _, стр = range списСтр {
			// <a class="simple-but border w50 mXa mb10" w:id="confirmLink" href="../wicket/page?5-1.ILinkListener-confirmLink"><span><span>да, подтверждаю</span></span></a>
			if strings.Contains(стр, `ILinkListener-confirmLink`) {
				еслиНайти = true
				break
			}
		}
		if !еслиНайти {
			return true
		}
		// Пробуем построить шахту
		_стр := strings.TrimPrefix(стр, `<a class="simple-but border w50 mXa mb10" w:id="confirmLink" href="..`)
		_стр = strings.TrimSuffix(_стр, `"><span><span>да, подтверждаю</span></span></a>`)
		// https://wartank.ru/wicket/page?4-1.ILinkListener-confirmLink
		// <a class="simple-but border mb5" href="FuelStorage?50-1.ILinkListener-upgradeLink-link">
		ссылка := "https://wartank.ru" + _стр
		списСтр = сам.сеть.ВебВоркер().Получ(ссылка)
		// Проверить, что постройка состоялась
		for _, стр := range списСтр {
			if strings.Contains(стр, "<title>Вы сделали слишком большую паузу</title>") {
				log.Printf("СкладТоплива.построить().фнПодтверждение(): подтверждение покупка склада топлива не прошла\n\tlink=%v\n\tстр=\n\t%v\n", ссылка, стр)
				return false // Покупка не оплачена
			}
		}
		log.Printf("+++++СкладТоплива.построить().фнПодтверждение(): подтверждение покупка склада топлива прошла\n")
		return true
	}

	фнКомплекс := func() {
		for {
			if фнКупить() {
				if фнПодтверждение() {
					break
				}
			}
		}
	}
	фнКомплекс()
	return true
}

// Уровень -- возвращает уровень топливного склада
func (сам *СкладТоплива) Уровень() types.ИСтатПарам {
	return сам.уровень
}

// Топливо -- возвращает топливо
func (сам *СкладТоплива) Топливо() types.ИСтатПарам {
	return сам.топливо
}

// ПродуктКолСейчас -- возвращает кол-во продукта прямо сейчас
func (сам *СкладТоплива) ПродуктКолСейчас() int {
	return сам.топливо.Получ()
}

// ПродуктИмяСейчас -- возвращает имя продукта прямо сейчас
func (сам *СкладТоплива) ПродуктИмяСейчас() string {
	return "топливо"
}

// ПродуктВремяСейчас -- возвращает сколько осталось времени прямо сейчас
func (сам *СкладТоплива) ПродуктВремяСейчас() string {
	return сам.продуктВремя
}
