package customer

import (
	"net/http"
	"strings"
	"tm/pkg/response"

	"github.com/labstack/echo/v4"
)

// AuthMiddleware validates JWT access tokens and extracts customer information
func (h *Handler) AuthMiddleware() echo.MiddlewareFunc {
	return func(next echo.HandlerFunc) echo.HandlerFunc {
		return func(c echo.Context) error {
			// Extract token from Authorization header
			authHeader := c.Request().Header.Get("Authorization")
			if authHeader == "" {
				return response.Unauthorized(c, "Authorization header required")
			}

			// Check if it's a Bearer token
			if !strings.HasPrefix(authHeader, "Bearer ") {
				return response.Unauthorized(c, "Invalid authorization format. Use 'Bearer <token>'")
			}

			// Extract the token
			tokenString := strings.TrimPrefix(authHeader, "Bearer ")

			// Validate the access token using authorization service
			validationResult, err := h.authService.ValidateAccessToken(tokenString)
			if err != nil {
				h.logger.Error("Token validation error", map[string]interface{}{
					"error": err.Error(),
				})
				return response.Unauthorized(c, "Invalid token")
			}

			if !validationResult.Valid {
				if validationResult.Expired {
					return response.Unauthorized(c, "Token expired")
				}
				return response.Unauthorized(c, validationResult.Error)
			}

			// Extract customer information from token
			customerID := validationResult.Claims.UserID

			// Store customer information in context for handlers to use
			c.Set("customer_id", customerID)
			c.Set("customer_email", validationResult.Claims.Email)
			c.Set("customer_role", validationResult.Claims.Role)
			c.Set("company_id", validationResult.Claims.CompanyID)
			c.Set("access_token", tokenString)

			// Continue to next handler
			return next(c)
		}
	}
}

// GetCustomerIDFromContext extracts customer ID from Echo context
func GetCustomerIDFromContext(c echo.Context) (string, error) {
	customerID, ok := c.Get("customer_id").(string)
	if !ok {
		return "", echo.NewHTTPError(http.StatusUnauthorized, "Customer ID not found in context")
	}
	return customerID, nil
}

// GetAccessTokenFromContext extracts access token from Echo context
func GetAccessTokenFromContext(c echo.Context) (string, error) {
	accessToken, ok := c.Get("access_token").(string)
	if !ok {
		return "", echo.NewHTTPError(http.StatusUnauthorized, "Access token not found in context")
	}
	return accessToken, nil
}
