package channel

import (
	"net/http"
	"strings"

	"github.com/tidbcloud/AgentTeam/internal/api"
	"github.com/tidbcloud/AgentTeam/internal/api/dto"
	"github.com/tidbcloud/AgentTeam/internal/api/dto/converter"
	"github.com/tidbcloud/AgentTeam/internal/unread"
)

// ChannelShareCardHandler owns channel share-card routes.
type ChannelShareCardHandler struct {
	appStore      ChannelShareCardAppStore
	realtime      ChannelRealtime
	messageFanout MessageFanout
	unreadRuntime ChannelUnreadReader
}

// Create handles POST /api/channels/:channelId/share-card.
func (h *ChannelShareCardHandler) Create(r api.WorkspaceScopedJSON[dto.ChannelShareCardCreateRequest]) (api.Response, error) {
	channelID := strings.TrimSpace(r.Gin.Param("channelId"))
	if channelID == "" {
		return api.Response{}, api.NewHTTPError(http.StatusBadRequest, "channelId is required")
	}
	targetChannelID := strings.TrimSpace(r.Body.TargetChannelID)
	if targetChannelID == "" {
		return api.Response{}, api.NewHTTPError(http.StatusBadRequest, "targetChannelId is required")
	}

	appMessage, delivery, err := h.appStore.CreateChannelShareCardForUser(r.Context(), r.User.User, r.WorkspaceID(), channelID, targetChannelID)
	if err != nil {
		return api.Response{}, err
	}
	if h.messageFanout != nil {
		h.messageFanout.EmitCommittedHumanMessage(r.Context(), r.WorkspaceID(), appMessage, delivery)
	}
	return api.OK(converter.ToAppMessage(appMessage)), nil
}

// Share handles POST /api/channel-share-cards/:messageId/share.
func (h *ChannelShareCardHandler) Share(r api.WorkspaceScopedJSON[dto.ChannelShareCardCreateRequest]) (api.Response, error) {
	messageID := strings.TrimSpace(r.Gin.Param("messageId"))
	if messageID == "" {
		return api.Response{}, api.NewHTTPError(http.StatusBadRequest, "messageId is required")
	}
	targetChannelID := strings.TrimSpace(r.Body.TargetChannelID)
	if targetChannelID == "" {
		return api.Response{}, api.NewHTTPError(http.StatusBadRequest, "targetChannelId is required")
	}

	appMessage, delivery, err := h.appStore.ShareChannelShareCardForUser(r.Context(), r.User.User, r.WorkspaceID(), messageID, targetChannelID)
	if err != nil {
		return api.Response{}, err
	}
	if h.messageFanout != nil {
		h.messageFanout.EmitCommittedHumanMessage(r.Context(), r.WorkspaceID(), appMessage, delivery)
	}
	return api.OK(converter.ToAppMessage(appMessage)), nil
}

// Get handles GET /api/channel-share-cards/:messageId.
func (h *ChannelShareCardHandler) Get(r api.WorkspaceScopedRequest) (api.Response, error) {
	messageID := strings.TrimSpace(r.Gin.Param("messageId"))
	if messageID == "" {
		return api.Response{}, api.NewHTTPError(http.StatusBadRequest, "messageId is required")
	}
	card, err := h.appStore.LoadChannelShareCardForUser(r.Context(), r.User.User.ID, r.WorkspaceID(), messageID)
	if err != nil {
		return api.Response{}, err
	}
	return api.OK(converter.ToChannelShareCardView(card)), nil
}

// Join handles POST /api/channel-share-cards/:messageId/join.
func (h *ChannelShareCardHandler) Join(r api.WorkspaceScopedRequest) (api.Response, error) {
	messageID := strings.TrimSpace(r.Gin.Param("messageId"))
	if messageID == "" {
		return api.Response{}, api.NewHTTPError(http.StatusBadRequest, "messageId is required")
	}
	channel, err := h.appStore.JoinChannelShareCardForUser(r.Context(), r.User.User.ID, r.WorkspaceID(), messageID)
	if err != nil {
		return api.Response{}, err
	}
	applyChannelMemberScopeInvalidated(h.realtime, h.unreadRuntime, r.WorkspaceID(), r.User.User.ID, r.Workspace.MemberID, channel.ChannelID, unread.ScopeTypeChannel, "channel_share_card_join")
	if h.realtime != nil {
		h.realtime.SubscribeScopeForUser(r.WorkspaceID(), r.User.User.ID, channel.ChannelID)
		h.realtime.EmitChannelUpdated(r.WorkspaceID())
	}
	return api.OK(channelResponseFromSummary(channel)), nil
}

// Revoke handles POST /api/channel-share-cards/:messageId/revoke.
func (h *ChannelShareCardHandler) Revoke(r api.WorkspaceScopedRequest) (api.Response, error) {
	messageID := strings.TrimSpace(r.Gin.Param("messageId"))
	if messageID == "" {
		return api.Response{}, api.NewHTTPError(http.StatusBadRequest, "messageId is required")
	}
	card, err := h.appStore.RevokeChannelShareCardForUser(r.Context(), r.User.User.ID, r.WorkspaceID(), messageID)
	if err != nil {
		return api.Response{}, err
	}
	return api.OK(converter.ToChannelShareCardView(card)), nil
}
