// package win_bots -- окно управления ботами
package win_bots

import (
	_ "embed"
	"fmt"
	"log"
	"net/url"
	"runtime"

	"github.com/zserge/lorca"

	"wartank/pkg/types"
)

//go:embed win_bots.html
var strWinHtml string

// WinBots -- окно управления ботами
type WinBots struct {
	desktop types.IDesktop
	store   types.IStore
	win     lorca.UI
	ws      types.IWebSocket
	fnAdd   func()
	fnView  func(nameBot string)
	dictBot map[string]string // Список ботов
}

// NewWinBots -- возвращает новое окно управления ботами
func NewWinBots(desktop types.IDesktop, fnAdd func(), fnView func(nameBot string), dictBot map[string]string) (*WinBots, error) {
	{ // Предусловия
		if desktop == nil {
			return nil, fmt.Errorf("NewWinBots(): IDesktop == nil")
		}
		if fnAdd == nil {
			return nil, fmt.Errorf("NewWinBots(): fnAdd == nil")
		}
		if fnView == nil {
			return nil, fmt.Errorf("NewWinBots(): fnView == nil")
		}
		if dictBot == nil {
			return nil, fmt.Errorf("NewWinBots(): dictBot == nil")
		}
	}

	sf := &WinBots{
		desktop: desktop,
		store:   desktop.Store(),
		ws:      desktop.Ws(),
		fnAdd:   fnAdd,
		fnView:  fnView,
		dictBot: dictBot,
	}

	args := []string{}
	if runtime.GOOS == "linux" {
		args = append(args, "--class=Lorca")
	}
	var err error
	sf.win, err = lorca.New("data:text/html,"+url.PathEscape(strWinHtml), "", 640, 480, args...)
	if err != nil {
		return nil, fmt.Errorf("NewWinBots(): in create win, err=\n\t%w", err)
	}
	go sf.close()
	return sf, nil
}

// Обновляет список ботов
func (sf *WinBots) UpdateList(dictBot map[string]string) {
	log.Println("WinBots.UpdateList()")
	sf.dictBot = dictBot
	sf.setBots()
}

// Работает в отдельном потоке, главный цикл окна
func (sf *WinBots) Run() {
	log.Println("WinBots.Run()")
	sf.win.Bind("close_win", sf.onClose)
	sf.win.Bind("user_add", sf.onUsersAdd)
	sf.win.Bind("user_view", sf.onUsersAdd)
	sf.setBots()
	<-sf.win.Done() // Ожидание закрытия окна
}

// Заполняет список ботов
func (sf *WinBots) setBots() {
	log.Println("WinBots.setBots()")
	strList := ""
	count := 0
	for key := range sf.dictBot {
		strCount := fmt.Sprint(count)
		strList += `<div style="color:#eee;margin-top:3px;" id="/bot/` + strCount + `">` + key +
			`&nbsp;&nbsp;&nbsp;<button type="button" name="add" value="Посм" onclick="bot_` + strCount + `()">Посмотреть</button></div>`
		sf.win.Bind("bot_"+strCount, func() {
			go sf.fnView(key)
		})
		count++
	}
	js := fmt.Sprintf(`
	function SetBotList(){
		var _el=document.getElementById("/bot/list");
		_el.innerHTML=%q
	}
	SetBotList()
	`, strList)
	sf.win.Eval(js)
}

// Добавляет бота по требованию
func (sf *WinBots) onUsersAdd() {
	log.Printf("WinBots.onUsersAdd()\n")
	go sf.fnAdd()
}

// Закрывает приложение
func (sf *WinBots) onClose() {
	log.Println("WinBots.onClose()")
	sf.win.Close()
}

// close -- ожидает отмены глобального контекста
func (sf *WinBots) close() {
	<-sf.desktop.CtxApp().Done()
	log.Println("WinBots.close()")
	sf.win.Close()
}
