package ui

import (
	"fmt"
	"go_dreamfactory/cmd/v2/lib/common"
	"go_dreamfactory/cmd/v2/model"
	"go_dreamfactory/cmd/v2/service"
	"go_dreamfactory/cmd/v2/service/observer"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/container"
	"fyne.io/fyne/v2/driver/desktop"
	"fyne.io/fyne/v2/layout"
	"fyne.io/fyne/v2/theme"
	"fyne.io/fyne/v2/widget"
	"github.com/sirupsen/logrus"
	"google.golang.org/protobuf/types/known/anypb"
)

type appMonitor struct {
	appAdapter

	obs         observer.Observer
	logPanel    *widget.Entry
	monitorList *common.ItemList
	id          int64
}

func (app *appMonitor) LazyInit(service service.PttService, obs observer.Observer) error {
	app.obs = obs
	app.tabItem = container.NewTabItemWithIcon(common.TOOLBAR_MONITOR, theme.MediaVideoIcon(), nil)

	content := container.NewMax()
	content.Objects = []fyne.CanvasObject{}

	// panel for output log
	app.logPanel = widget.NewMultiLineEntry()
	app.logPanel.Wrapping = fyne.TextWrapWord
	//clear button
	clearBtn := widget.NewButtonWithIcon(common.APP_TESTCASE_BTN_CLEARLOG, theme.DeleteIcon(), func() {
		app.logPanel.SetText("")
		app.monitorList.Reset()
	})

	resPanel := container.NewBorder(container.NewHBox(clearBtn, layout.NewSpacer()), nil, nil, nil, app.logPanel)

	app.monitorList = common.NewItemList()

	app.monitorList.ItemList = app.monitorList.CreateList()
	app.monitorList.ItemList.OnSelected = func(id widget.ListItemID) {
		o := app.monitorList.CachedList.Items[id]
		pd, ok := o.Data.(*model.PushModel)
		if !ok {
			return
		}
		if res, err := anypb.New(pd.Msg.Data); err == nil {
			app.logPanel.Text = res.String()
			app.logPanel.Refresh()
		} else {
			logrus.WithField("err", err).Error("view detail")
		}
	}

	// layout
	panel := container.NewVSplit(container.NewBorder(nil, nil, nil, nil,
		app.monitorList.ItemList), resPanel)
	panel.Offset = 0.8
	content.Objects = append(content.Objects, panel)
	app.tabItem.Content = content
	app.monitorlistener()
	return nil
}

func (a *appMonitor) OpenDefault() string {
	return common.TOOLBAR_MONITOR
}

func (a *appMonitor) GetAppName() string {
	return common.TOOLBAR_MONITOR
}

func (a appMonitor) OnClose() bool {
	return false
}

// monitor list data
func (app *appMonitor) monitorlistener() {
	app.obs.AddListener(observer.EVENT_APP_MONI, observer.Listener{
		OnNotify: func(d interface{}, args ...interface{}) {
			app.id++
			data := d.(*model.PushModel)
			protocol := fmt.Sprintf("【%s.%s】", data.Msg.MainType, data.Msg.SubType)
			app.monitorList.AddItem(common.Item{
				Text: fmt.Sprintf("%d - %-50v %-50v %-50v",
					app.id, protocol, data.MethodName, data.DataTime),
				Data: data,
			})

			app.monitorList.ItemList.ScrollToBottom()
		},
	})
}

func (this *appMonitor) ShortCut() fyne.Shortcut {
	return &desktop.CustomShortcut{KeyName: fyne.Key3, Modifier: desktop.AltModifier}
}

func (this *appMonitor) Icon() fyne.Resource {
	return theme.MediaVideoIcon()
}
