package reporter

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

	"github.com/dd0c/drift-agent/pkg/models"
)

// Reporter sends drift reports to the dd0c SaaS platform.
type Reporter struct {
	endpoint   string
	apiKey     string
	httpClient *http.Client
}

// New creates a reporter with mTLS support.
func New(endpoint, apiKey, certFile, keyFile string) (*Reporter, error) {
	tlsConfig := &tls.Config{
		MinVersion: tls.VersionTLS13,
	}

	// Load client cert for mTLS if provided
	if certFile != "" && keyFile != "" {
		cert, err := tls.LoadX509KeyPair(certFile, keyFile)
		if err != nil {
			return nil, fmt.Errorf("load mTLS cert: %w", err)
		}
		tlsConfig.Certificates = []tls.Certificate{cert}
	}

	return &Reporter{
		endpoint: endpoint,
		apiKey:   apiKey,
		httpClient: &http.Client{
			Timeout: 30 * time.Second,
			Transport: &http.Transport{
				TLSClientConfig: tlsConfig,
			},
		},
	}, nil
}

// Send transmits a drift report to the SaaS ingestion endpoint.
func (r *Reporter) Send(report *models.DriftReport) error {
	body, err := json.Marshal(report)
	if err != nil {
		return fmt.Errorf("marshal report: %w", err)
	}

	req, err := http.NewRequest("POST", r.endpoint+"/v1/ingest/drift", bytes.NewReader(body))
	if err != nil {
		return fmt.Errorf("create request: %w", err)
	}

	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Authorization", "Bearer "+r.apiKey)
	req.Header.Set("X-DD0C-Agent-Version", report.AgentVersion)
	req.Header.Set("X-DD0C-Nonce", report.Nonce)

	resp, err := r.httpClient.Do(req)
	if err != nil {
		return fmt.Errorf("send report: %w", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode == 409 {
		return fmt.Errorf("nonce already used (replay rejected)")
	}

	if resp.StatusCode != 200 && resp.StatusCode != 201 {
		return fmt.Errorf("unexpected status %d", resp.StatusCode)
	}

	return nil
}
