package services

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"go-account-register/config"
	"go-account-register/libs"
	"go-account-register/models"
	"go-account-register/utils"
	"log"
	"math/rand"
	"os"
	"strings"
	"time"

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

type AdsPowerService struct {
}

func (*AdsPowerService) CreateBrowser(accountId int64) string {
	TwitterAccount := InitTwitterAccountService()
	user := TwitterAccount.GetInfo(accountId)
	fingerprint := map[string]interface{}{
		"name":     fmt.Sprintf(`推特账号%d`, accountId),
		"group_id": "0",
		"platform": "",
		"user_proxy_config": map[string]interface{}{
			"proxy_soft": "no_proxy",
			"proxy_type": "socks5",
		},
		"fingerprint_config": map[string]interface{}{
			"webrtc": "proxy",
			"random_ua": map[string]interface{}{
				"ua_browser": []string{
					"chrome",
				},
				"ua_system_version": []string{
					"Windows 10",
					"Windows 11",
					"Mac OS X 15",
					"Mac OS X 14",
				},
			},
		},
	}
	if user.Cookies != nil {
		fingerprint["cookie"] = user.Cookies
	} else {
		cookieObj := []map[string]interface{}{
			{
				"name":     "auth_token",
				"value":    user.Token,
				"domain":   ".x.com",
				"path":     "/",
				"httpOnly": false,
				"secure":   true,
				"session":  true,
				"expires":  proto.TimeSinceEpoch(time.Now().Add(24 * time.Hour).Unix()),
				"sameSite": "unspecified",
			},
		}
		cookieJson, _ := json.Marshal(cookieObj)
		fingerprint["cookie"] = string(cookieJson)
	}
	if user.Proxy != "" {
		var proxyHandle utils.ProxyHandle
		protocol, username, password, ip, port, err2 := proxyHandle.ParseProxy(user.Proxy)
		if err2 == nil {
			fingerprint["user_proxy_config"] = map[string]interface{}{
				"proxy_soft":     "other",
				"proxy_type":     protocol,
				"proxy_host":     ip,
				"proxy_port":     port,
				"proxy_user":     username,
				"proxy_password": password,
			}
		}
	}
	adsPowerRequest := utils.NewAdsPowerRequest()
	jsonStr, _ := adsPowerRequest.CreateBrowser(fingerprint)
	var rawData map[string]interface{}
	if err := json.Unmarshal([]byte(jsonStr.Body()), &rawData); err != nil {
		panic(err)
	}
	log.Println("创建浏览器返回数据", rawData)
	success := rawData["msg"].(string)
	if success == "Success" {
		// 如果成功则将数据存入数据库
		data := rawData["data"].(map[string]interface{})
		id := data["profile_id"].(string)
		// jsonData, _ := json.Marshal(data)
		TwitterAccount.Update(accountId, &models.TwitterAccount{
			BrowserId: id,
		})
		return id
	}
	return ""
}

func (*AdsPowerService) GetRunStatus(id string) int {
	adsPowerRequest := utils.NewAdsPowerRequest()
	jsonStr, _ := adsPowerRequest.GetRunStatus(id)
	var rawData map[string]interface{}
	if err := json.Unmarshal([]byte(jsonStr.Body()), &rawData); err != nil {
		panic(err)
	}
	success := rawData["msg"].(string)
	if success == "success" {
		data := rawData["data"].(map[string]interface{})
		status := data["status"].(string)
		if status == "Active" {
			return 1
		}
		return 0
	}
	return 0
}

// 打开浏览器
func (*AdsPowerService) OpenBrowser(accountId int, browserId string) string {
	// 获取当前
	adsPowerRequest := utils.NewAdsPowerRequest()
	data := map[string]interface{}{
		"profile_id":   browserId,
		"delete_cache": "1",
		// "last_opened_tabs": "0",
	}
	jsonStr, _ := adsPowerRequest.OpenBrowser(data)
	var rawData map[string]interface{}
	if err := json.Unmarshal([]byte(jsonStr.Body()), &rawData); err != nil {
		panic(err)
	}
	success := rawData["msg"].(string)
	if success == "success" {
		data := rawData["data"].(map[string]interface{})
		ws := data["ws"].(map[string]interface{})
		puppeteer := ws["puppeteer"].(string)
		TwitterAccount := InitTwitterAccountService()
		TwitterAccount.Update(int64(accountId), &models.TwitterAccount{
			BrowserUrl: puppeteer,
		})
		return puppeteer
	}
	return ""
}

// 删除浏览器
func (*AdsPowerService) DeleteBrowser(browserId string) bool {
	adsPowerRequest := utils.NewAdsPowerRequest()
	// 先关闭浏览器
	_, err := adsPowerRequest.CloseBrowser(browserId)
	if err != nil {
		log.Println("关闭浏览器失败")
	}
	// 删除浏览器
	_, err2 := adsPowerRequest.DeleteBrowser(browserId)
	log.Println("删除浏览器，", err2 == nil)
	return err2 == nil
}

// 关闭浏览器
func (*AdsPowerService) CloseBrowser(browserId string) bool {
	adsPowerRequest := utils.NewAdsPowerRequest()
	jsonStr, _ := adsPowerRequest.CloseBrowser(browserId)
	var result struct {
		Data    string `json:"data"` // 动态键名 → 值
		Success bool   `json:"success"`
	}
	if err := json.Unmarshal([]byte(jsonStr.Body()), &result); err != nil {
		return false
	}
	return true
}

func randNum(min, max int) int {
	return rand.Intn(max-min) + min
}

func getKey(id string) input.Key {
	keys := map[string]input.Key{
		"0": input.Numpad0,
		"1": input.Numpad1,
		"2": input.Numpad2,
		"3": input.Numpad3,
		"4": input.Numpad4,
		"5": input.Numpad5,
		"6": input.Numpad6,
		"7": input.Numpad7,
		"8": input.Numpad8,
		"9": input.Numpad9,
		"+": input.NumpadAdd,
	}
	return keys[id]
}

// 将指定元素滑动到顶部
func scrollElementLocationCenter(el *rod.Element) {
	// 执行JS：滚动到视口顶部（平滑滚动）
	el.MustEval(`function() { 
			this.scrollIntoView({ 
				behavior: "smooth", 
				block: "center",  // 关键参数：垂直居中
				inline: "center"  // 水平居中
			});  
    }`)

	// 等待滚动完成
	// time.Sleep(2 * time.Second)
}

// 发推
func (*AdsPowerService) SendPost(accountId int, Content string, Img []string) *libs.ErrorInfo {
	// 获取账号状态
	UserService := InitTwitterAccountService()
	user := UserService.GetInfo(int64(accountId))
	if user.LoginStatus != "登录成功" {
		return libs.ErrorCode["AccountHasBeenTakenOffline"]
	}
	// 获取实例
	obj := Browser.GetBitBrowser(user.BrowserUrl)
	page := obj.Page
	// 跳转到首页
	page.MustNavigate("https://x.com/home").MustWaitLoad()

	err := rod.Try(func() {
		// 获取内容输入框
		textInput := page.Timeout(10 * time.Second).MustElement(`div.notranslate.public-DraftEditor-content`)
		textInput.MustInput(Content)
		// 检测字符串是否包含标签
		if strings.Contains(Content, "#") {
			_, err := page.Timeout(5 * time.Second).Element(`div.css-175oi2r.r-14lw9ot.r-z2wwpe.r-1upvrn0.r-h3f8nf.r-11yh6sk.r-1rnoaur`)
			time.Sleep(2 * time.Second)
			if err == nil {
				tagBuuton := page.Timeout(5 * time.Second).MustElement(`div.css-175oi2r.r-14lw9ot.r-z2wwpe.r-1upvrn0.r-h3f8nf.r-11yh6sk.r-1rnoaur div[data-testid="typeaheadResult"] button.css-175oi2r.r-x572qd.r-6dt33c.r-1loqt21.r-o7ynqc.r-6416eg.r-1ny4l3l`)
				tagBuuton.MustClick()
				time.Sleep(2 * time.Second)
			}
		}
		// 循环保存图片到本地
		if len(Img) > 0 {
			var file libs.File
			for _, v := range Img {
				tempFile, _ := file.DownloadImage(v)
				// 结束时删除临时文件
				defer os.Remove(tempFile)
				page.MustElement(`input[data-testid="fileInput"]`).MustSetFiles(tempFile)
				time.Sleep(1 * time.Second)
			}
			time.Sleep(5 * time.Second)
		}
	})
	if errors.Is(err, context.DeadlineExceeded) {
		fmt.Println("请求空闲等待超时！")
		return libs.ErrorCode["SendPostFailed"]
	}

	code := postButton(page)
	if code == 200 {
		return libs.ErrorCode["SendPostSuccessful"]
	}
	return libs.ErrorCode["SendPostFailed"]
}

// 模拟人类刷帖子 限制时间
func (*AdsPowerService) ViewPostsSpecifiedTime(accountId int) *libs.ErrorInfo {
	UserService := InitTwitterAccountService()
	user := UserService.GetInfo(int64(accountId))
	if user.LoginStatus != "登录成功" {
		return libs.ErrorCode["AccountHasBeenTakenOffline"]
	}
	// 获取实例
	obj := Browser.GetBitBrowser(user.BrowserUrl)
	page := obj.Page
	// 跳转到首页
	page.MustNavigate("https://x.com/home").MustWaitLoad()
	forYou := page.Timeout(10 * time.Second).MustElement(`div[data-testid="ScrollSnap-List"] div.css-175oi2r.r-14tvyh0.r-cpa5s6.r-16y2uox:nth-child(1)`)
	forYou.MustClick()
	page.MustWaitNavigation()
	// 是否检测到帖子列表
	err := rod.Try(func() {
		page.Timeout(5 * time.Second).MustElement(`article[data-testid="tweet"]`)
	})

	if errors.Is(err, context.DeadlineExceeded) {
		fmt.Println("请求空闲等待超时！")
		// 关闭浏览器
		Browser.CancelBrowser(accountId)
		return libs.ErrorCode["NetworkTimeout"]
	}
	var status chan string = make(chan string)
	// 获取配置中的时间限制
	appConfig, _ := config.LoadConfig()
	randTime := appConfig.Limit.ViweTimeMin + rand.Intn(appConfig.Limit.ViweTimeMax-appConfig.Limit.ViweTimeMin)
	go loopViewPosts(page, accountId, status, randTime)
	select {
	case res := <-status:
		if res == "fali" {
			return libs.ErrorCode["MaintainAccountFailed"]
		}
		if res == "success" {
			return libs.ErrorCode["MaintainAccountSuccessful"]
		}
	case <-time.After(time.Duration(randTime) * time.Minute):
		return libs.ErrorCode["MaintainAccountSuccessful"]
	}
	return libs.ErrorCode["MaintainAccountSuccessful"]
	// // 获取配置中的时间限制
	// appConfig, _ := config.LoadConfig()
	// randTime := appConfig.Limit.ViweTimeMin + rand.Intn(appConfig.Limit.ViweTimeMax-appConfig.Limit.ViweTimeMin)
	// // 获取当前时间戳
	// startTime := time.Now().Unix()
	// var activeTime int64 = time.Now().Unix()
	// // 函数报错则向这个通道发送消息
	// ch := make(chan string, 1)
	// for activeTime-startTime < int64(randTime*60) {
	// 	select {
	// 	case <-ch:
	// 		// 失败
	// 		return libs.ErrorCode["MaintainAccountFailed"]
	// 	default:
	// 		viewPosts(page, ch, accountId)
	// 	}
	// 	activeTime = time.Now().Unix()
	// }
	// return libs.ErrorCode["MaintainAccountSuccessful"]

	// timer := time.NewTimer(time.Duration(randTime) * time.Minute)
	// defer timer.Stop()

	// ticker := time.NewTicker(1 * time.Second)
	// defer ticker.Stop()

	// for {
	// 	select {
	// 	case <-timer.C:
	// 		fmt.Println("30分钟已到，自动返回")
	// 		return libs.ErrorCode["MaintainAccountSuccessful"]
	// 	case <-ch:
	// 		// 失败
	// 		return libs.ErrorCode["MaintainAccountFailed"]
	// 	case <-ticker.C:
	// 		viewPosts(page, ch, accountId)
	// 	}
	// }

}

func loopViewPosts(page *rod.Page, accountId int, status chan string, randTime int) {
	// 获取当前时间戳
	startTime := time.Now().Unix()
	var activeTime int64 = time.Now().Unix()
	// 函数报错则向这个通道发送消息
	ch := make(chan string, 1)
	for activeTime-startTime < int64(randTime*60) {
		viewPosts(page, ch, accountId)

		activeTime = time.Now().Unix()
	}
	status <- "success"
}

// 查看帖子
func viewPosts(page *rod.Page, ch chan string, accountId int) bool {
	// 滑动滚动条
	log.Println("开始滚动", accountId)
	randomTrackScroll(page)
	log.Println("结束滚动", accountId)
	is := rand.Float64() // 生成随机数
	if is < 0.5 {
		err := rod.Try(func() {
			// 获取视口内的帖子列表
			list, err := getVisibleElements(page, `div[data-testid="tweetText"]`)
			if err != nil || len(list) <= 0 {
				return
			}
			// 等待两秒
			time.Sleep(2 * time.Second)
			// 随机选择一个点击进入帖子
			tweetText := list[rand.Intn(len(list))]
			log.Println("选择一个帖子：", accountId, tweetText)
			scrollElementLocationCenter(tweetText)
			// 禁用链接点击
			_, err3 := page.Evaluate(&rod.EvalOptions{
				JS: `(selector) => {
	      const el = document.querySelector(selector);
	      const links = el.querySelectorAll('a');
	      links.forEach(a => {
	          a.style.pointerEvents = 'none';
	      });
	  	}`,
				JSArgs: []interface{}{`div[data-testid="tweetText"]`},
			})
			if err3 != nil {
			}
			tweetText.MustClick()
			// 恢复链接的点击行为（如果需要）
			_, _ = page.Evaluate(&rod.EvalOptions{
				JS: `(selector) => {
	      const el = document.querySelector(selector);
	      const links = el.querySelectorAll('a');
	      links.forEach(a => {
	          a.style.pointerEvents = '';
	      });
	  	}`,
				JSArgs: []interface{}{`div[data-testid="tweetText"]`},
			})
			page.MustWaitNavigation()
			// 查看帖子 3-5分钟
			timeMin := 3 + rand.Intn(2)
			time.Sleep(time.Duration(timeMin) * time.Minute)
			// 退回到上一步
			// page.MustNavigateBack()
			// 等待新页面加载完成
			// page.MustWaitLoad()
			page.MustNavigate("https://x.com/home").MustWaitLoad()

			// 判断当前URL是否与预期的URL一致
			url := page.MustEval("() => window.location.href").String()
			if url != "https://x.com/home" {
				// 如果不一致  就直接跳转
				page.MustNavigate("https://x.com/home").MustWaitLoad()
			}
		})
		if err != nil {
			ch <- "error"
		}
		return true
	}
	return false
}

// 随机滚动
func randomTrackScroll(page *rod.Page) {
	// height, _ := page.Eval(`() => document.body.scrollHeight`)
	// totalHeight := int(height.Value.Num())
	err := rod.Try(func() {
		var totalHeight int = 1000 + rand.Intn(1000)
		currentPos := 0
		log.Println("获取随机滚动的参数：", totalHeight)
		for currentPos < totalHeight {
			// 随机水平偏移（模拟人类不精确的滑动）
			xOffset := rand.Intn(20) - 10 // -10到10之间的随机值
			yDistance := 50 + rand.Intn(150)

			err := page.Mouse.Scroll(float64(xOffset), float64(yDistance), 1)
			if err != nil {
				log.Printf("滚动失败: %v", err)
			}
			currentPos += yDistance

			// 随机等待和偶尔的回滑
			if rand.Float32() < 0.1 { // 10%概率回滑一点
				backStep := 10 + rand.Intn(30)
				err := page.Mouse.Scroll(0, -float64(backStep), 1)
				if err != nil {
					log.Printf("回滑失败: %v", err)
				}
				currentPos -= backStep
			}

			time.Sleep(time.Millisecond * time.Duration(50+rand.Intn(300)))
			log.Println("滚动完成")
		}
	})
	if err != nil {

	}

}
