package auth

import (
	"net/http"
	"time"

	"github.com/gin-gonic/gin"

	"github.com/tidbcloud/AgentTeam/desktop/internal/token"
)

// LogoutLeaseCallback receives the authenticated logical UI-session identity
// and the bearer lease expiry before the credential is deleted.
type LogoutLeaseCallback func(sessionID string, expiresAt time.Time)

// sessionTokenStore is the narrow token-store seam needed by logout.
type sessionTokenStore interface {
	SessionInfo(token string) (token.SessionMetadata, bool)
	DeleteSession(token string)
}

func LogoutHandlerWithLease(store sessionTokenStore, onLogout ...LogoutLeaseCallback) gin.HandlerFunc {
	return func(c *gin.Context) {
		authToken := ""
		if h := c.GetHeader("Authorization"); h != "" {
			if tok, ok := cutPrefix(h, "Bearer "); ok {
				authToken = tok
			}
		}
		if authToken == "" {
			authToken = c.GetHeader("X-Session-Token")
		}
		if authToken != "" && store != nil {
			session, ok := store.SessionInfo(authToken)
			if ok {
				// Fence active-selection watchers/subscribers before the bearer
				// token becomes invalid, preserving the auth→uisession handoff.
				for _, notify := range onLogout {
					if notify != nil {
						notify(session.LogicalSessionID, session.ExpiresAt)
					}
				}
				store.DeleteSession(authToken)
			}
		}
		c.JSON(http.StatusOK, gin.H{"status": "ok"})
	}
}

// newLogoutHandlerWithLease is the in-package-test-injectable constructor
// matching LogoutHandlerWithLease's signature.
func newLogoutHandlerWithLease(store sessionTokenStore, onLogout ...LogoutLeaseCallback) gin.HandlerFunc {
	return LogoutHandlerWithLease(store, onLogout...)
}
