package client

import (
	"bytes"
	"crypto/tls"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"time"
)

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

func New(baseURL, apiKey string, insecure bool) *Client {
	return &Client{
		baseURL: baseURL,
		apiKey:  apiKey,
		httpClient: &http.Client{
			Timeout: 30 * time.Second,
			Transport: &http.Transport{
				TLSClientConfig: &tls.Config{InsecureSkipVerify: insecure},
			},
		},
	}
}

type RegisterRequest struct {
	AgentID      string `json:"agent_id,omitempty"`
	Name         string `json:"name"`
	Hostname     string `json:"hostname"`
	IP           string `json:"ip"`
	AgentVersion string `json:"agent_version,omitempty"`
	Platform     string `json:"platform"`
}

type RegisterResponse struct {
	ID      string `json:"id"`
	Message string `json:"message"`
}

func (c *Client) Register(req RegisterRequest) (string, error) {
	body, _ := json.Marshal(req)
	resp, err := c.doRequest("POST", "/api/v1/agent/register", body)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()
	data, _ := io.ReadAll(resp.Body)
	if resp.StatusCode != http.StatusCreated && resp.StatusCode != http.StatusOK {
		return "", fmt.Errorf("Registrierung fehlgeschlagen (HTTP %d): %s", resp.StatusCode, string(data))
	}
	var r RegisterResponse
	if err := json.Unmarshal(data, &r); err != nil {
		return "", fmt.Errorf("JSON Parse: %v", err)
	}
	return r.ID, nil
}

type HeartbeatRequest struct {
	AgentID      string          `json:"agent_id"`
	AgentVersion string          `json:"agent_version,omitempty"`
	Platform     string          `json:"platform"`
	SystemData   json.RawMessage `json:"system_data,omitempty"`
}

type HeartbeatResponse struct {
	Message         string `json:"message"`
	UpdateAvailable bool   `json:"update_available"`
	UpdateVersion   string `json:"update_version,omitempty"`
	UpdateHash      string `json:"update_hash,omitempty"`
}

func (c *Client) Heartbeat(req HeartbeatRequest) (*HeartbeatResponse, error) {
	body, _ := json.Marshal(req)
	resp, err := c.doRequest("POST", "/api/v1/agent/heartbeat", body)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	data, _ := io.ReadAll(resp.Body)
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("Heartbeat fehlgeschlagen (HTTP %d): %s", resp.StatusCode, string(data))
	}
	var r HeartbeatResponse
	json.Unmarshal(data, &r)
	return &r, nil
}

func (c *Client) doRequest(method, path string, body []byte) (*http.Response, error) {
	req, err := http.NewRequest(method, c.baseURL+path, bytes.NewReader(body))
	if err != nil {
		return nil, err
	}
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("X-API-Key", c.apiKey)
	return c.httpClient.Do(req)
}
