package auth

import (
	"net/http"
	"strings"
	"time"

	"github.com/gin-gonic/gin"

	"github.com/tidbcloud/AgentTeam/internal/api"
	"github.com/tidbcloud/AgentTeam/internal/api/dto"
	"github.com/tidbcloud/AgentTeam/internal/service/authflow"
)

// FeishuHandler owns Feishu organization auth routes.
type FeishuHandler struct {
	store         Store
	authFlow      AuthFlow
	organizations OrganizationProvider
	sessionTTL    time.Duration
}

// LoginURL handles POST /api/v1/auth/feishu/login-url.
// Builds and returns a Feishu OAuth login URL for the organization.
func (handler *FeishuHandler) LoginURL(ctx *gin.Context) {
	orgs, ok := handler.organizations, handler.organizations != nil
	if !ok {
		api.Error(ctx, http.StatusNotFound, "Organization provider not installed")
		return
	}

	var request dto.FeishuLoginURLRequest
	if err := ctx.ShouldBindJSON(&request); err != nil {
		api.Error(ctx, http.StatusBadRequest, "Invalid request body")
		return
	}

	authorizeURL, err := orgs.BuildFeishuLoginURL(
		ctx.Request.Context(),
		strings.TrimSpace(request.OrganizationSlug),
		strings.TrimSpace(request.RedirectURI),
	)
	if err != nil {
		api.StoreError(ctx, err)
		return
	}

	ctx.JSON(http.StatusOK, gin.H{"authorizeUrl": authorizeURL})
}

// Login handles POST /api/v1/auth/feishu/login.
// Authenticates a user via Feishu OAuth code and returns session tokens.
func (handler *FeishuHandler) Login(ctx *gin.Context) {
	orgs, ok := handler.organizations, handler.organizations != nil
	if !ok {
		api.Error(ctx, http.StatusNotFound, "Organization provider not installed")
		return
	}

	var request dto.FeishuLoginRequest
	if err := ctx.ShouldBindJSON(&request); err != nil {
		api.Error(ctx, http.StatusBadRequest, "Invalid request body")
		return
	}

	user, err := orgs.AuthenticateFeishuLogin(
		ctx.Request.Context(),
		strings.TrimSpace(request.Code),
		strings.TrimSpace(request.State),
		strings.TrimSpace(request.RedirectURI),
	)
	if err != nil {
		api.StoreError(ctx, err)
		return
	}
	if user.EmailVerifiedAt == nil {
		user, err = handler.store.MarkUserEmailVerified(ctx.Request.Context(), user.ID)
		if err != nil {
			api.StoreError(ctx, err)
			return
		}
	}

	authResponse, err := createAuthTokensResponse(ctx, handler.authFlow, handler.store, handler.sessionTTL, user, authflow.DefaultWorkspaceOptions{})
	if err != nil {
		api.StoreError(ctx, err)
		return
	}
	ctx.JSON(http.StatusOK, authResponse)
}
