package greet

import (
	"context"
	"encoding/json"
	"errors"
	"io"
	"net/http"
	"strconv"

	"dance-lessons-coach/pkg/validation"

	"github.com/go-chi/chi/v5"
	"github.com/rs/zerolog/log"
)

type GreeterV2 interface {
	GreetV2(ctx context.Context, name string) string
}

type ApiV2Greet interface {
	RegisterRoutes(router chi.Router)
}

type apiV2GreetHandler struct {
	greeter   GreeterV2
	validator *validation.Validator
}

func NewApiV2GreetHandler(greeter GreeterV2, validator *validation.Validator) ApiV2Greet {
	return &apiV2GreetHandler{greeter: greeter, validator: validator}
}

func (h *apiV2GreetHandler) RegisterRoutes(router chi.Router) {
	log.Trace().Msg("Registering v2 greet routes")
	router.Post("/", h.handleGreetPost)
	log.Trace().Msg("v2 Greet routes registered")
}

type greetRequest struct {
	Name string `json:"name" validate:"max=100"`
}

type greetResponse struct {
	Message string `json:"message"`
}

// handleGreetPost godoc
//
//	@Summary		Get greeting (v2)
//	@Description	Returns a greeting message with validation (v2)
//	@Tags			API/v2/Greeting
//	@Accept			json
//	@Produce		json
//	@Param			request	body		GreetRequest	true	"Greeting request"
//	@Success		200		{object}	GreetResponseV2	"Successful response"
//	@Failure		400		{object}	ValidationError	"Validation error"
//	@Security		ApiKeyAuth
//	@Router			/v2/greet [post]
func (h *apiV2GreetHandler) handleGreetPost(w http.ResponseWriter, r *http.Request) {
	// Read request body
	body, err := io.ReadAll(r.Body)
	if err != nil {
		http.Error(w, `{"error":"failed to read request body"}`, http.StatusBadRequest)
		return
	}

	// Parse JSON
	var req greetRequest
	if err := json.Unmarshal(body, &req); err != nil {
		http.Error(w, `{"error":"invalid JSON format"}`, http.StatusBadRequest)
		return
	}

	// Validate request if validator is available
	if h.validator != nil {
		log.Trace().Str("name", req.Name).Msg("Validating request")
		if err := h.validator.Validate(req); err != nil {
			log.Trace().Err(err).Msg("Validation failed")
			h.handleValidationError(w, err)
			return
		}
		log.Trace().Msg("Validation passed")
	}

	// Call service
	message := h.greeter.GreetV2(r.Context(), req.Name)

	// Write response
	h.writeJSONResponse(w, message)
}

func (h *apiV2GreetHandler) handleValidationError(w http.ResponseWriter, err error) {
	var validationErr *validation.ValidationError
	if errors.As(err, &validationErr) {
		// Create structured validation error response
		response := map[string]interface{}{
			"error":   "validation_failed",
			"message": "Invalid request data",
			"details": make([]map[string]string, 0, len(validationErr.Messages)),
		}

		// Parse validation messages into structured format
		for _, msg := range validationErr.Messages {
			// Simple parsing - in production, use proper parsing
			detail := map[string]string{
				"message": msg,
			}
			response["details"] = append(response["details"].([]map[string]string), detail)
		}

		w.Header().Set("Content-Type", "application/json")
		w.WriteHeader(http.StatusBadRequest)
		json.NewEncoder(w).Encode(response)
	} else {
		// Fallback for other types of errors
		http.Error(w, `{"error":"validation_error","message":`+strconv.Quote(err.Error())+`}`, http.StatusBadRequest)
	}
}

func (h *apiV2GreetHandler) writeJSONResponse(w http.ResponseWriter, message string) {
	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(greetResponse{Message: message})
}
