package adapters

import (
	"context"
	"errors"
	"fmt"
	"gitlink.org.cn/JointCloud/pcm-coordinator/internal/svc"
	"gitlink.org.cn/JointCloud/pcm-coordinator/internal/types"
	tool "gitlink.org.cn/JointCloud/pcm-coordinator/pkg/utils"
	"gorm.io/gorm"
	"io/ioutil"
	"k8s.io/apimachinery/pkg/util/json"
	"net/http"
	"net/url"
	"time"

	"github.com/zeromicro/go-zero/core/logx"
)

type CreateClusterLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewCreateClusterLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreateClusterLogic {
	return &CreateClusterLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *CreateClusterLogic) CreateCluster(req *types.ClusterCreateReq) (resp *types.ClusterResp, err error) {
	// 校验集群名称是否唯一
	var count int64
	l.svcCtx.DbEngin.Table("t_cluster").Where("name = ?", req.Name).Count(&count)
	if count > 0 {
		return nil, errors.New("the cluster name is already in use")
	}
	// 校验驱动器是否存在
	adapter := &types.AdapterInfo{}
	result := l.svcCtx.DbEngin.Table("t_adapter").First(&adapter, req.AdapterId)
	if errors.Is(result.Error, gorm.ErrRecordNotFound) {
		return nil, errors.New("adapter does not exist")
	}

	cluster := types.ClusterInfo{}

	tool.Convert(req, &cluster)
	cluster.CreateTime = time.Now().Format("2006-01-02 15:04:05")
	cluster.OwnerId = "0"
	// 获取集群经纬度
	//location, err := GeoMap(req.RegionName)
	//if err != nil {
	//	return nil, err
	//}
	//cluster.Location = location

	cluster.Id = tool.GenSnowflakeIDStr()
	tx := l.svcCtx.DbEngin.Table("t_cluster").Create(&cluster)
	if tx.Error != nil {
		logx.Errorf(tx.Error.Error())
		return nil, errors.New("cluster create failed")
	}

	// push cluster info to adapter
	go func() {
		var adapterServer string
		l.svcCtx.DbEngin.Raw("select server from t_adapter  where id = ?", req.AdapterId).Scan(&adapterServer)
		l.svcCtx.HttpClient.R().
			SetBody(&types.ClusterInfo{
				Name:          req.Name,
				Server:        req.Server,
				Token:         req.Token,
				MonitorServer: req.MonitorServer,
			}).
			ForceContentType("application/json").
			Post(adapterServer + "/api/v1/cluster/info")

	}()

	return
}

func GeoMap(address string) (string, error) {
	// 此处填写您在控制台-应用管理-创建应用后获取的AK
	ak := "d3cc9eee0266d39a52498726d1b82f87"

	// 接口地址
	uri := "https://restapi.amap.com/v3/geocode/geo"

	// 设置请求参数
	params := url.Values{
		"address": []string{address},
		"output":  []string{"json"},
		"key":     []string{ak},
	}

	// 发起请求
	request, err := url.Parse(uri + "?" + params.Encode())
	if nil != err {
		fmt.Printf("host error: %v", err)
		return "", err
	}

	resp, err1 := http.Get(request.String())
	fmt.Printf("url: %s\n", request.String())
	defer resp.Body.Close()
	if err1 != nil {
		fmt.Printf("request error: %v", err1)
		return "", err
	}
	body, err2 := ioutil.ReadAll(resp.Body)
	if err2 != nil {
		fmt.Printf("response error: %v", err2)
	}

	fmt.Println(string(body))
	geoResponse := GeoResponse{}
	json.Unmarshal(body, &geoResponse)
	return geoResponse.Geocodes[0].Location, err
}

type GeoResponse struct {
	Status   string    `json:"status"`
	Info     string    `json:"info"`
	InfoCode string    `json:"infocode"`
	Count    string    `json:"count"`
	Geocodes []GeoCode `json:"geocodes"`
}

type GeoCode struct {
	FormattedAddress string `json:"formatted_address"`
	Country          string `json:"country"`
	Province         string `json:"province"`
	CityCode         string `json:"citycode"`
	City             string `json:"city"`
	District         string `json:"district"`
	Adcode           string `json:"adcode"`
	Number           string `json:"number"`
	Location         string `json:"location"`
	Level            string `json:"level"`
}
