// Package dsms provides a client for archiving compliance artifacts to the
// DSMS gateway (IPFS-backed tamper-proof document storage).
package dsms

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"mime/multipart"
	"net/http"
	"os"
	"time"
)

// ArchiveResult is the response from a successful DSMS archive operation.
type ArchiveResult struct {
	CID        string `json:"cid"`
	Size       int    `json:"size"`
	GatewayURL string `json:"gateway_url"`
}

var gatewayURL = getEnv("DSMS_GATEWAY_URL", "http://dsms-gateway:8082")

func getEnv(key, fallback string) string {
	if v := os.Getenv(key); v != "" {
		return v
	}
	return fallback
}

// Archive stores content in DSMS and returns the CID.
// Non-critical: returns nil on failure (logs warning).
func Archive(content []byte, filename, documentType, documentID, version string) *ArchiveResult {
	var buf bytes.Buffer
	w := multipart.NewWriter(&buf)

	part, err := w.CreateFormFile("file", filename)
	if err != nil {
		log.Printf("[dsms] multipart error: %v", err)
		return nil
	}
	if _, err := part.Write(content); err != nil {
		log.Printf("[dsms] write error: %v", err)
		return nil
	}

	_ = w.WriteField("document_type", documentType)
	_ = w.WriteField("document_id", documentID)
	_ = w.WriteField("version", version)
	_ = w.WriteField("language", "de")
	w.Close()

	client := &http.Client{Timeout: 60 * time.Second}
	req, err := http.NewRequest("POST", gatewayURL+"/api/v1/documents", &buf)
	if err != nil {
		log.Printf("[dsms] request error: %v", err)
		return nil
	}
	req.Header.Set("Content-Type", w.FormDataContentType())
	req.Header.Set("Authorization", "Bearer system-backend")

	resp, err := client.Do(req)
	if err != nil {
		log.Printf("[dsms] unavailable: %v", err)
		return nil
	}
	defer resp.Body.Close()

	body, _ := io.ReadAll(resp.Body)
	if resp.StatusCode != 200 {
		log.Printf("[dsms] archive failed (%d): %s", resp.StatusCode, string(body[:min(len(body), 200)]))
		return nil
	}

	var result ArchiveResult
	if err := json.Unmarshal(body, &result); err != nil {
		log.Printf("[dsms] parse error: %v", err)
		return nil
	}

	log.Printf("[dsms] archived: %s → CID %s (%d bytes)", filename, result.CID, result.Size)
	return &result
}

// Verify checks document integrity by CID.
func Verify(cid string) (bool, error) {
	client := &http.Client{Timeout: 15 * time.Second}
	resp, err := client.Get(fmt.Sprintf("%s/api/v1/verify/%s", gatewayURL, cid))
	if err != nil {
		return false, err
	}
	defer resp.Body.Close()
	return resp.StatusCode == 200, nil
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}
