package main

import (
	"errors"
	"fmt"
	"go_dreamfactory/cmd/v2/lib/common"
	"go_dreamfactory/cmd/v2/service"
	"go_dreamfactory/cmd/v2/service/observer"
	"go_dreamfactory/cmd/v2/theme"
	"go_dreamfactory/cmd/v2/ui"
	"image/color"
	"io"
	"log"
	"os"
	"os/exec"
	"runtime"
	"strings"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/app"
	"fyne.io/fyne/v2/canvas"
	"fyne.io/fyne/v2/container"
	"fyne.io/fyne/v2/dialog"
	"fyne.io/fyne/v2/widget"
	"github.com/sirupsen/logrus"
	"github.com/tidwall/gjson"
)

var (
	connService service.ConnService
	pttService  service.PttService
	obs         = observer.NewObserver()
	logger      *logrus.Logger
)

func init() {
	_ = os.Setenv("FYNE_SCALE", "0.9")
	var err error
	// initialize logger
	if err = setupLogger(); err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	// if err = setupConfig(); err != nil {
	// 	fmt.Println(err)
	// 	os.Exit(1)
	// }

	if err = setupWsConn(); err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	if err = setupPtt(); err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
}

func main() {
	// create a new ui
	app := app.NewWithID("df-toolkit")
	app.SetIcon(theme.ResourceAppPng)

	appUI, err := ui.NewUI(app, connService, pttService, obs)
	if err != nil {
		w := fyne.CurrentApp().NewWindow("错误")
		w.SetContent(canvas.NewText(err.Error(), color.RGBA{255, 0, 0, 255}))
		w.ShowAndRun()
	}
	// logLifecycle(app)

	//创建enter
	w := fyne.CurrentApp().NewWindow("传送门")
	w.SetIcon(theme.ResourceAppPng)
	// 检查版本
	if app.Metadata().Build > 1 {
		checkVersion(app, w)
	}

	w.SetContent(container.NewGridWithColumns(2,
		widget.NewButton("工具", func() {
			toolWindow := ui.NewToolWindow(appUI, w)
			toolWindow.CreateWindow(common.APP_NAME, 1499, 800, true)
			w.Hide()
		}),
		widget.NewButton("登服", func() {
			mainWindow := ui.NewMainWindow(appUI, w)
			mainWindow.CreateWindow(common.APP_NAME, 1499, 800, true)
			w.Hide()
		}),
		// widget.NewButton("自动化测试", func() {
		// 	perfWindow := ui.NewPerfWindow(appUI, w)
		// 	perfWindow.CreateWindow(common.APP_NAME, 800, 600, true)
		// 	w.Hide()
		// }),
	))
	w.SetFixedSize(true)
	w.Resize(fyne.NewSize(400, 200))
	w.CenterOnScreen()
	w.SetCloseIntercept(func() {
		app.Quit()
	})

	logrus.WithField("version", app.Metadata().Version).Debug("app starting")
	w.Show()
	appUI.Run()
}

func logLifecycle(a fyne.App) {
	a.Lifecycle().SetOnStarted(func() {
		log.Println("Lifecycle: Started")
	})
	a.Lifecycle().SetOnStopped(func() {
		log.Println("Lifecycle: Stopped")
	})
	a.Lifecycle().SetOnEnteredForeground(func() {
		log.Println("Lifecycle: Entered Foreground")
	})
	a.Lifecycle().SetOnExitedForeground(func() {
		log.Println("Lifecycle: Exited Foreground")
	})
}

func setupPtt() (err error) {
	pttService = service.NewPttService(connService, obs)
	return
}

func setupWsConn() (err error) {
	connService = service.NewConnService(obs)
	return
}

func setupLogger() (err error) {
	logrus.SetFormatter(&logrus.JSONFormatter{
		TimestampFormat: "2006-01-02 15:04:05",
		// DisableColors: true,
		// FullTimestamp: true,
	})

	logrus.SetLevel(logrus.DebugLevel)
	logrus.SetOutput(os.Stdout)

	//设置output,默认为stderr,可以为任何io.Writer，比如文件*os.File
	file, err := os.OpenFile("robot.log", os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0666)
	writers := []io.Writer{
		file,
		os.Stdout}

	//同时写文件和屏幕
	fileAndStdoutWriter := io.MultiWriter(writers...)
	if err == nil {
		logrus.SetOutput(fileAndStdoutWriter)
	} else {
		logrus.Fatal("failed to log to file.")
	}
	return nil
}

// check version
func checkVersion(app fyne.App, parent fyne.Window) {
	b, err := connService.HttpConnect("http://10.0.0.9:8080/" + "version")
	if err != nil {
		dialog.ShowError(errors.New("版本检查:"+err.Error()), parent)
		return
	}

	oldVer := app.Metadata().Version
	parent.SetTitle(fmt.Sprintf("传送门 v%v", oldVer))
	ver := gjson.Get(string(b), "version").String()
	if strings.HasSuffix(ver, ".zip") {
		ver = strings.TrimSuffix(ver, ".zip")
	}
	logrus.WithField("version", ver).Debug("server version")
	if common.IsUpgrade(ver, oldVer) {
		chkDialog := dialog.NewConfirm("版本检查", "检查到新版本:"+ver+" 请升级后使用", func(b bool) {
			var commands = map[string]string{
				"windows": "explorer",
				"darwin":  "open",
				"linux":   "xdg-open",
			}
			//open browser
			open := func(uri string) error {
				// runtime.GOOS获取当前平台
				run, ok := commands[runtime.GOOS]
				if !ok {
					logrus.Errorf("don't know how to open things on %s platform", runtime.GOOS)
				}

				cmd := exec.Command(run, uri)
				return cmd.Run()
			}
			_ = open("http://10.0.0.9:8080/")
			defer parent.Close()
		}, parent)
		chkDialog.SetConfirmText(common.BUTTON_OK)
		chkDialog.Show()
	}
}
