// package mod_http -- http-движок для архитектуры
package engine_http

import (
	_ "embed"
	"fmt"
	"time"

	"github.com/gofiber/fiber/v2"
	"gitp78su.ipnodns.ru/svi/kern/v3"
	"gitp78su.ipnodns.ru/svi/kern/v3/kc/log_buf"
	"gitp78su.ipnodns.ru/svi/kern/v3/krn/ktypes"

	"gitp78su.ipnodns.ru/svi/goarch/lev0/alias"
	"gitp78su.ipnodns.ru/svi/goarch/lev0/cons"
	"gitp78su.ipnodns.ru/svi/goarch/lev0/types"
	"gitp78su.ipnodns.ru/svi/goarch/lev1/arch_doc"
	"gitp78su.ipnodns.ru/svi/goarch/lev1/view_coord"
	"gitp78su.ipnodns.ru/svi/goarch/lev1/view_size"
	"gitp78su.ipnodns.ru/svi/goarch/lev2/engine_http/http_api"
)

//go:embed index.html
var indexHtml []byte

// CanvasSize -- размер хоста
type CanvasSize struct {
	SizeX_ int `form:"w"`
	SizeY_ int `form:"h"`
}

func (sf *CanvasSize) String() string {
	return fmt.Sprintf("w:%v; h:%v", sf.SizeX_, sf.SizeY_)
}

// EngineHttp -- http-движок для архитектуры
type EngineHttp struct {
	// fibApp     *fiber.App
	kCtx     ktypes.IKernelCtx
	log      ktypes.ILogBuf
	diaMode  string            // Режим диаграммы
	canvSize CanvasSize        // Размер холста
	size     types.IViewSize   // Размер холста в его координатах
	pos      types.IViewCoord  // Координаты холста
	archDoc  *arch_doc.ArchDoc // Документ архитектуры
	httpApi  *http_api.HttpApi
}

// NewEngineHttp -- возвращает новый движок HTTP
func NewEngineHttp() *EngineHttp {
	optTerm := log_buf.OptIsTerm(true)
	optPref := log_buf.OptPrefix("EngineHttp")
	log := log_buf.NewLogBuf(optTerm, optPref)
	sf := &EngineHttp{
		kCtx:    kern.GetKernelCtx(),
		log:     log,
		diaMode: cons.ModeUseCase,
		size:    view_size.NewViewSize(800, 600),
		pos:     view_coord.NewViewCoord(0, 0),
		archDoc: arch_doc.GetArchDoc(),
		httpApi: http_api.NewHttpApi(),
	}
	sHttp := kern.GetKernelServerHttp()
	fibApp := sHttp.Fiber()
	fibApp.Static("/static", "./static", fiber.Static{
		Compress:      true,
		Browse:        true,
		CacheDuration: time.Second * 10,
	})
	fibApp.Get("/", sf.getIndex)
	fibApp.Get("/api/use_case", sf.postSetModeUseCase)
	fibApp.Post("/api/canvas/size/set", sf.postSetCanvasSize)
	return sf
}

// Устанавливает размер холста
func (sf *EngineHttp) postSetCanvasSize(ctx *fiber.Ctx) error {
	err := ctx.BodyParser(&sf.canvSize)
	if err != nil {
		sf.log.Err("postSetCanvasSize(): on body parser, err=\n\t%v", err)
	}
	var (
		w alias.SizeX
		h alias.SizeY
	)
	if sf.canvSize.SizeX_ > 0 {
		w = alias.SizeX(sf.canvSize.SizeX_ - 10)
	}
	if sf.canvSize.SizeY_ > 0 {
		h = alias.SizeY(sf.canvSize.SizeY_ - 10)
	}
	sf.size = view_size.NewViewSize(w, h)
	return ctx.SendString(sf.size.String())
}

// Возвращает картинку архитектуры
func (sf *EngineHttp) postSetModeUseCase(ctx *fiber.Ctx) error {
	sf.diaMode = cons.ModeUseCase
	return ctx.SendString("[mode='" + sf.diaMode + "']")
}

// Возвращает главную страницу сервиса
func (sf *EngineHttp) getIndex(ctx *fiber.Ctx) error {
	ctx.Response().Header.Set("Content-Type", "text/html")
	return ctx.Send(indexHtml)
}
