package geminiweb

import (
	"fmt"
	"os"
	"path/filepath"
	"sync"

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

// BrowserManager 管理瀏覽器實例的生命週期
type BrowserManager struct {
	mu           sync.Mutex
	browser      *rod.Browser
	userDataDir  string
	page         *rod.Page
	visible      bool
	isRunning    bool
	currentModel string
}

var (
	globalManager *BrowserManager
	globalMu      sync.Mutex
)

// GetBrowserManager 獲取全域瀏覽器管理器（單例）
func GetBrowserManager(userDataDir string, visible bool) (*BrowserManager, error) {
	globalMu.Lock()
	defer globalMu.Unlock()

	if globalManager != nil {
		return globalManager, nil
	}

	manager, err := NewBrowserManager(userDataDir, visible)
	if err != nil {
		return nil, err
	}

	globalManager = manager
	return globalManager, nil
}

// NewBrowserManager 建立新的瀏覽器管理器
func NewBrowserManager(userDataDir string, visible bool) (*BrowserManager, error) {
	cleanLockFiles(userDataDir)

	if err := os.MkdirAll(userDataDir, 0755); err != nil {
		return nil, fmt.Errorf("failed to create user data dir: %w", err)
	}

	return &BrowserManager{
		userDataDir: userDataDir,
		visible:     visible,
	}, nil
}

// cleanLockFiles 清理 Chrome 的殘留鎖檔案
func cleanLockFiles(userDataDir string) {
	lockFiles := []string{
		"SingletonLock",
		"SingletonCookie",
		"SingletonSocket",
		"Default/SingletonLock",
		"Default/SingletonCookie",
		"Default/SingletonSocket",
	}

	for _, file := range lockFiles {
		path := filepath.Join(userDataDir, file)
		os.Remove(path)
	}
}

// Launch 啟動瀏覽器（如果尚未啟動）
func (m *BrowserManager) Launch() error {
	m.mu.Lock()
	defer m.mu.Unlock()

	if m.isRunning && m.browser != nil {
		return nil
	}

	l := launcher.New()

	if m.visible {
		l = l.Headless(false)
	} else {
		l = l.Headless(true)
	}

	l = l.UserDataDir(m.userDataDir)

	url, err := l.Launch()
	if err != nil {
		return fmt.Errorf("failed to launch browser: %w", err)
	}

	b := rod.New().ControlURL(url)
	if err := b.Connect(); err != nil {
		return fmt.Errorf("failed to connect browser: %w", err)
	}

	m.browser = b

	page, err := b.Page(proto.TargetCreateTarget{URL: "about:blank"})
	if err != nil {
		_ = b.Close()
		return fmt.Errorf("failed to create page: %w", err)
	}

	m.page = page
	m.isRunning = true

	return nil
}

// GetPage 獲取頁面
func (m *BrowserManager) GetPage() (*rod.Page, error) {
	m.mu.Lock()
	defer m.mu.Unlock()

	if !m.isRunning || m.browser == nil {
		return nil, fmt.Errorf("browser not running")
	}

	return m.page, nil
}

// Close 關閉瀏覽器
func (m *BrowserManager) Close() error {
	m.mu.Lock()
	defer m.mu.Unlock()

	if !m.isRunning {
		return nil
	}

	var err error
	if m.browser != nil {
		err = m.browser.Close()
		m.browser = nil
	}

	m.page = nil
	m.isRunning = false
	return err
}

// IsRunning 檢查瀏覽器是否正在運行
func (m *BrowserManager) IsRunning() bool {
	m.mu.Lock()
	defer m.mu.Unlock()
	return m.isRunning
}

// SetCurrentModel 設定當前模型
func (m *BrowserManager) SetCurrentModel(model string) {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.currentModel = model
}

// GetCurrentModel 獲取當前模型
func (m *BrowserManager) GetCurrentModel() string {
	m.mu.Lock()
	defer m.mu.Unlock()
	return m.currentModel
}
