// package bot_net_login -- сетевой вход на сервер бота
package bot_net_login

import (
	"io"
	"net/http"
	"net/url"
	"strings"
	"wartank/pkg/components/kernel/logger"
	"wartank/pkg/types"
)

// БотСетьЛогин -- объект сетевого входа на сервер
type БотСетьЛогин struct {
	сеть types.ИБотСеть
	conn *http.Client // Сырой клиент HTTP
	куки types.ИБотКуки
	лог  types.ИЛоггер
}

// НовБотСетьЛогин -- возвращает новый *БотСетьЛогин
func НовБотСетьЛогин(ботСеть types.ИБотСеть, conn *http.Client) *БотСетьЛогин {
	лог := logger.НовЛоггер("БотСетьЛогин")
	лог.Инфо("НовБотСетьЛогин()\n")
	лог.Паника(ботСеть == nil, "НовБотСетьЛогин(): ИБотСеть==nil")

	сам := &БотСетьЛогин{
		сеть: ботСеть,
		conn: conn,
		куки: ботСеть.Куки(),
		лог:  лог,
	}
	сам.подключить()
	return сам
}

// Вызывается один раз
func (сам *БотСетьЛогин) подключить() {
	ссылкаНачать := сам.получСтрГлав()
	if ссылкаНачать != "" { // Это вход на базу
		стрСтрЛогин := сам.получСтрЛогин(ссылкаНачать)
		сам.выполнитьЛогин(стрСтрЛогин)
		return
	}
	// Логин уже был
	запр, ош1 := http.NewRequest("GET", "https://wartank.ru/angar", nil)
	сам.лог.Паника(ош1 != nil, "БотСетьЛогин.подключить(): при получении страницы ангара, err=\n\t%v\n", ош1)
	resp, ош2 := сам.conn.Do(запр)
	сам.лог.Паника(ош2 != nil, "БотСетьЛогин.подключить(): при выполнении запроса, err=\n\t%v\n", ош2)
	defer resp.Body.Close()
	_, ош := io.ReadAll(resp.Body)
	сам.лог.Паника(ош != nil, "БотСетьЛогин.подключить(): при получении тела страницы ангара, err=\n\t%v\n", ош)
}

// Прочитать главную страницу для получения кукисов
func (сам *БотСетьЛогин) получСтрГлав() string {
	ответ, ош := сам.conn.Get("https://wartank.ru/")
	сам.лог.Паника(ош != nil, "БотСетьЛогин.получСтрГлав(): err=\n\t%v\n", ош)
	defer ответ.Body.Close()
	// Получить куки из ответа
	куки := ответ.Cookies()
	if len(куки) > 0 {
		сам.куки.Уст(куки)
	}
	бинДанные, ош := io.ReadAll(ответ.Body)
	сам.лог.Паника(ош != nil, "БотСетьЛогин.получСтрГлав(): при чтении тела ответа, err=\n\t%v\n", ош)
	// Вырезать из тела страницы ссылку на вход
	списСтр := strings.Split(string(бинДанные), "\n")
	var (
		стрВых    string
		ссылкаНач string
	)
	for _, стрСсылка := range списСтр {
		if strings.Contains(стрСсылка, `w:id="showSigninLink"`) {
			стрВых = стрСсылка
			break
		}
	}
	if стрВых == "" { // Уже был логин
		return ""
	}
	{ // Получить ссылку на вход
		списСсылка := strings.Split(стрВых, `href="`)
		списСсылка = strings.Split(списСсылка[1], `"><span><span>`)
		ссылкаНач = "https://wartank.ru/" + списСсылка[0]
	}
	return ссылкаНач
}

// Получает страницу логина
func (сам *БотСетьЛогин) получСтрЛогин(linkBegin string) string {
	// _mt.Println("\БотСетьЛогин.getPageLogin()")
	ответ, ош := сам.conn.Get(linkBegin)
	сам.лог.Паника(ош != nil, "БотСетьЛогин.получСтрЛогин(): in make GET-request for send login page, err=\n\t%v\n", ош)
	defer ответ.Body.Close()
	данные, ош := io.ReadAll(ответ.Body)
	сам.лог.Паника(ош != nil, "БотСетьЛогин.получСтрЛогин(): in read body response, err=\n\t%v\n", ош)
	стрТелоЛогин := string(данные)
	return стрТелоЛогин
}

// Выполняет логин через POST-запрос
func (сам *БотСетьЛогин) выполнитьЛогин(strBody string) {
	// _mt.Println("\БотСетьЛогин.makePostLogin()")
	var strBodyMain string
	{ // Получить форму логина
		lstLogin := strings.Split(strBody, "\n")
		for _, strForm := range lstLogin {
			if strings.Contains(strForm, `<form w:id="loginForm" id=`) {
				strBodyMain = strForm
				break
			}
		}
	}
	var postLink string
	{ // Получить ссылку на POST-запрос
		lstLink := strings.Split(strBodyMain, ` action="`)
		strLink := lstLink[1]
		lstLink = strings.Split(strLink, `"><div style=`)
		postLink = "https://wartank.ru/" + lstLink[0]
	}
	// Конструируем ПОСТ-форму логина
	form := url.Values{}
	form.Add("id1_hf_0", "")
	form.Add("login", сам.сеть.Бот().Имя())
	form.Add("password", сам.сеть.Бот().Пароль())

	resp, err := сам.conn.PostForm(postLink, form)
	сам.лог.Паника(resp.StatusCode != 200, "БотСетьЛогин.makePostLogin():  in get POST-login response, err=\n\t%v\n", err)
	defer resp.Body.Close()
	сам.лог.Паника(err != nil, "БотСетьЛогин.makePostLogin(): in read body POST-login response, err=\n\t%v\n", err)
	urlObj, _ := url.Parse("https://wartank.ru/")
	сам.conn.Jar.SetCookies(urlObj, сам.куки.Получ())

}
