package handlers

import (
	"fmt"
	"net/http"
	"os"

	"veza-backend-api/internal/services"

	"github.com/gin-gonic/gin"
)

// OAuthServiceInterface defines the methods needed for OAuth handlers
type OAuthServiceInterface interface {
	GetAuthURL(provider string) (string, error)
	HandleCallback(provider, code, state string) (*services.OAuthUser, string, error)
}

// OAuthHandlers handles OAuth authentication flows
type OAuthHandlers struct {
	oauthService OAuthServiceInterface
	logger       interface{}
}

// OAuthHandlersInstance is the global instance
var OAuthHandlersInstance *OAuthHandlers

// InitOAuthHandlers initializes the OAuth handlers
func InitOAuthHandlers(oauthService *services.OAuthService) {
	OAuthHandlersInstance = &OAuthHandlers{
		oauthService: oauthService,
	}
}

// NewOAuthHandler creates a new OAuth handler instance
// BE-API-042: Implement OAuth callback endpoint
func NewOAuthHandler(oauthService *services.OAuthService, logger interface{}) *OAuthHandlers {
	return &OAuthHandlers{
		oauthService: oauthService,
		logger:       logger,
	}
}

// NewOAuthHandlerWithInterface creates a new OAuth handler instance with an interface (for testing)
func NewOAuthHandlerWithInterface(oauthService OAuthServiceInterface, logger interface{}) *OAuthHandlers {
	return &OAuthHandlers{
		oauthService: oauthService,
		logger:       logger,
	}
}

// GetOAuthProviders returns available OAuth providers
func (oh *OAuthHandlers) GetOAuthProviders(c *gin.Context) {
	providers := []map[string]interface{}{
		{
			"name":         "Google",
			"id":           "google",
			"authorizeUrl": "/api/v1/auth/oauth/google",
			"icon":         "google",
		},
		{
			"name":         "GitHub",
			"id":           "github",
			"authorizeUrl": "/api/v1/auth/oauth/github",
			"icon":         "github",
		},
		{
			"name":         "Discord",
			"id":           "discord",
			"authorizeUrl": "/api/v1/auth/oauth/discord",
			"icon":         "discord",
		},
	}

	RespondSuccess(c, http.StatusOK, gin.H{
		"providers": providers,
	})
}

// InitiateOAuth initiates OAuth flow
func (oh *OAuthHandlers) InitiateOAuth(c *gin.Context) {
	provider := c.Param("provider")

	// Get authorization URL
	authURL, err := oh.oauthService.GetAuthURL(provider)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// Redirect to OAuth provider
	c.Redirect(http.StatusTemporaryRedirect, authURL)
}

// OAuthCallback handles OAuth callback
func (oh *OAuthHandlers) OAuthCallback(c *gin.Context) {
	provider := c.Param("provider")
	code := c.Query("code")
	state := c.Query("state")

	if code == "" || state == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "missing code or state"})
		return
	}

	// Handle callback
	user, token, err := oh.oauthService.HandleCallback(provider, code, state)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// Redirect to frontend with token
	frontendURL := os.Getenv("FRONTEND_URL")
	if frontendURL == "" {
		frontendURL = "http://localhost:5173" // Fallback for development
	}
	redirectURL := fmt.Sprintf("%s/auth/callback?token=%s&user_id=%s", frontendURL, token, user.ID.String())

	c.Redirect(http.StatusTemporaryRedirect, redirectURL)
}
