package handlers

import (
	"encoding/json"
	"fmt"
	"net/http"

	"git.haelnorr.com/h/golib/hws"
)

// NotificationType defines the type of notification
type NotificationType string

const (
	NotificationSuccess NotificationType = "success"
	NotificationWarning NotificationType = "warning"
	NotificationInfo    NotificationType = "info"
)

// Notification represents a toast notification (success, warning, info)
type Notification struct {
	Type    NotificationType `json:"type"`
	Title   string           `json:"title"`
	Message string           `json:"message"`
}

// ErrorModal represents a full-screen error modal (500, 503)
type ErrorModal struct {
	Code    int    `json:"code"`
	Title   string `json:"title"`
	Message string `json:"message"`
	Details string `json:"details"`
}

// setHXTrigger sets the HX-Trigger header with JSON-encoded data
func setHXTrigger(w http.ResponseWriter, event string, data any) {
	payload := map[string]any{
		event: data,
	}

	jsonData, err := json.Marshal(payload)
	if err != nil {
		// Fallback if JSON encoding fails
		w.Header().Set("HX-Trigger", event)
		return
	}

	w.Header().Set("HX-Trigger", string(jsonData))
}

// formatErrorDetails extracts and formats error details from wrapped errors
func formatErrorDetails(err error) string {
	if err == nil {
		return ""
	}

	// Use %+v format to get stack trace from github.com/pkg/errors
	return fmt.Sprintf("%+v", err)
}

// notifyToast sends a toast notification via HX-Trigger header
func notifyToast(
	w http.ResponseWriter,
	notifType NotificationType,
	title string,
	message string,
) {
	notification := Notification{
		Type:    notifType,
		Title:   title,
		Message: message,
	}

	setHXTrigger(w, "showNotification", notification)
}

// notifyErrorModal sends a full-screen error modal via HX-Trigger header
func notifyErrorModal(
	s *hws.Server,
	w http.ResponseWriter,
	statusCode int,
	title string,
	message string,
	err error,
) {
	modal := ErrorModal{
		Code:    statusCode,
		Title:   title,
		Message: message,
		Details: formatErrorDetails(err),
	}

	// Log the error
	s.LogError(hws.HWSError{
		StatusCode: statusCode,
		Message:    message,
		Error:      err,
		Level:      hws.ErrorERROR,
	})

	// Set response status
	w.WriteHeader(statusCode)

	// Send notification via HX-Trigger
	setHXTrigger(w, "showErrorModal", modal)
}

// notifySuccess sends a success toast notification
func notifySuccess(w http.ResponseWriter, title string, message string) {
	notifyToast(w, NotificationSuccess, title, message)
}

// notifyWarning sends a warning toast notification
func notifyWarning(w http.ResponseWriter, title string, message string) {
	notifyToast(w, NotificationWarning, title, message)
}

// notifyInfo sends an info toast notification
func notifyInfo(w http.ResponseWriter, title string, message string) {
	notifyToast(w, NotificationInfo, title, message)
}

// notifyInternalServiceError sends a 500 error modal
func notifyInternalServiceError(
	s *hws.Server,
	w http.ResponseWriter,
	message string,
	err error,
) {
	notifyErrorModal(s, w, 500, "Internal Server Error", message, err)
}

// notifyServiceUnavailable sends a 503 error modal
func notifyServiceUnavailable(
	s *hws.Server,
	w http.ResponseWriter,
	message string,
	err error,
) {
	notifyErrorModal(s, w, 503, "Service Unavailable", message, err)
}
