package content

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

	"github.com/insertr/insertr/internal/engine"
)

// HTTPClient implements ContentClient for HTTP API access
type HTTPClient struct {
	BaseURL    string
	APIKey     string
	HTTPClient *http.Client
}

// NewHTTPClient creates a new HTTP content client
func NewHTTPClient(baseURL, apiKey string) *HTTPClient {
	return &HTTPClient{
		BaseURL: strings.TrimSuffix(baseURL, "/"),
		APIKey:  apiKey,
		HTTPClient: &http.Client{
			Timeout: 30 * time.Second,
		},
	}
}

// GetContent fetches a single content item by ID
func (c *HTTPClient) GetContent(siteID, contentID string) (*engine.ContentItem, error) {
	url := fmt.Sprintf("%s/api/content/%s?site_id=%s", c.BaseURL, contentID, siteID)

	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return nil, fmt.Errorf("creating request: %w", err)
	}

	if c.APIKey != "" {
		req.Header.Set("Authorization", "Bearer "+c.APIKey)
	}

	resp, err := c.HTTPClient.Do(req)
	if err != nil {
		return nil, fmt.Errorf("making request: %w", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode == 404 {
		return nil, nil // Content not found, return nil without error
	}

	if resp.StatusCode != 200 {
		return nil, fmt.Errorf("API error: %s", resp.Status)
	}

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("reading response: %w", err)
	}

	var item engine.ContentItem
	if err := json.Unmarshal(body, &item); err != nil {
		return nil, fmt.Errorf("parsing response: %w", err)
	}

	return &item, nil
}

// GetBulkContent fetches multiple content items by IDs
func (c *HTTPClient) GetBulkContent(siteID string, contentIDs []string) (map[string]engine.ContentItem, error) {
	if len(contentIDs) == 0 {
		return make(map[string]engine.ContentItem), nil
	}

	// Build query parameters
	params := url.Values{}
	params.Set("site_id", siteID)
	for _, id := range contentIDs {
		params.Add("ids", id)
	}

	url := fmt.Sprintf("%s/api/content/bulk?%s", c.BaseURL, params.Encode())

	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return nil, fmt.Errorf("creating request: %w", err)
	}

	if c.APIKey != "" {
		req.Header.Set("Authorization", "Bearer "+c.APIKey)
	}

	resp, err := c.HTTPClient.Do(req)
	if err != nil {
		return nil, fmt.Errorf("making request: %w", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != 200 {
		return nil, fmt.Errorf("API error: %s", resp.Status)
	}

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("reading response: %w", err)
	}

	var response engine.ContentResponse
	if err := json.Unmarshal(body, &response); err != nil {
		return nil, fmt.Errorf("parsing response: %w", err)
	}

	// Convert slice to map for easy lookup
	result := make(map[string]engine.ContentItem)
	for _, item := range response.Content {
		result[item.ID] = item
	}

	return result, nil
}

// GetAllContent fetches all content for a site
func (c *HTTPClient) GetAllContent(siteID string) (map[string]engine.ContentItem, error) {
	url := fmt.Sprintf("%s/api/content?site_id=%s", c.BaseURL, siteID)

	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return nil, fmt.Errorf("creating request: %w", err)
	}

	if c.APIKey != "" {
		req.Header.Set("Authorization", "Bearer "+c.APIKey)
	}

	resp, err := c.HTTPClient.Do(req)
	if err != nil {
		return nil, fmt.Errorf("making request: %w", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != 200 {
		return nil, fmt.Errorf("API error: %s", resp.Status)
	}

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("reading response: %w", err)
	}

	var response engine.ContentResponse
	if err := json.Unmarshal(body, &response); err != nil {
		return nil, fmt.Errorf("parsing response: %w", err)
	}

	// Convert slice to map for easy lookup
	result := make(map[string]engine.ContentItem)
	for _, item := range response.Content {
		result[item.ID] = item
	}

	return result, nil
}
