package report

import (
	"fmt"
	"net"
	"os"

	"github.com/go-resty/resty/v2"
	"github.com/perfect-panel/server/pkg/constant"
	"github.com/perfect-panel/server/pkg/logger"
	"github.com/pkg/errors"
)

// FreePort returns a free TCP port by opening a listener on port 0.
func FreePort() (int, error) {
	l, err := net.Listen("tcp", ":0")
	if err != nil {
		return 0, err
	}
	defer l.Close()
	// Get the assigned port
	addr := l.Addr().(*net.TCPAddr)
	return addr.Port, nil
}

// ModulePort returns the module port from the environment variable or a free port.
func ModulePort() (int, error) {
	// 从环境变量获取端口号
	value, exists := os.LookupEnv("PPANEL_PORT")
	if exists {
		var port int
		_, err := fmt.Sscanf(value, "%d", &port)
		if err != nil {
			return FreePort()
		}
		return port, nil
	}
	return FreePort()
}

// GatewayPort returns the gateway port from the environment variable or a free port.
func GatewayPort() (int, error) {
	// 从环境变量获取端口号
	value, exists := os.LookupEnv("GATEWAY_PORT")
	if exists {
		var port int
		_, err := fmt.Sscanf(value, "%d", &port)
		if err != nil {
			logger.Errorf("Failed to parse GATEWAY_PORT: %v Value %s", err.Error(), value)
			panic(err)
		}
		return port, nil
	}
	return 0, errors.New("could not determine gateway port")
}

// RegisterModule registers a module with the gateway.
func RegisterModule(port int) error {
	// 从环境变量中读取网关模块端口
	gatewayPort, err := GatewayPort()
	if err != nil {
		logger.Errorf("Failed to determine GATEWAY_PORT: %v", err)
		return err
	}

	// 从环境变量中获取通讯密钥
	value, exists := os.LookupEnv("SECRET_KEY")
	if !exists {
		panic("could not determine secret key")
	}

	var response RegisterResponse

	client := resty.New().SetBaseURL(fmt.Sprintf("http://127.0.0.1:%d", gatewayPort))
	result, err := client.R().SetHeader("Content-Type", "application/json").SetBody(RegisterServiceRequest{
		Secret:         value,
		ProxyPath:      "/api",
		ServiceURL:     fmt.Sprintf("http://127.0.0.1:%d", port),
		Repository:     constant.Repository,
		HeartbeatURL:   fmt.Sprintf("http://127.0.0.1:%d/v1/common/heartbeat", port),
		ServiceName:    constant.ServiceName,
		ServiceVersion: constant.Version,
	}).SetResult(&response).Post(RegisterAPI)

	if err != nil {
		logger.Errorf("Failed to register service: %v", err)
		return err
	}

	if result.IsError() {
		return errors.New("failed to register module: " + result.Status())
	}

	if !response.Data.Success {
		logger.Infof("Result: %v", result.String())
		return errors.New("failed to register module: " + response.Message)
	}
	logger.Infof("Module registered successfully: %s", response.Message)
	return nil
}

// IsGatewayMode checks if the application is running in gateway mode.
// It returns true if GATEWAY_MODE is set to "true" and GATEWAY_PORT is valid.
func IsGatewayMode() bool {
	value, exists := os.LookupEnv("GATEWAY_MODE")
	if exists && value == "true" {
		if _, err := GatewayPort(); err == nil {
			return true
		}
	}

	return false
}
