package handlers

import (
	"net/http"

	"git.linuxforward.com/byop/byop-engine/auth"
	"git.linuxforward.com/byop/byop-engine/dbstore"
	"github.com/gin-gonic/gin"
	"golang.org/x/crypto/bcrypt"
)

// AuthHandler handles authentication-related operations
type AuthHandler struct {
	authService auth.Service
	userStore   *dbstore.UserStore
}

// NewAuthHandler creates a new AuthHandler
func NewAuthHandler(authService auth.Service, userStore *dbstore.UserStore) *AuthHandler {
	return &AuthHandler{
		authService: authService,
		userStore:   userStore,
	}
}

// Login handles user authentication
func (h *AuthHandler) Login(c *gin.Context) {
	var credentials struct {
		Email    string `json:"email"`
		Password string `json:"password"`
	}

	if err := c.ShouldBindJSON(&credentials); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request body"})
		return
	}

	// Validate user credentials
	user, err := h.userStore.GetUserByEmail(credentials.Email)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch user"})
		return
	}

	if user == nil {
		c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid email"})
		return
	}

	// Check password using bcrypt
	if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(credentials.Password)); err != nil {
		c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid password"})
		return
	}

	// Generate token for authentication
	tokenResp, err := h.authService.GenerateToken(c, credentials.Email, string(user.Role))
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to generate token"})
		return
	}

	// Construct the new response format
	response := map[string]interface{}{
		"token":        tokenResp.AccessToken,
		"refreshToken": tokenResp.RefreshToken,
		"user": map[string]interface{}{
			"id":       user.ID,
			"username": user.Username,
			"email":    user.Email,
			"role":     user.Role,
			"preferences": map[string]interface{}{
				"theme":         user.Preferences.Theme,
				"notifications": user.Preferences.Notifications,
			},
		},
	}

	c.JSON(http.StatusOK, response)
}

// RefreshToken handles token refresh
func (h *AuthHandler) RefreshToken(c *gin.Context) {
	var refreshRequest struct {
		RefreshToken string `json:"refresh_token" binding:"required"`
	}

	if err := c.ShouldBindJSON(&refreshRequest); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request body"})
		return
	}

	// Validate refresh token and generate new access token
	resp, err := h.authService.RefreshToken(c, refreshRequest.RefreshToken)
	if err != nil {
		c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid or expired refresh token"})
		return
	}

	c.JSON(http.StatusOK, resp)
}

// Logout handles user logout
func (h *AuthHandler) Logout(c *gin.Context) {
	// TODO: Implement logout logic

	c.Status(http.StatusNoContent)
}
