package auth

import (
	"fmt"
	"strings"
	"time"

	"github.com/go-rod/rod"
	"github.com/go-rod/rod/lib/launcher"
	"github.com/go-rod/rod/lib/proto"
	"github.com/go-rod/stealth"
)

// RodAuth 使用 Rod + Stealth 完成 OAuth 授权
type RodAuth struct {
	browser  *rod.Browser
	headless bool
	proxy    string
}

// NewRodAuth 创建 Rod 授权器
func NewRodAuth(headless bool, proxy string) (*RodAuth, error) {
	l := launcher.New().
		Headless(headless).
		Set("disable-blink-features", "AutomationControlled").
		Set("disable-dev-shm-usage").
		Set("no-sandbox").
		Set("disable-gpu").
		Set("disable-extensions").
		Set("disable-background-networking").
		Set("disable-sync").
		Set("disable-translate").
		Set("metrics-recording-only").
		Set("no-first-run")

	if proxy != "" {
		l = l.Proxy(proxy)
	}

	controlURL, err := l.Launch()
	if err != nil {
		return nil, fmt.Errorf("启动浏览器失败: %v", err)
	}

	browser := rod.New().ControlURL(controlURL)
	if err := browser.Connect(); err != nil {
		return nil, fmt.Errorf("连接浏览器失败: %v", err)
	}

	return &RodAuth{
		browser:  browser,
		headless: headless,
		proxy:    proxy,
	}, nil
}

// Close 关闭浏览器
func (r *RodAuth) Close() {
	if r.browser != nil {
		r.browser.Close()
	}
}

// CompleteOAuth 完成 OAuth 授权
func (r *RodAuth) CompleteOAuth(authURL, email, password, teamID string) (string, error) {
	page, err := stealth.Page(r.browser)
	if err != nil {
		return "", fmt.Errorf("创建页面失败: %v", err)
	}
	defer page.Close()

	page = page.Timeout(45 * time.Second)

	if err := page.Navigate(authURL); err != nil {
		return "", fmt.Errorf("访问授权URL失败: %v", err)
	}

	page.MustWaitDOMStable()

	if code := r.checkForCode(page); code != "" {
		return code, nil
	}

	emailInput, err := page.Timeout(5 * time.Second).Element("input[name='email'], input[type='email'], input[name='username']")
	if err != nil {
		return "", fmt.Errorf("未找到邮箱输入框")
	}

	emailInput.MustSelectAllText().MustInput(email)
	time.Sleep(200 * time.Millisecond)

	if btn, _ := page.Timeout(2 * time.Second).Element("button[type='submit']"); btn != nil {
		btn.MustClick()
	}

	time.Sleep(1500 * time.Millisecond)

	if code := r.checkForCode(page); code != "" {
		return code, nil
	}

	passwordInput, err := page.Timeout(8 * time.Second).Element("input[type='password']")
	if err != nil {
		return "", fmt.Errorf("未找到密码输入框")
	}

	passwordInput.MustSelectAllText().MustInput(password)
	time.Sleep(200 * time.Millisecond)

	if btn, _ := page.Timeout(2 * time.Second).Element("button[type='submit']"); btn != nil {
		btn.MustClick()
	}

	for i := 0; i < 66; i++ {
		time.Sleep(300 * time.Millisecond)

		if code := r.checkForCode(page); code != "" {
			return code, nil
		}

		info, _ := page.Info()
		currentURL := info.URL

		if strings.Contains(currentURL, "consent") {
			if btn, _ := page.Timeout(500 * time.Millisecond).Element("button[type='submit']"); btn != nil {
				btn.Click(proto.InputMouseButtonLeft, 1)
			}
		}

		if strings.Contains(currentURL, "authorize") && teamID != "" {
			wsSelector := fmt.Sprintf("[data-workspace-id='%s'], [data-account-id='%s']", teamID, teamID)
			if wsBtn, _ := page.Timeout(500 * time.Millisecond).Element(wsSelector); wsBtn != nil {
				wsBtn.Click(proto.InputMouseButtonLeft, 1)
			}
		}
	}

	return "", fmt.Errorf("授权超时")
}

// checkForCode 检查 URL 中是否包含 code
func (r *RodAuth) checkForCode(page *rod.Page) string {
	info, err := page.Info()
	if err != nil {
		return ""
	}
	if strings.Contains(info.URL, "code=") {
		return ExtractCodeFromCallbackURL(info.URL)
	}
	return ""
}

// CompleteWithRod 使用 Rod + Stealth 完成 S2A 授权
func CompleteWithRod(authURL, email, password, teamID string, headless bool, proxy string) (string, error) {
	auth, err := NewRodAuth(headless, proxy)
	if err != nil {
		return "", err
	}
	defer auth.Close()

	return auth.CompleteOAuth(authURL, email, password, teamID)
}

// CompleteWithBrowser 使用 Rod 完成 S2A 授权 (别名)
func CompleteWithBrowser(authURL, email, password, teamID string, headless bool, proxy string) (string, error) {
	return CompleteWithRod(authURL, email, password, teamID, headless, proxy)
}
