package api

import (
	"bytes"
	"fmt"
	"image"
	"io"
	"math/rand"
	"net/http"
	"net/url"
	"strings"
	"time"
)

// BsPhp 结构体，对应 Python 中的 BsPhp 类
type BsPhp struct {
	codeURL     string
	url         string
	key         string
	mutualKey   string
	method      string
	sendSignKey string
	recSignKey  string
	bsPhpSeSsL  string
}

// NewBsPhp 创建一个新的 BsPhp 实例
func NewBsPhp(url, key, mutualKey, method, sendSignKey, recSignKey string) *BsPhp {
	if method == "" {
		method = "POST"
	}
	return &BsPhp{
		codeURL:     "https://app.bsphp.com/index.php?m=coode&sessl=",
		url:         url,
		key:         key,       // 数据加密密码
		mutualKey:   mutualKey, // 通讯认证key
		method:      method,
		sendSignKey: sendSignKey,
		recSignKey:  recSignKey,
		bsPhpSeSsL:  "",
	}
}

// sendData 发送数据到服务器
func (b *BsPhp) sendData(api string, attachParam map[string]string) map[string]interface{} {
	// 使用新的随机数生成方法（Go 1.20+）
	rng := rand.New(rand.NewSource(time.Now().UnixNano()))
	digits := "0123456789"
	appsafecode := ""
	for i := 0; i < 6; i++ {
		appsafecode += string(digits[rng.Intn(len(digits))])
	}

	// 构建参数
	param := map[string]string{
		"api":         api,
		"BSphpSeSsL":  b.bsPhpSeSsL,
		"date":        time.Now().Format("2006-01-02#15:04:05"),
		"md5":         "",
		"mutualkey":   b.mutualKey,
		"appsafecode": appsafecode,
	}

	// 合并附加参数
	for k, v := range attachParam {
		param[k] = v
	}

	// 将参数转换为 URL 编码的字符串
	values := url.Values{}
	for k, v := range param {
		values.Add(k, v)
	}
	data := SendData(b.url, values.Encode(), b.key, b.method, b.sendSignKey, b.recSignKey)

	// 验证 appsafecode
	if data == nil {
		return nil
	}

	if dataAppsafecode, ok := data["appsafecode"].(string); ok && dataAppsafecode != appsafecode {
		data["data"] = "appsafecode 安全参数验证不通过，自己写保护代码"
	}

	return data
}

// Connect 网络连接验证
func (b *BsPhp) Connect() bool {
	result := b.sendData("internet.in", nil)
	return result != nil && result["data"] == "1"
}

// GetSeSsl 取BSphpSeSsL
func (b *BsPhp) GetSeSsl() bool {
	result := b.sendData("BSphpSeSsL.in", nil)
	if result == nil || result["data"] == "" {
		return false
	}
	b.bsPhpSeSsL = result["data"].(string)
	return true
}

// CodeIsOpen 获取验证码是否开启
func (b *BsPhp) CodeIsOpen(types string) []string {
	result := b.sendData("getsetimag.in", map[string]string{"type": types})
	if result != nil && result["data"] != nil {
		return strings.Split(result["data"].(string), "|")
	}
	return nil
}

// GetVersion 获取版本
func (b *BsPhp) GetVersion() string {
	result := b.sendData("v.in", nil)
	if result != nil && result["data"] != nil {
		return result["data"].(string)
	}
	return ""
}

// GetURL 获取地址
func (b *BsPhp) GetURL() string {
	result := b.sendData("url.in", nil)
	if result != nil && result["data"] != nil {
		return result["data"].(string)
	}
	return ""
}

// GetNotice 获取公告
func (b *BsPhp) GetNotice() string {
	result := b.sendData("gg.in", nil)
	if result != nil && result["data"] != nil {
		return result["data"].(string)
	}
	return "公告获取失败"
}

// GetCode 获取验证码
// GetCode 获取验证码
// GetCode 获取验证码
func (b *BsPhp) GetCode() []byte {
	url := b.codeURL + b.bsPhpSeSsL
	println("请求验证码URL:", url)

	resp, err := http.Get(url)
	if err != nil {
		println("HTTP请求失败:", err.Error())
		return nil
	}
	defer resp.Body.Close()

	// 检查HTTP状态码
	if resp.StatusCode != 200 {
		println("HTTP状态码错误:", resp.StatusCode)
		return nil
	}

	// 检查Content-Type
	contentType := resp.Header.Get("Content-Type")
	println("Content-Type:", contentType)

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		println("读取响应体失败:", err.Error())
		return nil
	}

	// 检查数据长度
	if len(body) == 0 {
		println("接收到空的图片数据")
		return nil
	}

	println("成功获取验证码图片，大小:", len(body), "字节")

	// 打印数据的前32个字节用于调试
	if len(body) >= 32 {
		fmt.Printf("数据前32字节: %x\n", body[:32])
	} else {
		fmt.Printf("所有数据: %x\n", body)
	}

	// 检查JPEG文件头
	if len(body) >= 2 {
		if body[0] == 0xFF && body[1] == 0xD8 {
			println("JPEG文件头正确")
		} else {
			println("JPEG文件头错误，前两个字节:", fmt.Sprintf("%02x %02x", body[0], body[1]))
		}
	}

	// 尝试用Go标准库解码验证
	reader := bytes.NewReader(body)
	_, format, err := image.DecodeConfig(reader)
	if err != nil {
		println("Go标准库解码失败:", err.Error())
		// 尝试检查是否是HTML错误页面
		if strings.Contains(string(body[:min(100, len(body))]), "<html") ||
			strings.Contains(string(body[:min(100, len(body))]), "<!DOCTYPE") {
			println("接收到的可能是HTML页面而不是图片")
		}
		return nil
	}
	println("Go标准库解码成功，格式:", format)

	return body
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

// Login 账号登录
func (b *BsPhp) Login(user, password, coode, key, maxoror string) interface{} {
	param := map[string]string{
		"user":    user,
		"pwd":     password,
		"key":     key,
		"coode":   coode,
		"maxoror": maxoror,
	}
	result := b.sendData("login.lg", param)
	// fmt.Println("登录", result)
	if result == nil {
		return "系统错误，登录失败！"
	}

	code, ok := result["code"].(float64)

	if !ok || code != 1011 {
		return result["data"]
	}

	b.bsPhpSeSsL = result["SeSsL"].(string)
	return strings.Split(result["data"].(string), "|")
}

// Reg 注册
func (b *BsPhp) Reg(user, pwd, pwdb, coode, mobile, mibaoWenti, mibaoDaan, qq, mail, key, extension string) string {
	param := map[string]string{
		"user":        user,
		"pwd":         pwd,
		"pwdb":        pwdb,
		"qq":          qq,
		"mail":        mail,
		"key":         key,
		"coode":       coode,
		"mobile":      mobile,
		"mibao_wenti": mibaoWenti,
		"mibao_daan":  mibaoDaan,
		"extension":   extension,
	}
	result := b.sendData("registration.lg", param)
	if result == nil {
		return "系统错误，注册失败！"
	}
	return result["data"].(string)
}

// Unbind 解绑
func (b *BsPhp) Unbind(user, password string) string {
	param := map[string]string{
		"user": user,
		"pwd":  password,
	}
	result := b.sendData("jiekey.lg", param)
	if result == nil {
		return "系统错误，解绑失败！"
	}
	return result["data"].(string)
}

// Pay 充值
func (b *BsPhp) Pay(user, userpwd string, userset bool, card, pwd string) string {
	usersetValue := "0"
	if userset {
		usersetValue = "1"
	}
	param := map[string]string{
		"user":    user,
		"userpwd": userpwd,
		"userset": usersetValue, // 是否验证密码
		"ka":      card,
		"pwd":     pwd,
	}
	result := b.sendData("chong.lg", param)
	if result == nil {
		return "系统错误，充值失败！"
	}
	return result["data"].(string)
}

// BackPass 找回密码
func (b *BsPhp) BackPass(user, pwd, pwdb, wenti, daan, coode string) string {
	param := map[string]string{
		"user":  user,
		"pwd":   pwd,
		"pwdb":  pwdb,
		"wenti": wenti,
		"daan":  daan,
		"coode": coode,
	}
	result := b.sendData("backto.lg", param)
	if result == nil {
		return "系统错误，找回密码失败！"
	}
	return result["data"].(string)
}

// EditPass 修改密码
func (b *BsPhp) EditPass(user, pwd, pwda, pwdb, img string) string {
	param := map[string]string{
		"user": user,
		"pwd":  pwd,
		"pwda": pwda,
		"pwdb": pwdb,
		"img":  img,
	}
	result := b.sendData("password.lg", param)
	if result == nil {
		return "系统错误，修改密码失败！"
	}
	return result["data"].(string)
}

// Feedback 意见反馈
func (b *BsPhp) Feedback(user, pwd, table, qq, leix, text, coode string) string {
	param := map[string]string{
		"user":  user,
		"pwd":   pwd,
		"table": table,
		"qq":    qq,
		"leix":  leix,
		"text":  text,
		"coode": coode,
	}
	result := b.sendData("liuyan.in", param)
	if result == nil {
		return "系统错误，意见反馈失败！"
	}
	return result["data"].(string)
}

// GetServerTime 获取服务器系统时间
func (b *BsPhp) GetServerTime() string {
	param := map[string]string{
		"date": time.Now().Format("2006-01-02 15:04:05"),
	}
	result := b.sendData("date.in", param)
	if result == nil {
		return "系统错误，取系统时间失败！"
	}
	return result["data"].(string)
}

// GetBind 取用户绑定特征
func (b *BsPhp) GetBind() string {
	result := b.sendData("userkey.lg", nil)
	if result == nil {
		return "系统错误，取绑定特征失败！"
	}
	return result["data"].(string)
}

// GetEndTime 取用户到期时间
func (b *BsPhp) GetEndTime() string {
	result := b.sendData("vipdate.lg", nil)
	if result == nil {
		return "系统错误，取到期时间失败！"
	}
	return result["data"].(string)
}

// GetSoftInfo 取软件描述介绍
func (b *BsPhp) GetSoftInfo() string {
	result := b.sendData("miao.in", nil)
	if result == nil {
		return "系统错误，获取软件介绍失败！"
	}
	return result["data"].(string)
}

// GetVerify 获取验证数据
func (b *BsPhp) GetVerify(key string) string {
	param := map[string]string{
		"key": key,
	}
	result := b.sendData("lgkey.lg", param)
	if result == nil {
		return "系统错误，取验证数据失败！"
	}
	return result["data"].(string)
}

// GetUserInfo 获取用户信息
func (b *BsPhp) GetUserInfo(info string) string {
	param := map[string]string{
		"info": info,
	}
	result := b.sendData("getuserinfo.lg", param)
	if result == nil {
		return "系统错误，取用户信息失败！"
	}
	return result["data"].(string)
}

// GetLoginStatus 取登录状态
func (b *BsPhp) GetLoginStatus() string {
	result := b.sendData("lginfo.lg", nil)
	if result == nil {
		return "系统错误，获取登录状态失败！"
	}
	return result["data"].(string)
}
