package http

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

	"github.com/example/storage-appliance/internal/auth"
)

// LoginHandler handles user login
func (a *App) LoginHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method == "GET" {
		// Show login page
		data := map[string]interface{}{
			"Title": "Login",
		}
		if err := templates.ExecuteTemplate(w, "login", data); err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
		}
		return
	}

	// Handle POST login
	var req struct {
		Username string `json:"username"`
		Password string `json:"password"`
	}

	if r.Header.Get("Content-Type") == "application/json" {
		if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
			http.Error(w, "invalid request", http.StatusBadRequest)
			return
		}
	} else {
		req.Username = r.FormValue("username")
		req.Password = r.FormValue("password")
	}

	// Authenticate user
	userStore := auth.NewUserStore(a.DB)
	user, err := userStore.Authenticate(r.Context(), req.Username, req.Password)
	if err != nil {
		if r.Header.Get("HX-Request") == "true" {
			w.Header().Set("Content-Type", "text/html")
			w.WriteHeader(http.StatusUnauthorized)
			w.Write([]byte(`<div class="text-red-600">Invalid username or password</div>`))
		} else {
			http.Error(w, "invalid credentials", http.StatusUnauthorized)
		}
		return
	}

	// Create session
	sessionStore := auth.NewSessionStore(a.DB)
	session, err := sessionStore.CreateSession(r.Context(), user.ID)
	if err != nil {
		http.Error(w, "failed to create session", http.StatusInternalServerError)
		return
	}

	// Set session cookie
	http.SetCookie(w, &http.Cookie{
		Name:     auth.SessionCookieName,
		Value:    session.Token,
		Path:     "/",
		HttpOnly: true,
		Secure:   false, // Set to true in production with HTTPS
		SameSite: http.SameSiteStrictMode,
		MaxAge:   int(auth.SessionDuration.Seconds()),
	})

	// Set CSRF token cookie
	csrfToken := generateCSRFToken()
	http.SetCookie(w, &http.Cookie{
		Name:     "csrf_token",
		Value:    csrfToken,
		Path:     "/",
		HttpOnly: false, // Needed for HTMX to read it
		Secure:   false,
		SameSite: http.SameSiteStrictMode,
		MaxAge:   int(auth.SessionDuration.Seconds()),
	})

	// Redirect or return success
	if r.Header.Get("HX-Request") == "true" {
		w.Header().Set("HX-Redirect", "/dashboard")
		w.WriteHeader(http.StatusOK)
	} else {
		http.Redirect(w, r, "/dashboard", http.StatusFound)
	}
}

// LogoutHandler handles user logout
func (a *App) LogoutHandler(w http.ResponseWriter, r *http.Request) {
	// Get session token from cookie
	cookie, err := r.Cookie(auth.SessionCookieName)
	if err == nil {
		// Delete session
		sessionStore := auth.NewSessionStore(a.DB)
		sessionStore.DeleteSession(r.Context(), cookie.Value)
	}

	// Clear cookies
	http.SetCookie(w, &http.Cookie{
		Name:     auth.SessionCookieName,
		Value:    "",
		Path:     "/",
		HttpOnly: true,
		MaxAge:   -1,
	})
	http.SetCookie(w, &http.Cookie{
		Name:     "csrf_token",
		Value:    "",
		Path:     "/",
		HttpOnly: false,
		MaxAge:   -1,
	})

	if r.Header.Get("HX-Request") == "true" {
		w.Header().Set("HX-Redirect", "/login")
		w.WriteHeader(http.StatusOK)
	} else {
		http.Redirect(w, r, "/login", http.StatusFound)
	}
}
