package battleon

import (
	"context"
	"fmt"
	"time"

	"wartank/pkg/components/section"
	"wartank/pkg/components/sectionnet"
	"wartank/pkg/types"
	"wartank/server/serv_bots/warbot/angar/battle/battle_worker/battleon/health"
	"wartank/server/serv_bots/warbot/angar/battle/battle_worker/battleon/manevr"
	"wartank/server/serv_bots/warbot/angar/battle/battle_worker/battleon/shot"
	"wartank/server/serv_bots/warbot/angar/battle/battle_worker/battleon/shot/isshot"
)

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

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

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

// НовСражениеДействие -- возвращает новый *BattleOn
func НовСражениеДействие(бот types.ИБот) (*СражениеДействие, error) {
	секция, ош := section.NewSection(бот, "Исполнитель сражения", `<title>Сражения</title>`)
	if ош != nil {
		return nil, fmt.Errorf("НовСражениеДействие(): in create ISection, err=\n\t%w", ош)
	}

	// Ограничить время сражения бота
	кнтСражение, фнОтменить := context.WithTimeout(бот.Кнт(), time.Second*305)
	сам := &СражениеДействие{
		Section:     секция,
		бот:         бот,
		кнт:         кнтСражение,
		фнОтменить:  фнОтменить,
		логин:       бот.Имя(),
		еслиВыстрел: isshot.NewIsShot(),
	}
	сам.сеть, ош = sectionnet.NewSectionNet(сам, "https://wartank.ru/pve")
	if ош != nil {
		return nil, fmt.Errorf("NewBattleOn(): in create *SectionNet, err=\n\t%w", ош)
	}
	go сам.пуск()
	_ = types.ИСражениеДействие(сам)
	return сам, nil
}

// запускает сражение
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 (sf *СражениеДействие) Сеть() types.ISectionNet {
	return sf.сеть
}

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

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

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

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