package battle_worker

import (
	"context"
	"time"
	"wartank/pkg/arena"
	"wartank/pkg/components/arena_net"
	"wartank/pkg/types"
	"wartank/server/serv_bots/warbot/angar/battle/battle_worker/battle_worker/health"
	"wartank/server/serv_bots/warbot/angar/battle/battle_worker/battle_worker/manevr"
	"wartank/server/serv_bots/warbot/angar/battle/battle_worker/battle_worker/shot"
	"wartank/server/serv_bots/warbot/angar/battle/battle_worker/battle_worker/shot/is_shot"
)

/*
	Предоставляет сетевой компонент при непосредственном сражении
*/

// СражениеДействие -- непосредственно танкует в сражении
type СражениеДействие struct {
	types.ИАрена
	сеть       types.ИАренаСеть
	бот        types.ИБот
	кнт        context.Context // Контекст сражения
	фнОтменить func()          // Функция отмены сражения

	выстрел     *shot.Выстрел    // Объект выстрела
	здоровье    *health.Здоровье // Текущее здоровье танка
	манёвр      *manevr.Манёвр   // Возможность маневрирования
	логин       string
	еслиВыстрел *is_shot.IsShot // Признак необходимости маскирования (запрет стрельбы, когда слабое здоровье)
}

// НовСражениеДействие -- возвращает новый *BattleOn
func НовСражениеДействие(бот types.ИБот) *СражениеДействие {
	// Ограничить время сражения бота
	кнтСражение, фнОтменить := context.WithTimeout(бот.Контекст(), time.Second*305)
	сам := &СражениеДействие{
		бот:         бот,
		кнт:         кнтСражение,
		фнОтменить:  фнОтменить,
		логин:       бот.Имя(),
		еслиВыстрел: is_shot.NewIsShot(),
	}
	аренаКонфиг := arena.АренаКонфиг{
		Бот_:         сам.бот,
		АренаИмя_:    "Исполнитель сражения",
		СтрКонтроль_: `<title>Сражения</title>`,
		ФнПуск_:      сам.пуск,
	}
	сам.ИАрена = arena.НовАрена(аренаКонфиг)
	сам.сеть = arena_net.НовАренаСеть(сам, "https://wartank.ru/pve")
	go сам.пуск()
	_ = types.ИСражениеДействие(сам)
	return сам
}

// запускает сражение
func (сам *СражениеДействие) пуск() {
	defer func() {
		сам.фнОтменить()
		// log._rintf("BattleOn.run(): сражение завершено\n")
	}()
	{ // Подготовка к сражению
		var err error
		сам.выстрел, err = shot.НовВыстрел(сам) // Объект выстрела
		if err != nil {
			// log._rintf("ERRO BattleOn.Run(): при создании выстрела танка, err=\n\t%v\n", err)
			return
		}
		сам.здоровье, err = health.НовЗдоровье(сам)
		if err != nil {
			// log._rintf("ERRO BattleOn.Run(): при создании здоровья танка, err=\n\t%v\n", err)
			return
		}
		сам.манёвр, err = manevr.НовМанёвр(сам)
		if err != nil {
			// log._rintf("ERRO BattleOn.Run(): при создании маневра танка, err=\n\t%v\n", err)
			return
		}
	}
	// Рабочий цикл сражения
	<-сам.кнт.Done()
}

// Сеть -- возвращает сетевой компонент секции
func (сам *СражениеДействие) Сеть() types.ИАренаСеть {
	return сам.сеть
}

func (сам *СражениеДействие) МанёврНадоУст() {
	if сам.манёвр == nil {
		return
	}
	сам.манёвр.УстНадо()
}

// ВыстрелБлок -- признак запрета стрельбы при слабом здоровье
func (сам *СражениеДействие) ВыстрелБлок() types.ИЕслиВыстрел {
	return сам.еслиВыстрел
}

// Кнт -- возвращает контекст отмены сражения
func (сам *СражениеДействие) Контекст() context.Context {
	return сам.кнт
}

// ОтменитьДействие -- вызов функции отмены контекста сражения
func (сам *СражениеДействие) Отменить() {
	сам.фнОтменить()
}
