package stwhbclient

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

	"git.bissendorf.co/bissendorf/unifood/m/v2/core/interfaces"
	"git.bissendorf.co/bissendorf/unifood/m/v2/model/external/stwbremen"
)

type stwHBClientFactory struct{}

func NewFactory() *stwHBClientFactory { return &stwHBClientFactory{} }

func Create[T any]() *stwHBClient[T] {
	return New[T]()
}

type stwHBClient[T any] struct {
	interfaces.QueryClient[T]

	client  *http.Client
	baseUrl string
}

func New[T any]() *stwHBClient[T] {
	return &stwHBClient[T]{
		client:  http.DefaultClient,
		baseUrl: "https://content.stw-bremen.de",
	}
}

func (c *stwHBClient[T]) Get(ctx context.Context, queryStatement string, selectStatement string, allowCache bool) (*T, error) {
	// Setup url
	url := c.baseUrl + "/api/kql"
	if !allowCache {
		url = url + "nocache"
	}

	// Create request from query
	fullQuery := fmt.Sprintf(`{"query": "%s", "select": %s}`, queryStatement, selectStatement)
	req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, strings.NewReader(fullQuery))
	if err != nil {
		return nil, fmt.Errorf("unable to create request: %w", err)
	}

	// Perform request
	response, err := c.client.Do(req)
	if err != nil || response.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("performing request failed: %w", err)
	}
	defer response.Body.Close()

	// Read response
	var result stwbremen.Result[T]
	err = json.NewDecoder(response.Body).Decode(&result)
	if err != nil {
		return nil, fmt.Errorf("unable to parse result: %w", err)
	}

	return &result.Result, nil

}
