package handlers

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

	"github.com/google/uuid"

	"mgit.msbls.de/m/KanzlAI-mGMT/internal/auth"
	"mgit.msbls.de/m/KanzlAI-mGMT/internal/services"
)

// DetermineHandlers holds handlers for deadline determination endpoints
type DetermineHandlers struct {
	determine *services.DetermineService
	deadlines *services.DeadlineService
}

// NewDetermineHandlers creates determine handlers
func NewDetermineHandlers(determine *services.DetermineService, deadlines *services.DeadlineService) *DetermineHandlers {
	return &DetermineHandlers{determine: determine, deadlines: deadlines}
}

// GetTimeline handles GET /api/proceeding-types/{code}/timeline
// Returns the full event tree for a proceeding type (no date calculations)
func (h *DetermineHandlers) GetTimeline(w http.ResponseWriter, r *http.Request) {
	code := r.PathValue("code")
	if code == "" {
		writeError(w, http.StatusBadRequest, "proceeding type code required")
		return
	}

	timeline, pt, err := h.determine.GetTimeline(code)
	if err != nil {
		writeError(w, http.StatusNotFound, "proceeding type not found")
		return
	}

	writeJSON(w, http.StatusOK, map[string]any{
		"proceeding_type": pt,
		"timeline":        timeline,
	})
}

// Determine handles POST /api/deadlines/determine
// Calculates the full timeline with cascading dates and conditional logic
func (h *DetermineHandlers) Determine(w http.ResponseWriter, r *http.Request) {
	var req services.DetermineRequest
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		writeError(w, http.StatusBadRequest, "invalid request body")
		return
	}

	if req.ProceedingType == "" || req.TriggerEventDate == "" {
		writeError(w, http.StatusBadRequest, "proceeding_type and trigger_event_date are required")
		return
	}

	resp, err := h.determine.Determine(req)
	if err != nil {
		writeError(w, http.StatusBadRequest, err.Error())
		return
	}

	writeJSON(w, http.StatusOK, resp)
}

// BatchCreate handles POST /api/cases/{caseID}/deadlines/batch
// Creates multiple deadlines on a case from determined timeline
func (h *DetermineHandlers) BatchCreate(w http.ResponseWriter, r *http.Request) {
	tenantID, ok := auth.TenantFromContext(r.Context())
	if !ok {
		writeError(w, http.StatusForbidden, "missing tenant")
		return
	}

	caseID, err := parsePathUUID(r, "caseID")
	if err != nil {
		writeError(w, http.StatusBadRequest, "invalid case ID")
		return
	}

	var req struct {
		Deadlines []struct {
			Title           string     `json:"title"`
			DueDate         string     `json:"due_date"`
			OriginalDueDate *string    `json:"original_due_date,omitempty"`
			RuleID          *uuid.UUID `json:"rule_id,omitempty"`
			RuleCode        *string    `json:"rule_code,omitempty"`
			Notes           *string    `json:"notes,omitempty"`
		} `json:"deadlines"`
	}
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		writeError(w, http.StatusBadRequest, "invalid request body")
		return
	}

	if len(req.Deadlines) == 0 {
		writeError(w, http.StatusBadRequest, "at least one deadline is required")
		return
	}

	var created int
	for _, d := range req.Deadlines {
		if d.Title == "" || d.DueDate == "" {
			continue
		}
		input := services.CreateDeadlineInput{
			CaseID:  caseID,
			Title:   d.Title,
			DueDate: d.DueDate,
			Source:   "determined",
			RuleID:  d.RuleID,
			Notes:   d.Notes,
		}
		_, err := h.deadlines.Create(r.Context(), tenantID, input)
		if err != nil {
			internalError(w, "failed to create deadline", err)
			return
		}
		created++
	}

	writeJSON(w, http.StatusCreated, map[string]any{
		"created": created,
	})
}
