package host

import (
	"easyvqd/internal/conf"
	"easyvqd/pkg/pluginheart"
	"encoding/json"
	"fmt"
	"log/slog"

	"git.lnton.com/lnton/pluginsdk/pkg/data"
	"git.lnton.com/lnton/pluginsdk/pkg/plugin"
)

type IFrameResultCB func(string, []byte, int)
type Core struct {
	Plugin     *plugin.PluginSDK   // 用于业务GRPC通信
	HttpPlugin *pluginheart.Engine // 用于插件管理HTTP通信
	RtspConfig *ConfigBaseOutput
	CbIFrame   IFrameResultCB
}

var StartOk chan struct{}

func NewCore(cfg *conf.Bootstrap) *Core {
	cb := plugin.PluginCallback{
		OnShutdown: func() { slog.Info("Plugin shutting down") },
	}
	sdk, err := plugin.NewPlugin(data.Plugin{
		ID:         "EasyVQD",
		Name:       "EasyVQD",
		Version:    "1.0.0",
		ServerAddr: fmt.Sprintf("%s:%d", "localhost", cfg.Plugin.GrpcPort),
	}, cb)
	if err != nil {
		panic(err)
	}

	engine := pluginheart.NewEngine("easyvqd", cfg.Plugin.HttpAPI)

	// 后台等待启动完成信号，然后触发心跳（不阻塞主流程）
	go func() {
		StartOk = make(chan struct{})
		<-StartOk
		engine.AutoHeart(pluginheart.HeartInput{
			Port: cfg.Server.HTTP.Port,
		}, false)
	}()

	core := &Core{
		Plugin:     sdk,
		HttpPlugin: engine,
	}
	sdk.AddResponseHandler("stop", core.stop)
	sdk.AddResponseHandler("ping", core.ping)
	// 这部分都是收到响应后的回调
	sdk.AddResponseHandler("play", core.playRespH)
	sdk.AddResponseHandler("findDevices", core.findDevicesRespH)
	sdk.AddResponseHandler("findChannels", core.findChannelsRespH)
	sdk.AddResponseHandler("getBaseConfig", core.getBaseConfigRespH)
	sdk.AddResponseHandler("findTalkUrl", core.findTalkUrlRespH)
	sdk.AddResponseHandler("iframeData", core.iframeDataRespH)
	// 响应主机下发的 "iframeData" 命令
	sdk.AddRequestHandler("iframeData", core.iframeDataReqH)
	// defer sdk.Close()
	return core
}

func (c *Core) iframeDataReqH(requestID string, args json.RawMessage) (interface{}, error) {
	//slog.Debug("Received 'iframeData' from host", "request_id", requestID, "args", args)
	out := IframeOutput{}
	if err := json.Unmarshal(args, &out); err != nil {
		return nil, nil
	}
	c.CbIFrame(out.StreamName, out.Data, out.Codes)
	return nil, nil
}

func (c Core) stop(requestID string, args json.RawMessage) (interface{}, error) {
	slog.Info("Received 'stop' from host", "request_id", requestID)
	return map[string]interface{}{"status": "stopped"}, nil
}

func (c Core) ping(requestID string, args json.RawMessage) (interface{}, error) {
	slog.Debug("Received 'ping' from host", "request_id", requestID, "args", args)
	return nil, nil
}

func (c Core) findDevicesRespH(requestID string, args json.RawMessage) (interface{}, error) {
	slog.Debug("Received 'findDeviceList' from host", "request_id", requestID, "args", args)
	return nil, nil
}

func (c Core) findChannelsRespH(requestID string, args json.RawMessage) (interface{}, error) {
	slog.Debug("Received 'findChannels' from host", "request_id", requestID, "args", args)
	return nil, nil
}
func (c Core) getBaseConfigRespH(requestID string, args json.RawMessage) (interface{}, error) {
	slog.Debug("Received 'getBaseConfig' from host", "request_id", requestID, "args", args)
	return nil, nil
}
func (c Core) findTalkUrlRespH(requestID string, args json.RawMessage) (interface{}, error) {
	slog.Debug("Received 'findTalkUrl' from host", "request_id", requestID, "args", args)
	return nil, nil
}
func (c Core) playRespH(requestID string, args json.RawMessage) (interface{}, error) {
	slog.Debug("Received 'play' from host", "request_id", requestID, "args", args)
	return nil, nil
}

func (c Core) iframeDataRespH(requestID string, args json.RawMessage) (interface{}, error) {
	slog.Debug("Received 'iframeData' from host", "request_id", requestID, "args", args)
	return nil, nil
}
