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/core/authidentity"
)

// MiniappPairingHandler owns the unauthenticated miniapp pairing exchange
// route. The issue side lives in the workspace package because it requires
// an authenticated workspace member.
type MiniappPairingHandler struct {
	store      Store
	sessionTTL time.Duration
}

// Exchange handles POST /api/v1/miniapp-pairing-exchanges.
// The store consumes the pairing code and mints a fresh session in the same
// transaction, so a mint-side failure rolls back code consumption and the
// miniapp can retry safely.
func (handler *MiniappPairingHandler) Exchange(ctx *gin.Context) {
	var request dto.MiniappPairingExchangeRequest
	if err := ctx.ShouldBindJSON(&request); err != nil {
		api.Error(ctx, http.StatusBadRequest, "Invalid request body")
		return
	}

	code := strings.TrimSpace(request.Code)
	if code == "" {
		api.Error(ctx, http.StatusBadRequest, "code is required")
		return
	}

	result, err := handler.store.ExchangeMiniappPairingCodeForSession(
		ctx.Request.Context(),
		code,
		authidentity.MiniappPairingClient{
			InstallationID: request.InstallationID,
			DeviceName:     request.DeviceName,
			DevicePlatform: request.DevicePlatform,
		},
		handler.sessionTTL,
	)
	if err != nil {
		api.StoreError(ctx, err)
		return
	}

	ctx.JSON(http.StatusOK, dto.MiniappPairingExchangeResponse{
		AccessToken:   result.AccessToken,
		RefreshToken:  result.RefreshToken,
		User:          userResponseFromDomain(result.User),
		WorkspaceID:   result.WorkspaceID,
		WorkspaceName: result.WorkspaceName,
		ServerURL:     result.ServerURL,
	})
}
