package api

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

	"dance-lessons-coach/pkg/user"

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

// UserHandler handles user management requests
type UserHandler struct {
	userRepo        user.UserRepository
	passwordService user.PasswordService
}

// NewUserHandler creates a new user handler
func NewUserHandler(userRepo user.UserRepository, passwordService user.PasswordService) *UserHandler {
	return &UserHandler{
		userRepo:        userRepo,
		passwordService: passwordService,
	}
}

// RegisterRoutes registers user routes
func (h *UserHandler) RegisterRoutes(router chi.Router) {
	router.Post("/register", h.handleRegister)
}

// RegisterRequest represents a user registration request

// handleRegister handles user registration requests
func (h *UserHandler) handleRegister(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()

	var req RegisterRequest
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		http.Error(w, `{"error":"invalid_request","message":"Invalid JSON request body"}`, http.StatusBadRequest)
		return
	}

	// Check if user already exists
	exists, err := h.userRepo.UserExists(ctx, req.Username)
	if err != nil {
		log.Error().Ctx(ctx).Err(err).Msg("Failed to check if user exists")
		http.Error(w, `{"error":"server_error","message":"Failed to process registration"}`, http.StatusInternalServerError)
		return
	}
	if exists {
		http.Error(w, `{"error":"user_exists","message":"Username already taken"}`, http.StatusConflict)
		return
	}

	// Hash password
	hashedPassword, err := h.passwordService.HashPassword(ctx, req.Password)
	if err != nil {
		log.Error().Ctx(ctx).Err(err).Msg("Failed to hash password")
		http.Error(w, `{"error":"server_error","message":"Failed to process registration"}`, http.StatusInternalServerError)
		return
	}

	// Create user
	newUser := &user.User{
		Username:     req.Username,
		PasswordHash: hashedPassword,
		IsAdmin:      false,
	}

	if err := h.userRepo.CreateUser(ctx, newUser); err != nil {
		log.Error().Ctx(ctx).Err(err).Msg("Failed to create user")
		http.Error(w, `{"error":"server_error","message":"Failed to create user"}`, http.StatusInternalServerError)
		return
	}

	// Return success
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusCreated)
	json.NewEncoder(w).Encode(map[string]string{"message": "User registered successfully"})
}
