package convoy

import (
	"fmt"
	"log"
	"strconv"
	"strings"
	"time"
	"wartank/pkg/alias"
	"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.ИСтатПарам // Количество славы
}

// НовКонвой -- возвращает новый *Convoy
func НовКонвой(бот types.ИБот) *Конвой {
	сам := &Конвой{
		бот:   бот,
		слава: static_param.НовСтатПарам("glory"),
	}
	аренаКонфиг := arena.АренаКонфиг{
		Бот_:         сам.бот,
		АренаИмя_:    "Конвой",
		СтрКонтроль_: `<title>Конвой</title>`,
		ФнПуск_:      сам.пуск,
		СтрУрл_:      "https://wartank.ru/convoy",
	}
	сам.ИАрена = arena.НовАрена(аренаКонфиг)
	сам.сеть = arena_net.НовАренаСеть(сам, "https://wartank.ru/convoy")
	return сам
}

// UpdateLst -- принудительно обновляет состояние конвоя
func (сам *Конвой) UpdateLst() {
	сам.сеть.Обновить()
}

// Слава --возвращает счётчик славы конвоя
func (сам *Конвой) Слава() types.ИСтатПарам {
	return сам.слава
}

// обрабатывает конвой
func (сам *Конвой) пуск() {
	фнЦикл := func() {
		сам.проверитьМиссия6фрагов()
		сам.проверитьМиссияРазведкаКонвой()
		сам.проверитьМиссияМастерРазведки()
		сам.атаковать()
	}
	for {
		select {
		case <-сам.бот.Контекст().Done():
			return
		default:
			фнЦикл()
			time.Sleep(time.Second * 3)
			фнЦикл() // Для второго шага
			time.Sleep(time.Minute * 20)
		}
	}
}

func (сам *Конвой) атаковать() {
	if false {
		сам.обновитьВремя()
	}
	for {
		стрВбой := сам.найтиВбой()
		if стрВбой == "" {
			return
		}
		сам.атакаНачать() // в этом месте только атаковать
		сам.проверитьМиссияРазведкаКонвой()
		сам.проверитьМиссияМастерРазведки()
		сам.проверитьМиссия6фрагов()
		сам.Обновить()
	}
}

// Обновляет славу по требованию
func (сам *Конвой) Обновить() {
	// Найти строку с упоминанием оставшегося времени конвоя
	lstConvoy := сам.СписПолучить()
	var (
		strGlory    string
		еслиНайдено bool
	)
	for _, lastTime := range lstConvoy {
		if strings.Contains(lastTime, `alt="Слава" title="Слава"> `) {
			strGlory = lastTime
			еслиНайдено = true
			break
		}
	}
	if !еслиНайдено { // Не найдена строка со славой -- это атака
		return
	}
	// Ищем количество славы
	lstGlory := strings.Split(strGlory, `alt="Слава" title="Слава"> `)
	strGlory = lstGlory[1]
	iGlory, err := strconv.Atoi(strGlory)
	if err != nil {
		// log._rintf("ERRO ConvoyNet.updateGlory(): слава(%v) не число, err=\n\t%v\n", strGlory, err)
		return
	}
	сам.слава.Уст(iGlory)
}

// Обновляет оставшееся время конвоя
func (сам *Конвой) обновитьВремя() {
	// Время подходит надо обновляться
	сам.сеть.Обновить()
	ош := сам.ОбратВремяУст("20")
	if ош != nil {
		log.Printf("Конвой.обновитьВремя(): при обновлении времени, ош=\n\t%v\n", ош)
		сам.бот.Сервер().Отменить()
		return
	}
	// Найти строку с упоминанием оставшегося времени конвоя
	lstConvoy := сам.СписПолучить()
	var (
		strLastTime string
		еслиНайдено bool
		isMask      bool
	)
	for _, lastTime := range lstConvoy {
		if strings.Contains(lastTime, `До следующего конвоя: `) {
			strLastTime = lastTime
			еслиНайдено = true
			break
		}
		if strings.Contains(lastTime, `Полная маскировка через `) {
			strLastTime = lastTime
			isMask = true
			break
		}
		// <div class="bot"><a class="simple-but border red" w:id="startFight" href="convoy?7-1.ILinkListener-root-startFight"><span><span>В БОЙ!</span></span></a></div>
		if strings.Contains(lastTime, `ILinkListener-root-startFight`) {
			return
		}
		if strings.Contains(lastTime, `ILinkListener-root-findEnemy`) {
			return
		}
		// <div class="bot"><a class="simple-but border" w:id="startMasking" href="convoy?12-1.ILinkListener-root-startMasking"><span><span>В БОЙ!</span></span></a></div>
		if strings.Contains(lastTime, `ILinkListener-root-startMasking`) {
			return
		}
	}
	switch {
	case еслиНайдено: // Большая пауза между конвоями
		// Ждём окончания ожидания конвоя
		lstTime := strings.Split(strLastTime, `До следующего конвоя: `)
		strLastTime = lstTime[1]
		if err := сам.ОбратВремяУст(alias.Время(strLastTime)); err != nil {
			// log._rintf("WARN Конвой.обновитьВремя(): при установке времени ожидания конвоя(%v)\n\terr=%v\n", strLastTime, err)
			err := сам.ОбратВремяУст("10")
			if err != nil {
				log.Printf("Конвой.обновитьВремя(): при установке времени ожидания конвоя(%v)\n\terr=%v\n", strLastTime, err)
				сам.бот.Сервер().Отменить()
			}
		}
	case isMask: // Если маскировка между конвоями
		// Ждём окончания ожидания конвоя
		lstTime := strings.Split(strLastTime, `Полная маскировка через `)
		strLastTime = lstTime[1]
		if err := сам.ОбратВремяУст(alias.Время(strLastTime)); err != nil {
			// log._rintf("ERRO BКонвой.обновитьВремя(): при установке времени банка для 1го режима(%v)\n\terr=%v\n", strLastTime, err)
			err := сам.ОбратВремяУст("10")
			if err != nil {
				log.Printf("Конвой.обновитьВремя(): при установке времени банка для 1го режима(%v)\n\terr=%v\n", strLastTime, err)
				сам.бот.Сервер().Отменить()
			}
		}
	}
}

func (сам *Конвой) найтиВбой() string {
	var (
		strOut      = ""
		еслиНайдено bool
	)
	lstConvoy := сам.сеть.ВебВоркер().Получ("https://wartank.ru/convoy")
	if сам.бот.Имя() == "prospero tank" {
		log.Printf("")
	}
	for _, strOut = range lstConvoy {
		// <div class="bot"><a class="simple-but border" w:id="findEnemy" href="convoy?50-1.ILinkListener-root-findEnemy"><span><span>Начать разведку</span></span></a></div>
		если1 := strings.Contains(strOut, `.ILinkListener-root-findEnemy"`)
		if если1 {
			_ссылка := strings.TrimPrefix(strOut, `<div class="bot"><a class="simple-but border" w:id="findEnemy" href="`)
			_ссылка = strings.TrimSuffix(_ссылка, `"><span><span>Начать разведку</span></span></a></div>`)
			strOut = "https://wartank.ru/" + _ссылка
			еслиНайдено = true
			break
		}
		если2 := strings.Contains(strOut, `<span>В БОЙ!</span>`)
		if если2 {
			lstLink := strings.Split(strOut, `<div class="bot"><a class="simple-but border" w:id="startMasking" href="`)
			if len(lstLink) == 1 {
				lstLink = strings.Split(strOut, `<div class="bot"><a class="simple-but border red" w:id="startFight" href="`)
			}
			strOut = lstLink[1]
			lstLink = strings.Split(strOut, `"><span><span>В БОЙ!</span></span></a></div>`)
			strOut = "https://wartank.ru/" + lstLink[0]
			еслиНайдено = true
			break
		}
		// <div class="bot"><a class="simple-but border" w:id="findEnemy" href="convoy?15-1.ILinkListener-root-findEnemy"><span><span>Начать разведку</span></span></a></div>
		если3 := strings.Contains(strOut, "<span>Начать разведку</span>")
		if если3 {
			_ссылка := strings.TrimPrefix(strOut, `<<div class="bot"><a class="simple-but border" w:id="findEnemy" href="`)
			_ссылка = strings.TrimSuffix(_ссылка, `"><span><span>Начать разведку</span></span></a></div>`)
			strOut = "https://wartank.ru/" + _ссылка
			еслиНайдено = true
			break
		}
		if strings.Contains(strOut, `>ОБЫЧНЫЕ<`) {
			lstLink := strings.Split(strOut, `<a href="`)
			strOut = lstLink[1]
			lstLink = strings.Split(strOut, `" class="simple-but gray"><span><span>ОБЫЧНЫЕ</span></span></a>`)
			strOut = "https://wartank.ru/" + lstLink[0]
			еслиНайдено = true
			break
		}
	}
	if !еслиНайдено { // Время ожидания
		// if err := сам.SetCountDown(1); err != nil {
		// 	panic(fmt.Errorf("Конвой.атакаНачать(): прb установке CountDown, err=\n\t%w", err))
		// }
		return ""
	}
	return strOut
}

// Проводит атаку на конвой
func (сам *Конвой) атакаНачать() {
	// Найти контрольную строку
	strOut := сам.найтиВбой()
	if strOut == "" { // Время ожидания
		// if err := сам.SetCountDown(1); err != nil {
		// 	panic(fmt.Errorf("Конвой.атакаНачать(): прb установке CountDown, err=\n\t%w", err))
		// }
		return
	}
	strLink := strOut
	// Можно начать разведку
	lstConvoy := сам.сеть.ВебВоркер().Получ(strLink)
	if err := сам.СтрОбновить(lstConvoy); err != nil {
		for _, strOut = range lstConvoy {
			if strings.Contains(strOut, `<title>Ошибка на сервере. Сообщение админу уже отправлено.</title>`) {
				// log._rintf("ERRO Конвой.атакаНачать(): при обновлении lstConvoy, strOut=\n\t%v\n", strOut)
				return
			}
		}
		for _, strOut = range lstConvoy {
			if strings.Contains(strOut, `<title>База</title>`) {
				// log._rintf("ERRO Конвой.атакаНачать(): при обновлении lstConvoy (найдено lstBase), strOut=\n\t%v\n", strOut)
				return
			}
		}
		// log._rintf("ERRO Конвой.атакаНачать(): при обновлении lstConvoy, err=\n\t%v\n", err)
		return
	}
	сам.начатьРазведку()
	if err := сам.ОбратВремяУст("01"); err != nil {
		panic(fmt.Errorf("Конвой.атакаНачать(): при установке CountDown, err=\n\t%w", err))
	}
}

// Выполняет атаку на конвой
func (сам *Конвой) начатьРазведку() {
	// Вырезать ссылку на атаку
	strOut := ""
	еслиНайдено := false
	lstConvoy := сам.СписПолучить()
	// <div class="bot"><a class="simple-but border" w:id="findEnemy" href="convoy?50-1.ILinkListener-root-findEnemy"><span><span>Начать разведку</span></span></a></div>
	for _, strOut = range lstConvoy {
		if strings.Contains(strOut, `.ILinkListener-root-findEnemy`) {
			еслиНайдено = true
			break
		}
	}
	if !еслиНайдено { // Нечего атаковать
		return
	}
	// Атакуем конвой
	_link := strings.TrimPrefix(strOut, `<div class="bot"><a class="simple-but border" w:id="findEnemy" href="`)
	_link = strings.TrimSuffix(_link, `"><span><span>Начать разведку</span></span></a></div>`)
	// https://wartank.ru/convoy?52-1.ILinkListener-root-findEnemy
	link := "https://wartank.ru/" + _link
	{ // Выполнить атаку
		lstConvoy = сам.сеть.ВебВоркер().Получ(link)
		if err := сам.СтрОбновить(lstConvoy); err != nil {
			log.Printf("Конвой.attack(): при обновлении lstConvoy, err=\n\t%v\n", err)
			return
		}
	}
}

// Забирает награду в конвое "Активируй боевую силу"
func (сам *Конвой) проверитьМиссияРазведкаКонвой() {
	var (
		strOut      string
		еслиНайдено bool
	)
	сам.сеть.Обновить()
	lstConvoy := сам.СписПолучить()
	// <a class="simple-but border" href="convoy?21-1.ILinkListener-missions-cc-0-c-awardLink"><span><span>Получить награду</span></span></a>
	for _, strOut = range lstConvoy {
		if strings.Contains(strOut, `.ILinkListener-missions-cc-0-c-awardLink`) {
			еслиНайдено = true
			break
		}
	}
	if !еслиНайдено {
		return
	}
	// <a class="simple-but border" href="convoy?21-1.ILinkListener-missions-cc-0-c-awardLink"><span><span>Получить награду</span></span></a>
	_ссылка := strings.TrimPrefix(strOut, `<a class="simple-but border" href="`)
	_ссылка = strings.TrimSuffix(_ссылка, `"><span><span>Получить награду</span></span></a>`)
	// https://wartank.ru/convoy?23-1.ILinkListener-missions-cc-0-c-awardLink
	ссылка := "https://wartank.ru/" + _ссылка
	lstConvoy = сам.сеть.ВебВоркер().Получ(ссылка)
	if err := сам.СтрОбновить(lstConvoy); err != nil {
		log.Printf("Конвой.проверитьМиссияРазведкаКонвой(): пр обновлении lstConvoy, err=\n\t%v\n", err)
		return
	}
	log.Printf("Конвой.проверитьМиссияРазведкаКонвой(): награда получена\n")
}

// Забирает награду в конвое "Мастер дозора"
func (сам *Конвой) проверитьМиссияМастерРазведки() {
	var (
		strOut      string
		еслиНайдено bool
		lstConvoy   = сам.СписПолучить()
		ind         int
	)
	if len(lstConvoy) == 0 {
		сам.сеть.Обновить()
		lstConvoy = сам.СписПолучить()
	}
	for ind, strOut = range lstConvoy {
		if strings.Contains(strOut, `Проведи разведку в конвое<br/>`) {
			еслиНайдено = true
			ind += 23
			strOut = lstConvoy[ind]
			break
		}
	}
	if !еслиНайдено {
		return
	}
	// <a class="simple-but border" href="convoy?61-1.ILinkListener-missions-cc-0-c-awardLink"><span><span>Получить награду</span></span></a>
	if !strings.Contains(strOut, `ILinkListener-missions-cc-0-c-awardLink`) {
		return
	}
	lstLink := strings.Split(strOut, `<a class="simple-but border" href="`)
	strLink := lstLink[1]
	lstLink = strings.Split(strLink, `"><span><span>Получить награду</span></span></a>`)
	// https://wartank.ru/convoy?61-1.ILinkListener-missions-cc-0-c-awardLink
	strLink = "https://wartank.ru/" + lstLink[0]
	lstConvoy, err := сам.сеть.Get(strLink)
	if err != nil {
		// log._rintf("ERRO Конвой.checkMaster(): при выполнении команды GET, err=\n\t%v\n", err)
		return
	}
	if err := сам.СтрОбновить(lstConvoy); err != nil {
		// log._rintf("ERRO Конвой.checkMaster(): пр обновлении lstConvoy, err=\n\t%v\n", err)
		return
	}
	// log._rintf("INFO Конвой.checkMaster(): награда получена\n")
}

// Забирает награду в конвое "Уничтожь 6 врагов в конвое"
func (сам *Конвой) проверитьМиссия6фрагов() {
	var (
		strOut      string
		еслиНайдено bool
	)
	сам.сеть.Обновить()
	lstConvoy := сам.СписПолучить()
	// <a class="simple-but border" href="convoy?8-1.ILinkListener-missions-cc-1-c-awardLink"><span><span>Получить награду</span></span></a>
	for _, strOut = range lstConvoy {
		if strings.Contains(strOut, `.ILinkListener-missions-cc-1-c-awardLink`) {
			еслиНайдено = true
			break
		}
	}
	if !еслиНайдено {
		return
	}
	// <a class="simple-but border" href="convoy?8-1.ILinkListener-missions-cc-1-c-awardLink"><span><span>Получить награду</span></span></a>
	_ссылка := strings.TrimPrefix(strOut, `<a class="simple-but border" href="`)
	_ссылка = strings.TrimSuffix(_ссылка, `"><span><span>Получить награду</span></span></a>`)
	// https://wartank.ru/convoy?15-1.ILinkListener-missions-cc-1-c-awardLink
	ссылка := "https://wartank.ru/" + _ссылка
	lstConvoy = сам.сеть.ВебВоркер().Получ(ссылка)
	if err := сам.СтрОбновить(lstConvoy); err != nil {
		log.Printf("Конвой.проверитьМиссия6фрагов(): при обновлении lstConvoy, ош=\n\t%v\n", err)
		return
	}
	log.Printf("Конвой.проверитьМиссия6фрагов(): награда получена\n")
}
