package handlers

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

	"veza-backend-api/internal/dto"
	"veza-backend-api/internal/errors"

	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
)

// ValidateRequest represents the request body for the validate endpoint
type ValidateRequest struct {
	Type string          `json:"type" binding:"required"` // e.g., "RegisterRequest", "LoginRequest"
	Data json.RawMessage `json:"data" binding:"required"` // The data to validate
}

// ValidateResponse represents the response from the validate endpoint
type ValidateResponse struct {
	Valid   bool                  `json:"valid"`
	Errors  []dto.ValidationError `json:"errors,omitempty"`
	Message string                `json:"message,omitempty"`
}

// ValidateHandler handles validation requests
type ValidateHandler struct {
	commonHandler *CommonHandler
	logger        *zap.Logger
}

// NewValidateHandler creates a new ValidateHandler
func NewValidateHandler(logger *zap.Logger) *ValidateHandler {
	return &ValidateHandler{
		commonHandler: NewCommonHandler(logger),
		logger:        logger,
	}
}

// Validate validates request bodies against known DTOs
// POST /api/v1/validate
// @Summary      Validate request body
// @Description  Validates request data against known DTO types without executing the actual operation
// @Tags         Validation
// @Accept       json
// @Produce      json
// @Param        request body ValidateRequest true "Validation request with type and data"
// @Success      200  {object}  ValidateResponse "Validation result"
// @Failure      400  {object}  APIResponse "Invalid request format"
// @Router       /validate [post]
func (h *ValidateHandler) Validate(c *gin.Context) {
	var req ValidateRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		RespondWithError(c, http.StatusBadRequest, "Invalid request format", errors.ErrorDetail{
			Message: err.Error(),
		})
		return
	}

	// Map type string to DTO struct and validate
	var validationErrors []dto.ValidationError

	switch req.Type {
	case "RegisterRequest":
		var dtoReq dto.RegisterRequest
		if err := json.Unmarshal(req.Data, &dtoReq); err != nil {
			RespondWithError(c, http.StatusBadRequest, "Invalid data format for RegisterRequest", errors.ErrorDetail{
				Message: err.Error(),
			})
			return
		}
		validationErrors = h.commonHandler.validator.Validate(&dtoReq)

	case "LoginRequest":
		var dtoReq dto.LoginRequest
		if err := json.Unmarshal(req.Data, &dtoReq); err != nil {
			RespondWithError(c, http.StatusBadRequest, "Invalid data format for LoginRequest", errors.ErrorDetail{
				Message: err.Error(),
			})
			return
		}
		validationErrors = h.commonHandler.validator.Validate(&dtoReq)

	default:
		RespondWithError(c, http.StatusBadRequest, "Unknown validation type: "+req.Type)
		return
	}

	// Return validation result
	if len(validationErrors) > 0 {
		RespondSuccess(c, http.StatusOK, ValidateResponse{
			Valid:   false,
			Errors:  validationErrors,
			Message: "Validation failed",
		})
		return
	}

	RespondSuccess(c, http.StatusOK, ValidateResponse{
		Valid:   true,
		Message: "Validation passed",
	})
}
