package errors

import (
	"bytes"
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"os"
	"runtime/debug"
	"strings"
	"time"
)

func getEnvConfig(key string) string {
	if val := os.Getenv(key); val != "" {
		return val
	}
	log.Fatalf("Environment variable %s not set", key)
	return ""
}

// Parse handles incoming errors logic for the application by reporting them to an external service
func Parse(err error) error {
	if err == nil {
		return nil
	}

	notifyURL := getEnvConfig("HAVEN_NOTIFY_URL")
	if notifyURL == "" {
		fmt.Printf("Error reporting failed: HAVEN_NOTIFY_URL not set\n")
		return err
	}

	endpoint := fmt.Sprintf("%s/template/notify/error", strings.TrimRight(notifyURL, "/"))
	stackTrace := string(debug.Stack())

	payload := map[string]interface{}{
		"caller":   "Mindforge.Cronjob",
		"message":  err.Error(),
		"critical": true,
		"extra": []map[string]interface{}{
			{
				"name":  "Stack trace",
				"value": stackTrace,
			},
		},
	}

	jsonBody, marshalErr := json.Marshal(payload)
	if marshalErr != nil {
		fmt.Printf("Error marshalling notify payload: %v\n", marshalErr)
		return err
	}

	req, reqErr := http.NewRequest("POST", endpoint, bytes.NewBuffer(jsonBody))
	if reqErr != nil {
		fmt.Printf("Error creating notify request: %v\n", reqErr)
		return err
	}
	req.Header.Set("Content-Type", "application/json")

	client := &http.Client{Timeout: 10 * time.Second}
	resp, respErr := client.Do(req)
	if respErr != nil {
		fmt.Printf("Error sending notify request: %v\n", respErr)
		return err
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated && resp.StatusCode != http.StatusAccepted {
		fmt.Printf("Notify API returned non-OK status: %d\n", resp.StatusCode)
	}

	return err
}
