package app

import (
	"encoding/base64"
	"encoding/json"
	"fmt"
	"io"
	"log/slog"
	"net/http"
	"proxy-server/gateway/core"
	"proxy-server/gateway/env"
	"strings"
)

func Online(name string) (err error) {
	var resp string
	resp, err = call(env.EndpointOnline, map[string]any{
		"name":    name,
		"version": core.Version,
	})
	if err != nil {
		return err
	}

	var body struct {
		Id      int32             `json:"id"`
		Secret  string            `json:"secret"`
		Permits []*core.PermitDef `json:"permits"`
		Edges   []*core.Edge      `json:"edges"`
	}
	err = json.Unmarshal([]byte(resp), &body)
	if err != nil {
		return err
	}

	Id = body.Id
	PlatformSecret = body.Secret
	for _, def := range body.Permits {
		StorePermit(def)
	}
	for _, edge := range body.Edges {
		err := StoreEdge(edge)
		if err != nil {
			slog.Error("存储边缘节点失败", "err", err, "edge", edge)
		}
	}
	return nil
}

func Offline() (err error) {
	_, err = call(env.EndpointOffline, map[string]any{
		"id": Id,
	})
	return err
}

func Update(data []*core.Edge) (err error) {
	_, err = call(env.EndpointUpdate, map[string]any{
		"id":    Id,
		"edges": data,
	})
	if err != nil {
		err = fmt.Errorf("更新节点数据失败：%w", err)
	}
	return err
}

func call(endpoint string, body any) (string, error) {
	bodyStr, err := json.Marshal(body)
	if err != nil {
		panic(err)
	}

	req, err := http.NewRequest("POST", endpoint, strings.NewReader(string(bodyStr)))
	if err != nil {
		panic(err)
	}

	var auth = base64.RawURLEncoding.EncodeToString([]byte(env.ClientId + ":" + env.ClientSecret))
	var basic = fmt.Sprintf("Basic %s", auth)
	req.Header.Set("Authorization", basic)
	req.Header.Set("Content-Type", "application/json")

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return "", err
	}
	defer func(Body io.ReadCloser) {
		_ = Body.Close()
	}(resp.Body)

	if resp.StatusCode != http.StatusOK {
		return "", fmt.Errorf("请求失败，状态码：%d", resp.StatusCode)
	}

	respBody, err := io.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}

	return string(respBody), nil
}
