package sub2api

import (
	"bytes"
	"context"
	"net/http"
	"strings"
)

func (c *Client) ProbeCapabilities(ctx context.Context) (HostCapabilities, error) {
	groups, err := c.probeEndpoint(ctx, http.MethodGet, "/api/v1/admin/groups", nil)
	if err != nil {
		return HostCapabilities{}, err
	}

	channels, err := c.probeEndpoint(ctx, http.MethodGet, "/api/v1/admin/channels", nil)
	if err != nil {
		return HostCapabilities{}, err
	}

	plans, err := c.probeEndpoint(ctx, http.MethodGet, "/api/v1/admin/payment/plans", nil)
	if err != nil {
		return HostCapabilities{}, err
	}

	accounts, err := c.probeEndpoint(ctx, http.MethodGet, "/api/v1/admin/accounts", nil)
	if err != nil {
		return HostCapabilities{}, err
	}

	accountTest, err := c.probeEndpoint(ctx, http.MethodGet, "/api/v1/admin/accounts/__probe__/test", nil)
	if err != nil {
		return HostCapabilities{}, err
	}

	accountModels, err := c.probeEndpoint(ctx, http.MethodGet, "/api/v1/admin/accounts/__probe__/models", nil)
	if err != nil {
		return HostCapabilities{}, err
	}

	subscriptions, err := c.probeEndpoint(ctx, http.MethodGet, "/api/v1/admin/subscriptions/assign", nil)
	if err != nil {
		return HostCapabilities{}, err
	}

	return HostCapabilities{
		Groups:        groups,
		Channels:      channels,
		Plans:         plans,
		Accounts:      accounts,
		AccountTest:   accountTest,
		AccountModels: accountModels,
		Subscriptions: subscriptions,
	}, nil
}

func (c *Client) probeEndpoint(ctx context.Context, method, path string, requestBody any) (bool, error) {
	statusCode, _, body, err := c.perform(ctx, method, path, requestBody)
	if err != nil {
		return false, err
	}

	switch {
	case statusCode >= http.StatusOK && statusCode < http.StatusMultipleChoices:
		return true, nil
	case statusCode == http.StatusUnauthorized || statusCode == http.StatusForbidden:
		return false, newHTTPError(method, path, statusCode, body)
	case statusCode == http.StatusNotFound || statusCode == http.StatusMethodNotAllowed:
		return false, nil
	case statusCode >= http.StatusBadRequest && statusCode < http.StatusInternalServerError:
		return true, nil
	default:
		return false, newHTTPError(method, path, statusCode, body)
	}
}

func looksLikeExistingEndpoint(headers http.Header, body []byte) bool {
	contentType := strings.ToLower(headers.Get("Content-Type"))
	trimmedBody := bytes.TrimSpace(body)

	if strings.Contains(contentType, "application/json") || strings.Contains(contentType, "text/event-stream") {
		return true
	}
	if len(trimmedBody) == 0 {
		return false
	}
	if trimmedBody[0] == '{' || trimmedBody[0] == '[' {
		return true
	}

	return false
}
