package handlers

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

	"mgit.msbls.de/m/paliad/internal/auth"
	"mgit.msbls.de/m/paliad/internal/services"
)

// GET /onboarding — first-login profile capture. The page is authenticated
// (user must have logged in), but it is NOT behind the onboarding gate — it
// is the one place a user without a paliad.users row is allowed to land.
func handleOnboardingPage(w http.ResponseWriter, r *http.Request) {
	// If the user is already onboarded, send them to the dashboard so the
	// page doesn't become a dead end after a refresh.
	if dbSvc != nil {
		if uid, ok := auth.UserIDFromContext(r.Context()); ok {
			if u, err := dbSvc.users.GetByID(r.Context(), uid); err == nil && u != nil {
				http.Redirect(w, r, "/dashboard", http.StatusFound)
				return
			}
		}
	}
	http.ServeFile(w, r, "dist/onboarding.html")
}

// POST /api/onboarding — creates the caller's paliad.users row. The id and
// email are pulled from the verified JWT claims so a user can't onboard as
// someone else.
func handleCreateOnboarding(w http.ResponseWriter, r *http.Request) {
	if !requireDB(w) {
		return
	}
	uid, ok := requireUser(w, r)
	if !ok {
		return
	}
	claims, ok := auth.ClaimsFromContext(r.Context())
	if !ok || claims.Email == "" {
		writeJSON(w, http.StatusUnauthorized, map[string]string{
			"error": "missing email claim — please sign out and back in",
		})
		return
	}

	var input services.CreateUserInput
	if err := json.NewDecoder(r.Body).Decode(&input); err != nil {
		writeJSON(w, http.StatusBadRequest, map[string]string{"error": "invalid JSON"})
		return
	}

	u, err := dbSvc.users.Create(r.Context(), uid, claims.Email, input)
	if err != nil {
		switch {
		case errors.Is(err, services.ErrUserAlreadyOnboarded):
			writeJSON(w, http.StatusConflict, map[string]string{
				"error": "onboarding already completed",
			})
		default:
			// Validation errors from the service (bad office, missing
			// job_title, empty display_name) come through as generic errors;
			// surface them so the form can show a precise message.
			writeJSON(w, http.StatusBadRequest, map[string]string{"error": err.Error()})
		}
		return
	}
	writeJSON(w, http.StatusCreated, u)
}
