package billing

import (
	"context"
	"encoding/json"
	"fmt"
	"net/http"
	"net/url"
	"strings"
	"time"

	"github.com/tidbcloud/aisupport/services/jsm-syncer/config"
)

const defaultSupportPlanLevel = "Basic"

type Client interface {
	Configured() bool
	GetActiveSupportPlan(ctx context.Context, tenantID string) (string, error)
}

type client struct {
	baseURL    string
	httpClient *http.Client
}

func NewClient(conf config.BillingConfig) Client {
	timeout := conf.Timeout
	if timeout == 0 {
		timeout = 10 * time.Second
	}
	return &client{
		baseURL: strings.TrimRight(conf.BaseURL, "/"),
		httpClient: &http.Client{
			Timeout: timeout,
		},
	}
}

func (c *client) Configured() bool {
	return c.baseURL != ""
}

func (c *client) GetActiveSupportPlan(ctx context.Context, tenantID string) (string, error) {
	if !c.Configured() {
		return "", fmt.Errorf("billing client is not configured")
	}
	tenantID = strings.TrimSpace(tenantID)
	if tenantID == "" {
		return "", fmt.Errorf("tenant_id is required")
	}

	endpoint := fmt.Sprintf(
		"%s/api/v1/billing/tenants/%s/binded_support_plan",
		c.baseURL,
		url.PathEscape(tenantID),
	)
	req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint, nil)
	if err != nil {
		return "", err
	}
	req.Header.Set("Accept", "application/json")

	resp, err := c.httpClient.Do(req)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()

	if resp.StatusCode < 200 || resp.StatusCode >= 300 {
		return "", fmt.Errorf("get active support plan failed: status %s", resp.Status)
	}

	var body supportPlanResponse
	if err := json.NewDecoder(resp.Body).Decode(&body); err != nil {
		return "", err
	}
	return normalizeSupportPlanLevel(body.Level), nil
}

type supportPlanResponse struct {
	Level string `json:"level"`
}

func normalizeSupportPlanLevel(level string) string {
	level = strings.TrimSpace(level)
	if level == "" {
		return defaultSupportPlanLevel
	}
	return level
}
