//go:build windows

package main

import (
	"log"
	"syscall"

	"github.com/tailscale/walk"
	"github.com/tailscale/win"
)

type notifyLevel int

const (
	notifyMessage notifyLevel = iota
	notifyInfo
	notifyWarn
	notifyError
)

func openURLInBrowser(url string) {
	win.ShellExecute(0, nil, syscall.StringToUTF16Ptr(url), nil, nil, win.SW_SHOWDEFAULT)
}

func (s *mirageShell) sendNotify(title, msg string, level notifyLevel) {
	var send func(string, string) error
	switch level {
	case notifyMessage:
		send = s.tray.ShowMessage
	case notifyInfo:
		send = s.tray.ShowInfo
	case notifyWarn:
		send = s.tray.ShowWarning
	case notifyError:
		send = s.tray.ShowError
	}

	if msg != "" {
		log.Printf("[notify] %s: %s", title, msg)
		s.runOnUI(func() {
			if err := send(title, msg); err != nil {
				log.Printf("send notify failed: %v", err)
			}
		})
		return
	}

	log.Printf("[notify] %s", title)
	s.runOnUI(func() {
		if err := send("", title); err != nil {
			log.Printf("send notify failed: %v", err)
		}
	})
}

func popConfirmDialog(title, msg string, w, h int) (confirm bool) {
	dlg, err := walk.NewDialogWithFixedSize(nil)
	if err != nil {
		log.Printf("create dialog failed: %v", err)
		return false
	}
	dlg.SetName(title)
	dlg.SetTitle(title)
	dlg.SetIcon(trayIcons[iconLogo])
	dlg.SetMinMaxSize(walk.Size{Width: w, Height: h}, walk.Size{Width: w, Height: h})
	dlg.SetX(int(win.GetSystemMetrics(win.SM_CXSCREEN)/2 - int32(w)/2))
	dlg.SetY(int(win.GetSystemMetrics(win.SM_CYSCREEN)/2 - int32(h)/2))

	vboxLayout := walk.NewVBoxLayout()
	vboxLayout.SetMargins(walk.Margins{HNear: 10, VNear: 10, HFar: 10, VFar: 10})
	dlg.SetLayout(vboxLayout)

	brusher, err := walk.NewSolidColorBrush(walk.RGB(250, 250, 250))
	if err == nil {
		dlg.SetBackground(brusher)
	}

	label, err := walk.NewTextLabel(dlg)
	if err == nil {
		label.SetText(msg)
		label.SetAlignment(walk.AlignHCenterVCenter)
		label.SetMinMaxSize(walk.Size{Width: w - 20, Height: h - 50}, walk.Size{Width: w - 20, Height: h - 50})
		if font, fontErr := walk.NewFont("Microsoft YaHei UI", 9, 0); fontErr == nil {
			label.SetFont(font)
		}
	}

	btns, err := walk.NewComposite(dlg)
	if err != nil {
		log.Printf("create dialog buttons failed: %v", err)
		return false
	}
	btns.SetLayout(walk.NewHBoxLayout())

	confirmBtn, err := walk.NewPushButton(btns)
	if err != nil {
		log.Printf("create confirm button failed: %v", err)
		return false
	}
	confirmBtn.SetText("确认")

	cancelBtn, err := walk.NewPushButton(btns)
	if err != nil {
		log.Printf("create cancel button failed: %v", err)
		return false
	}
	cancelBtn.SetText("取消")

	confirmBtn.Clicked().Attach(func() {
		confirm = true
		dlg.Accept()
	})
	cancelBtn.Clicked().Attach(func() {
		dlg.Cancel()
	})

	dlg.Run()
	return confirm
}

func popTextInputDialog(title, inputTip, defaultValue string) (confirm bool, value string) {
	dlg, err := walk.NewDialogWithFixedSize(nil)
	if err != nil {
		log.Printf("create input dialog failed: %v", err)
		return false, ""
	}
	dlg.SetName(title)
	dlg.SetTitle(title)
	dlg.SetIcon(trayIcons[iconLogo])
	dlg.SetMinMaxSize(walk.Size{Width: 360, Height: 120}, walk.Size{Width: 360, Height: 120})
	dlg.SetX(int(win.GetSystemMetrics(win.SM_CXSCREEN)/2 - 180))
	dlg.SetY(int(win.GetSystemMetrics(win.SM_CYSCREEN)/2 - 60))
	dlg.SetLayout(walk.NewVBoxLayout())

	label, err := walk.NewTextLabel(dlg)
	if err == nil {
		label.SetText(inputTip)
	}
	input, err := walk.NewLineEdit(dlg)
	if err != nil {
		log.Printf("create input failed: %v", err)
		return false, ""
	}
	input.SetText(defaultValue)

	buttons, err := walk.NewComposite(dlg)
	if err != nil {
		log.Printf("create button composite failed: %v", err)
		return false, ""
	}
	buttons.SetLayout(walk.NewHBoxLayout())

	okBtn, err := walk.NewPushButton(buttons)
	if err != nil {
		log.Printf("create ok button failed: %v", err)
		return false, ""
	}
	okBtn.SetText("确定")
	okBtn.Clicked().Attach(func() {
		value = input.Text()
		dlg.Accept()
	})

	cancelBtn, err := walk.NewPushButton(buttons)
	if err != nil {
		log.Printf("create cancel button failed: %v", err)
		return false, ""
	}
	cancelBtn.SetText("取消")
	cancelBtn.Clicked().Attach(func() {
		dlg.Cancel()
	})

	if dlg.Run() == walk.DlgCmdOK {
		return true, value
	}
	return false, ""
}
