// Code generated by django-cfg/django_client - DO NOT EDIT.
// Generated at: {{ generated_at }}

package {{ package_name }}

import (
{% if has_request_body %}
	"bytes"
{% endif %}
	"context"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
{% if has_query_params %}
	"net/url"
{% endif %}
{% if has_path_params %}
	"strings"
{% endif %}

	// Import shared package for error types
	"{{ module_name }}/shared"
)

// Client provides access to {{ package_name }} operations.
type Client struct {
	BaseURL    string
	HTTPClient *http.Client
	Token      string
}

// NewClient creates a new {{ package_name }} client.
func NewClient(baseURL string, httpClient *http.Client, token string) *Client {
	return &Client{
		BaseURL:    baseURL,
		HTTPClient: httpClient,
		Token:      token,
	}
}

{% for operation in operations %}
{% if operation.query_params_struct %}
// {{ operation.query_params_struct.name }} contains query parameters for {{ operation.name }}.
type {{ operation.query_params_struct.name }} struct {
{% for field in operation.query_params_struct.fields %}
	{{ field.name }} {{ field.type }} `json:"{{ field.json_name }}"`
{% endfor %}
}

{% endif %}
{% endfor %}

{% for operation in operations %}
// {{ operation.name }} - {{ operation.description | replace('\n', '\n// ') }}
func (c *Client) {{ operation.name }}(ctx context.Context{% for param in operation.parameters %}, {{ param.name }} {{ param.type }}{% endfor %}{% if operation.request_type %}, body {{ operation.request_type }}{% endif %}) ({{ operation.response_type }}, error) {
	var result {{ operation.response_type }}

	// Build URL
	path := "{{ operation.path }}"
{% for param in operation.parameters %}
{% if param.location == "path" %}
	path = strings.ReplaceAll(path, "{{ '{' }}{{ param.name }}{{ '}' }}", fmt.Sprintf("%v", {{ param.name }}))
{% endif %}
{% endfor %}

{% if operation.parameters|selectattr("location", "equalto", "query")|list %}
	// Add query parameters
	if params != nil {
		query := url.Values{}
		// TODO: Add query parameter marshaling based on struct fields
		path = path + "?" + query.Encode()
	}
{% endif %}

	u := c.BaseURL + path

	// Prepare request body
	var reqBody io.Reader
{% if operation.request_type %}
	bodyBytes, err := json.Marshal(body)
	if err != nil {
		return result, fmt.Errorf("failed to marshal request body: %w", err)
	}
	reqBody = bytes.NewReader(bodyBytes)
{% endif %}

	// Create request
	req, err := http.NewRequestWithContext(ctx, "{{ operation.http_method }}", u, reqBody)
	if err != nil {
		return result, fmt.Errorf("failed to create request: %w", err)
	}

	// Set headers
{% if operation.request_type %}
	req.Header.Set("Content-Type", "application/json")
{% endif %}
	if c.Token != "" {
		req.Header.Set("Authorization", "Bearer "+c.Token)
	}

	// Execute request
	resp, err := c.HTTPClient.Do(req)
	if err != nil {
		return result, &shared.NetworkError{
			Err:    err,
			Method: "{{ operation.http_method }}",
			URL:    u,
		}
	}
	defer resp.Body.Close()

	// Read response body
	respBody, err := io.ReadAll(resp.Body)
	if err != nil {
		return result, &shared.NetworkError{
			Err:    fmt.Errorf("failed to read response: %w", err),
			Method: "{{ operation.http_method }}",
			URL:    u,
		}
	}

	// Check status code
	if resp.StatusCode < 200 || resp.StatusCode >= 300 {
		return result, shared.ParseAPIError(resp.StatusCode, resp.Status, "{{ operation.http_method }}", u, respBody)
	}

{% if operation.http_method != "DELETE" %}
	// Decode response
	if err := json.Unmarshal(respBody, &result); err != nil {
		return result, &shared.UnmarshalError{
			Err:  err,
			Body: respBody,
			Type: "{{ operation.response_type }}",
		}
	}
{% endif %}

	return result, nil
}

{% endfor %}
