package lxrod

import (
	"context"
	"errors"
	"os"
	"os/exec"
	"path/filepath"

	"git.listensoft.net/tool/jspkit/taxerr"
	"github.com/go-rod/rod"
	"github.com/go-rod/rod/lib/devices"
	"github.com/go-rod/rod/lib/launcher"
	"github.com/go-rod/rod/lib/launcher/flags"
)

// NewLauncher 创建一个新的 rod 浏览器启动器
func NewLauncher(ctx context.Context) *launcher.Launcher {
	return launcher.New().Context(ctx).Set("window-size", "1600,900").Headless(false)
}

// NewEdgeBrowser 创建一个由 rod chromium 模拟的 Edge 浏览器
func NewEdgeBrowser(ctx context.Context, u string) *rod.Browser {
	return rod.New().Context(ctx).DefaultDevice(EdgeLandscape).ControlURL(u)
}

// NewChromeBrowser 创建一个由 rod chromium 模拟的 Chrome 浏览器
func NewChromeBrowser(ctx context.Context, u string) *rod.Browser {
	return rod.New().Context(ctx).DefaultDevice(ChromeLandscape).ControlURL(u)
}

// EdgeLandscape device.
var EdgeLandscape = devices.Device{
	Title:          "Edge Laptop with HiDPI screen",
	Capabilities:   []string{},
	UserAgent:      "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0",
	AcceptLanguage: "en",
	Screen: devices.Screen{
		DevicePixelRatio: 2,
		Horizontal: devices.ScreenSize{
			Width:  1600,
			Height: 900,
		},
		Vertical: devices.ScreenSize{
			Width:  900,
			Height: 1600,
		},
	},
}.Landscape()

// ChromeLandscape device.
var ChromeLandscape = devices.Device{
	Title:          "Chrome Laptop with HiDPI screen",
	Capabilities:   []string{},
	UserAgent:      "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36",
	AcceptLanguage: "en",
	Screen: devices.Screen{
		DevicePixelRatio: 2,
		Horizontal: devices.ScreenSize{
			Width:  1600,
			Height: 900,
		},
		Vertical: devices.ScreenSize{
			Width:  900,
			Height: 1600,
		},
	},
}.Landscape()

// NewUserMode 使用系统浏览器启动一个新的浏览器。具体使用哪个浏览器由 rod 选择。
// 一般是 Chrome 浏览器。注意：本地的浏览器必须完全关闭，否则会启动失败。
func (lxrod *Lxrod) NewUserMode(ctx context.Context) (b *rod.Browser, p *rod.Page, err error) {
	l := launcher.NewUserMode().Headless(false)
	l.Flags["disable-blink-features"] = []string{"AutomationControlled"}
	lxrod.Launcher = l
	wsURL, err := l.Launch()
	lxrod.WsURL = wsURL
	if err != nil {
		return nil, nil, taxerr.NewWebStuckTitle(true)
	}
	b = rod.New().NoDefaultDevice().ControlURL(wsURL).Context(ctx).MustConnect()
	p = b.MustPage().MustSetWindow(0, 0, 1600, 900).MustSetViewport(1600, 900, 1, false)
	lxrod.Browser = b
	return b, p, nil
}

// NewSystemEdge 使用用户的 Edge 启动浏览器。注意：本地的 Edge
// 浏览器必须完全关闭，否则会启动失败。
func (lxrod *Lxrod) NewSystemEdge(ctx context.Context) (b *rod.Browser, p *rod.Page, err error) {
	bin, ok := findEdgePath()
	if !ok {
		return nil, nil, errors.New("未找到 Edge 浏览器")
	}

	l := launcher.NewUserMode().Headless(false)
	l.Flags["disable-blink-features"] = []string{"AutomationControlled"}
	l.Set(flags.Bin, bin)
	lxrod.Launcher = l

	wsURL, err := l.Launch()
	if err != nil {
		return nil, nil, err
	}
	lxrod.WsURL = wsURL

	b = rod.New().NoDefaultDevice().ControlURL(wsURL).Context(ctx).MustConnect()
	p = b.MustPage().MustSetWindow(0, 0, 1600, 900).MustSetViewport(1600, 900, 1, false)
	lxrod.Browser = b
	return b, p, nil
}

// 查找系统 Edge 的路径。从 [launcher.LookPath] 处拷贝的。
func findEdgePath() (found string, has bool) {
	list := append([]string{"edge"},
		expandWindowsExePaths(
			`Microsoft\Edge\Application\msedge.exe`,
		)...,
	)
	for _, path := range list {
		var err error
		found, err = exec.LookPath(path)
		has = err == nil
		if has {
			break
		}
	}
	return
}

func expandWindowsExePaths(list ...string) []string {
	newList := []string{}
	for _, p := range list {
		newList = append(
			newList,
			filepath.Join(os.Getenv("ProgramFiles"), p),
			filepath.Join(os.Getenv("ProgramFiles(x86)"), p),
			filepath.Join(os.Getenv("LocalAppData"), p),
		)
	}

	return newList
}
