package handlers

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

	"github.com/google/uuid"

	"mgit.msbls.de/m/paliad/internal/services"
)

// POST /api/tools/event-trigger — Phase 3 Slice 6 (t-paliad-187, design
// §5). Discovers and computes deadline rules triggered by an event-type
// and/or a deadline-concept. Caller passes UUID identifiers (not the
// legacy /api/tools/event-deadlines bigint trigger_event_id surface);
// service handles the bridge to Pipeline-C rules internally.
//
// Body:
//
//	{
//	  "eventTypeId": "uuid",          // optional — fires Pipeline-C rules via event_types.trigger_event_id
//	  "conceptId":   "uuid",          // optional — fires Pipeline-A rules linked by concept_id FK
//	  "triggerDate": "2026-01-15",    // required, YYYY-MM-DD
//	  "flags":       ["with_ccr"],    // optional, gates rules via evalConditionExpr
//	  "courtId":     "upc-ld-mn",     // optional, picks (country, regime) for non-working-day arithmetic
//	  "perspective": "claimant"        // optional, drops opposing-side rules
//	}
//
// At least one of eventTypeId / conceptId must be set. When both are
// set, the rule set is the UNION deduped by rule.id.
//
// Response: same shape as POST /api/tools/fristenrechner (UIResponse) —
// the frontend can render with the existing timeline renderer.
//
// Returns 503 when the DB pool is unavailable (server bootstrap before
// services attached); the page itself still renders since it's static
// HTML so a downstream error pop-up is the worst the user sees.
func handleEventTriggerCalculate(w http.ResponseWriter, r *http.Request) {
	if dbSvc == nil || dbSvc.eventTrigger == nil {
		writeJSON(w, http.StatusServiceUnavailable, map[string]string{
			"error": "Event-Trigger ist vorübergehend nicht verfügbar (keine Datenbank).",
		})
		return
	}
	var req struct {
		EventTypeID string   `json:"eventTypeId,omitempty"`
		ConceptID   string   `json:"conceptId,omitempty"`
		TriggerDate string   `json:"triggerDate"`
		Flags       []string `json:"flags,omitempty"`
		CourtID     string   `json:"courtId,omitempty"`
		Perspective string   `json:"perspective,omitempty"`
	}
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Ungültige Anfrage"})
		return
	}
	if req.TriggerDate == "" {
		writeJSON(w, http.StatusBadRequest, map[string]string{"error": "triggerDate ist erforderlich"})
		return
	}
	if req.EventTypeID == "" && req.ConceptID == "" {
		writeJSON(w, http.StatusBadRequest, map[string]string{
			"error": "eventTypeId oder conceptId ist erforderlich",
		})
		return
	}

	input := services.EventTriggerInput{
		TriggerDate: req.TriggerDate,
		Flags:       req.Flags,
		CourtID:     req.CourtID,
		Perspective: req.Perspective,
	}
	if req.EventTypeID != "" {
		id, err := uuid.Parse(req.EventTypeID)
		if err != nil {
			writeJSON(w, http.StatusBadRequest, map[string]string{
				"error": "eventTypeId ist keine gültige UUID",
			})
			return
		}
		input.EventTypeID = &id
	}
	if req.ConceptID != "" {
		id, err := uuid.Parse(req.ConceptID)
		if err != nil {
			writeJSON(w, http.StatusBadRequest, map[string]string{
				"error": "conceptId ist keine gültige UUID",
			})
			return
		}
		input.ConceptID = &id
	}

	resp, err := dbSvc.eventTrigger.Trigger(r.Context(), input)
	if err != nil {
		if errors.Is(err, services.ErrInvalidInput) {
			writeJSON(w, http.StatusBadRequest, map[string]string{"error": err.Error()})
			return
		}
		writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
		return
	}
	writeJSON(w, http.StatusOK, resp)
}
