package greet

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

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

// GreetResponse represents a greeting response
//
//	@Description	GreetResponse represents a greeting response with a message
//	@Property		message string "The greeting message" example("Hello John!")
type GreetResponse struct {
	Message string `json:"message" example:"Hello John!"`
}

// GreetRequest represents a greeting request
//
//	@Description	GreetRequest represents a request with a name to greet
//	@Property		name string "The name to greet" example("John")
type GreetRequest struct {
	Name string `json:"name" example:"John"`
}

// ErrorResponse represents an error response
//
//	@Description	ErrorResponse represents an error response
type ErrorResponse struct {
	Error   string `json:"error" example:"invalid_request"`
	Message string `json:"message" example:"Invalid name parameter"`
}

// GreetResponseV2 represents a v2 greeting response
//
//	@Description	GreetResponseV2 represents a v2 greeting response
type GreetResponseV2 struct {
	Message string `json:"message" example:"Hello my friend John!"`
}

// ValidationError represents a validation error response
//
//	@Description	ValidationError represents a validation error with details
type ValidationError struct {
	Error   string             `json:"error" example:"validation_failed"`
	Message string             `json:"message" example:"Invalid request data"`
	Details []ValidationDetail `json:"details,omitempty"`
}

// ValidationDetail represents a single validation error detail
//
//	@Description	ValidationDetail represents a single field validation error
type ValidationDetail struct {
	Field string `json:"field" example:"name"`
	Error string `json:"error" example:"must be <= 100 characters"`
}

type Greeter interface {
	Greet(ctx context.Context, name string) string
}

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

type apiV1GreetHandler struct {
	greeter Greeter
}

func NewApiV1GreetHandler(greeter Greeter) ApiV1Greet {
	return &apiV1GreetHandler{greeter: greeter}
}

func (h *apiV1GreetHandler) RegisterRoutes(router chi.Router) {
	log.Trace().Msg("Registering greet routes")
	router.Get("/", h.handleGreetQuery)
	router.Get("/{name}", h.handleGreetPath)
	log.Trace().Msg("Greet routes registered")
}

// handleGreetQuery godoc
//
//	@Summary		Get default greeting
//	@Description	Returns a default greeting message
//	@Tags			API/v1/Greeting
//	@Accept			json
//	@Produce		json
//	@Success		200	{object}	GreetResponse	"Successful response"
//	@Security		ApiKeyAuth
//	@Router			/v1/greet [get]
func (h *apiV1GreetHandler) handleGreetQuery(w http.ResponseWriter, r *http.Request) {
	name := r.URL.Query().Get("name")
	h.writeJSONResponse(w, h.greeter.Greet(r.Context(), name))
}

// handleGreetPath godoc
//
//	@Summary		Get personalized greeting
//	@Description	Returns a greeting with the specified name
//	@Tags			API/v1/Greeting
//	@Accept			json
//	@Produce		json
//	@Param			name	path		string			true	"Name to greet"
//	@Success		200		{object}	GreetResponse	"Successful response"
//	@Failure		400		{object}	ErrorResponse	"Invalid name parameter"
//	@Security		ApiKeyAuth
//	@Router			/v1/greet/{name} [get]
func (h *apiV1GreetHandler) handleGreetPath(w http.ResponseWriter, r *http.Request) {
	name := chi.URLParam(r, "name")
	h.writeJSONResponse(w, h.greeter.Greet(r.Context(), name))
}

func (h *apiV1GreetHandler) writeJSONResponse(w http.ResponseWriter, message string) {
	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(map[string]string{"message": message})
}
