package httpclient

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

type EncryptRequest struct {
	Nonce      string `json:"nonce"`
	Ciphertext string `json:"ciphertext"`
	Alg        string `json:"alg"`
}

type DecryptResponse struct {
	OK    bool   `json:"ok"`
	Error string `json:"error,omitempty"`
}

// PostCipher sends ciphertext+nonce to server and returns decoded response body.
func PostCipher(ctx context.Context, url string, req *EncryptRequest) (*DecryptResponse, int, error) {
	body, err := json.Marshal(req)
	if err != nil {
		return nil, 0, fmt.Errorf("marshal request: %w", err)
	}
	// Print HTTP request info
	fmt.Printf("HTTP Request -> method=POST url=%s\n", url)
	fmt.Printf("HTTP Request Headers -> Content-Type: application/json\n")
	fmt.Printf("HTTP Request Body -> %s\n", string(body))

	h := &http.Client{Timeout: 10 * time.Second}
	hreq, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(body))
	if err != nil {
		return nil, 0, fmt.Errorf("new request: %w", err)
	}
	hreq.Header.Set("Content-Type", "application/json")

	start := time.Now()
	resp, err := h.Do(hreq)
	if err != nil {
		return nil, 0, fmt.Errorf("http do: %w", err)
	}
	defer resp.Body.Close()
	respBody, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, resp.StatusCode, fmt.Errorf("read response: %w", err)
	}
	latency := time.Since(start)
	fmt.Printf("HTTP Response <- status=%d duration=%s\n", resp.StatusCode, latency.String())
	if ct := resp.Header.Get("Content-Type"); ct != "" {
		fmt.Printf("HTTP Response Headers <- Content-Type: %s\n", ct)
	}
	fmt.Printf("HTTP Response Body <- %s\n", string(respBody))
	var out DecryptResponse
	if err := json.Unmarshal(respBody, &out); err != nil {
		return nil, resp.StatusCode, fmt.Errorf("unmarshal response: %w", err)
	}
	return &out, resp.StatusCode, nil
}


