package pig

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/gogf/gf/v2/net/gtrace"
	"github.com/gogf/gf/v2/os/glog"
	"github.com/gogf/gf/v2/os/gtime"
	"kami/internal/service"
	"kami/utility/cache"
	"sync"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/net/gclient"
)

type InternalClient struct {
	Client *gclient.Client
}

var client *InternalClient

func NewClient() *InternalClient {
	sync.OnceFunc(func() {
		client = &InternalClient{
			Client: g.Client(),
		}
	})()
	return client
}

func (c *InternalClient) getToken(ctx context.Context) (string, error) {
	tokenKey := cache.PrefixTracePigAccount.Key("PrefixTracePigAccount")
	tokenVar, err := cache.NewCache().Get(ctx, tokenKey)
	if err != nil {
		return "", err
	}
	if tokenVar != nil && tokenVar.String() != "" {
		return tokenVar.String(), nil
	}

	// 从设置中获取豪猪账号和密码
	var username, password string
	settings, err := service.CamelOil().GetCamelOilSettings(ctx)
	if err != nil || settings == nil {
		// 如果获取设置失败，使用默认值（向后兼容）
		return "", errors.New("获取设置失败")
	} else {
		// 使用设置中的账号密码
		username = settings.HaozhuUsername
		password = settings.HaozhuPassword
	}

	resp, err := c.Client.Post(ctx, fmt.Sprintf("https://api.haozhuyun.com/sms/?api=login&user=%s&pass=%s", username, password))
	if err != nil {
		return "", err
	}

	respData := struct {
		Token string `json:"token"`
		Code  int    `json:"code"`
		Msg   string `json:"msg"`
	}{}
	err = json.Unmarshal(resp.ReadAll(), &respData)
	if err != nil {
		return "", err
	}
	if respData.Token == "" {
		return "", fmt.Errorf("获取token失败")
	}
	_ = cache.NewCache().Set(ctx, tokenKey, respData.Token, gtime.D)
	return respData.Token, nil
}

// GetAccountInfo 获取账号信息
func (c *InternalClient) GetAccountInfo(ctx context.Context) (string, error) {
	ctx, span := gtrace.NewSpan(ctx, "pig.GetAccountInfo")
	defer span.End()
	//尝试100次，直到获取到号码为止
	token, err := c.getToken(ctx)
	if err != nil {
		return "", err
	}
	respBody := struct {
		Token string `json:"token"`
		SID   int    `json:"sid"`
	}{
		Token: token,
		SID:   21108,
	}

	resp, err := c.Client.Post(ctx, fmt.Sprintf("https://api.haozhuyun.com/sms?api=getPhone&token=%s&sid=%d&Province=&ascription=&isp=", respBody.Token, respBody.SID))
	if err != nil {
		return "", err
	}
	respStr := resp.ReadAllString()
	glog.Info(ctx, "获取信息", respStr)
	respStruct := struct {
		Phone string `json:"phone"`
	}{}
	err = json.Unmarshal([]byte(respStr), &respStruct)
	if respStruct.Phone != "" {
		return respStruct.Phone, nil
	}
	return "", fmt.Errorf("获取账号失败")
}

// CheckVerifyCode 检测验证码是否已接收
func (c *InternalClient) CheckVerifyCode(ctx context.Context, phone string) (code string, received bool, err error) {
	token, err := c.getToken(ctx)
	if err != nil {
		return "", false, err
	}
	//构建 url 请求
	resp, err := c.Client.Post(ctx, fmt.Sprintf("https://api.haozhuwang.cn/sms/?api=getMessage&token=%s&sid=%s&phone=%s", token, "21108", phone))
	if err != nil {
		return "", false, err
	}
	respStr := resp.ReadAllString()
	glog.Info(ctx, "获取信息", respStr)
	respStruct := struct {
		Code json.Number `json:"code"`
		Msg  string      `json:"msg"`
		Sms  string      `json:"sms"`
		Yzm  string      `json:"yzm"`
	}{}
	err = json.Unmarshal([]byte(respStr), &respStruct)
	if err != nil {
		return "", false, err
	}
	glog.Info(ctx, respStruct)
	if respStruct.Code != "0" {
		return "", false, nil
	}
	return respStruct.Yzm, true, nil
}
