package admin

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

	"epigas.gitea.cloud/RiskRancher/core/pkg/auth"
)

// PasswordResetRequest is the expected JSON payload
type PasswordResetRequest struct {
	NewPassword string `json:"new_password"`
}

// HandleAdminResetPassword allows a Sheriff to forcefully overwrite a user's password.
func (h *Handler) HandleAdminResetPassword(w http.ResponseWriter, r *http.Request) {
	idStr := r.PathValue("id")
	userID, err := strconv.Atoi(idStr)
	if err != nil {
		http.Error(w, "Invalid user ID in URL", http.StatusBadRequest)
		return
	}

	var req PasswordResetRequest
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		http.Error(w, "Invalid JSON payload", http.StatusBadRequest)
		return
	}

	if req.NewPassword == "" {
		http.Error(w, "New password cannot be empty", http.StatusBadRequest)
		return
	}

	hashedPassword, err := auth.HashPassword(req.NewPassword)
	if err != nil {
		http.Error(w, "Internal server error during hashing", http.StatusInternalServerError)
		return
	}

	err = h.Store.UpdateUserPassword(r.Context(), userID, hashedPassword)
	if err != nil {
		http.Error(w, "Failed to update user password", http.StatusInternalServerError)
		return
	}

	w.WriteHeader(http.StatusOK)
	json.NewEncoder(w).Encode(map[string]string{
		"message": "Password reset successfully",
	})
}

type RoleUpdateRequest struct {
	GlobalRole string `json:"global_role"`
}

// HandleUpdateUserRole allows a Sheriff to promote or demote a user.
func (h *Handler) HandleUpdateUserRole(w http.ResponseWriter, r *http.Request) {
	idStr := r.PathValue("id")
	userID, err := strconv.Atoi(idStr)
	if err != nil {
		http.Error(w, "Invalid user ID in URL", http.StatusBadRequest)
		return
	}
	var req RoleUpdateRequest
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		http.Error(w, "Invalid JSON payload", http.StatusBadRequest)
		return
	}

	validRoles := map[string]bool{
		"Sheriff": true, "Wrangler": true, "RangeHand": true, "CircuitRider": true, "Magistrate": true,
	}
	if !validRoles[req.GlobalRole] {
		http.Error(w, "Invalid role provided", http.StatusBadRequest)
		return
	}

	err = h.Store.UpdateUserRole(r.Context(), userID, req.GlobalRole)
	if err != nil {
		http.Error(w, "Failed to update user role", http.StatusInternalServerError)
		return
	}

	w.WriteHeader(http.StatusOK)
	json.NewEncoder(w).Encode(map[string]string{
		"message": "User role updated successfully to " + req.GlobalRole,
	})
}

// HandleDeactivateUser allows a Sheriff to safely offboard a user.
func (h *Handler) HandleDeactivateUser(w http.ResponseWriter, r *http.Request) {
	idStr := r.PathValue("id")
	userID, err := strconv.Atoi(idStr)
	if err != nil {
		http.Error(w, "Invalid user ID in URL", http.StatusBadRequest)
		return
	}

	err = h.Store.DeactivateUserAndReassign(r.Context(), userID)
	if err != nil {
		http.Error(w, "Failed to deactivate user", http.StatusInternalServerError)
		return
	}

	w.WriteHeader(http.StatusOK)
	json.NewEncoder(w).Encode(map[string]string{
		"message": "User successfully deactivated and tickets reassigned.",
	})
}

// CreateUserRequest is the payload the Sheriff sends to invite a new user
type CreateUserRequest struct {
	Email      string `json:"email"`
	FullName   string `json:"full_name"`
	Password   string `json:"password"`
	GlobalRole string `json:"global_role"`
}

// HandleCreateUser allows a Sheriff to manually provision a new user account.
func (h *Handler) HandleCreateUser(w http.ResponseWriter, r *http.Request) {
	var req CreateUserRequest
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		http.Error(w, "Invalid JSON payload", http.StatusBadRequest)
		return
	}

	if req.Email == "" || req.FullName == "" || req.Password == "" || req.GlobalRole == "" {
		http.Error(w, "Missing required fields", http.StatusBadRequest)
		return
	}

	validRoles := map[string]bool{
		"Sheriff": true, "Wrangler": true, "RangeHand": true, "CircuitRider": true, "Magistrate": true,
	}
	if !validRoles[req.GlobalRole] {
		http.Error(w, "Invalid role provided", http.StatusBadRequest)
		return
	}

	hashedPassword, err := auth.HashPassword(req.Password)
	if err != nil {
		http.Error(w, "Internal server error during hashing", http.StatusInternalServerError)
		return
	}

	user, err := h.Store.CreateUser(r.Context(), req.Email, req.FullName, hashedPassword, req.GlobalRole)
	if err != nil {
		if strings.Contains(err.Error(), "UNIQUE constraint failed") {
			http.Error(w, "Email already exists in the system", http.StatusConflict)
			return
		}
		http.Error(w, "Failed to provision user", http.StatusInternalServerError)
		return
	}

	w.WriteHeader(http.StatusCreated)
	json.NewEncoder(w).Encode(map[string]interface{}{
		"message":     "User provisioned successfully. Share the temporary password securely.",
		"id":          user.ID,
		"email":       user.Email,
		"full_name":   user.FullName,
		"global_role": user.GlobalRole,
	})
}

// HandleGetUsers returns a list of all users in the system for the Sheriff to manage.
func (h *Handler) HandleGetUsers(w http.ResponseWriter, r *http.Request) {
	users, err := h.Store.GetAllUsers(r.Context())
	if err != nil {
		http.Error(w, "Failed to fetch user roster", http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusOK)
	json.NewEncoder(w).Encode(users)
}

// HandleGetWranglers returns a clean list of IT users for assignment dropdowns
func (h *Handler) HandleGetWranglers(w http.ResponseWriter, r *http.Request) {
	wranglers, err := h.Store.GetWranglers(r.Context())
	if err != nil {
		http.Error(w, "Failed to fetch wranglers", http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(wranglers)
}
