package providers

import (
	"bytes"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"strings"
)

// DummyCAProvider ist ein Dummy-Provider für Tests
type DummyCAProvider struct {
	baseURL string
}

func NewDummyCAProvider() *DummyCAProvider {
	return &DummyCAProvider{
		baseURL: "http://localhost:8088",
	}
}

func (p *DummyCAProvider) GetName() string {
	return "dummy-ca"
}

func (p *DummyCAProvider) GetDisplayName() string {
	return "Dummy CA"
}

func (p *DummyCAProvider) GetDescription() string {
	return "Externe Dummy CA für Tests und Entwicklung (http://localhost:8088)"
}

func (p *DummyCAProvider) ValidateConfig(settings map[string]interface{}) error {
	// Dummy-Provider benötigt keine Konfiguration
	return nil
}

func (p *DummyCAProvider) TestConnection(settings map[string]interface{}) error {
	// Teste Verbindung zur externen CA über Health Check
	url := fmt.Sprintf("%s/health", p.baseURL)
	resp, err := http.Get(url)
	if err != nil {
		return fmt.Errorf("CA-Server nicht erreichbar: %v", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return fmt.Errorf("CA-Server antwortet mit Status %d", resp.StatusCode)
	}

	// Prüfe Response Body
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return fmt.Errorf("fehler beim Lesen der Health-Check-Response: %v", err)
	}

	var healthResponse struct {
		Status string `json:"status"`
	}
	if err := json.Unmarshal(body, &healthResponse); err != nil {
		return fmt.Errorf("ungültige Health-Check-Response: %v", err)
	}

	if healthResponse.Status != "ok" {
		return fmt.Errorf("CA-Server meldet Status: %s", healthResponse.Status)
	}

	return nil
}

// GetRequiredSettings gibt die erforderlichen Einstellungen zurück
func (p *DummyCAProvider) GetRequiredSettings() []SettingField {
	return []SettingField{}
}

// SignCSR signiert einen CSR über die externe Dummy CA API
func (p *DummyCAProvider) SignCSR(csrPEM string, settings map[string]interface{}) (*SignCSRResult, error) {
	// Entferne mögliche Whitespace am Anfang/Ende
	csrPEM = strings.TrimSpace(csrPEM)

	// Base64-kodiere den CSR
	csrB64 := base64.StdEncoding.EncodeToString([]byte(csrPEM))

	// Erstelle Request Body
	requestBody := map[string]interface{}{
		"csr":           csrB64,
		"action":        "sign",
		"validity_days": 365,
	}

	// Konvertiere zu JSON
	jsonData, err := json.Marshal(requestBody)
	if err != nil {
		return nil, fmt.Errorf("fehler beim Erstellen des Request-Body: %v", err)
	}

	// Erstelle HTTP Request
	url := fmt.Sprintf("%s/csr", p.baseURL)
	req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
	if err != nil {
		return nil, fmt.Errorf("fehler beim Erstellen des HTTP-Requests: %v", err)
	}

	req.Header.Set("Content-Type", "application/json")

	// Führe Request aus
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return nil, fmt.Errorf("fehler beim Senden des Requests an die CA: %v", err)
	}
	defer resp.Body.Close()

	// Lese Response Body
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("fehler beim Lesen der Response: %v", err)
	}

	// Prüfe Status Code
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("CA-API Fehler (Status %d): %s", resp.StatusCode, string(body))
	}

	// Parse Response
	var apiResponse struct {
		ID          string `json:"id"`
		Status      string `json:"status"`
		Message     string `json:"message"`
		Certificate string `json:"certificate"`
		Error       string `json:"error"`
	}

	if err := json.Unmarshal(body, &apiResponse); err != nil {
		return nil, fmt.Errorf("fehler beim Parsen der Response: %v", err)
	}

	// Prüfe auf Fehler in der Response
	if apiResponse.Error != "" {
		return nil, fmt.Errorf("CA-API Fehler: %s", apiResponse.Error)
	}

	// Prüfe Status
	if apiResponse.Status != "success" {
		return nil, fmt.Errorf("CSR-Signierung fehlgeschlagen: %s", apiResponse.Message)
	}

	// Rückgabe des Ergebnisses
	return &SignCSRResult{
		CertificatePEM: apiResponse.Certificate,
		OrderID:        apiResponse.ID,
		Status:         "issued",
		Message:        apiResponse.Message,
	}, nil
}

// GetCertificate ruft ein Zertifikat über die externe Dummy CA API ab
func (p *DummyCAProvider) GetCertificate(certificateID string, settings map[string]interface{}) (string, error) {
	if certificateID == "" {
		return "", fmt.Errorf("zertifikat-ID ist erforderlich")
	}

	// Erstelle HTTP Request
	url := fmt.Sprintf("%s/certificate/%s", p.baseURL, certificateID)
	resp, err := http.Get(url)
	if err != nil {
		return "", fmt.Errorf("fehler beim Abrufen des Zertifikats: %v", err)
	}
	defer resp.Body.Close()

	// Lese Response Body
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return "", fmt.Errorf("fehler beim Lesen der Response: %v", err)
	}

	// Prüfe Status Code
	if resp.StatusCode == http.StatusNotFound {
		return "", fmt.Errorf("Zertifikat mit ID %s nicht gefunden", certificateID)
	}

	if resp.StatusCode != http.StatusOK {
		return "", fmt.Errorf("CA-API Fehler (Status %d): %s", resp.StatusCode, string(body))
	}

	// Parse Response
	var apiResponse struct {
		ID          string `json:"id"`
		Certificate string `json:"certificate"`
		CreatedAt   string `json:"created_at"`
	}

	if err := json.Unmarshal(body, &apiResponse); err != nil {
		return "", fmt.Errorf("fehler beim Parsen der Response: %v", err)
	}

	if apiResponse.Certificate == "" {
		return "", fmt.Errorf("zertifikat in Response nicht gefunden")
	}

	return apiResponse.Certificate, nil
}
