package app

import (
	"context"
	"fmt"
	"strings"
)

// ValidateChannelSubscriptionForUser checks whether the user is allowed to subscribe to
// realtime events for one channel, DM thread, or reply thread.
//
// This matches the Socket.IO `join:channel` behaviour expected by the web app client.
func (store *Store) ValidateChannelSubscriptionForUser(ctx context.Context, userID string, workspaceID string, channelID string) error {
	trimmedChannelID := strings.TrimSpace(channelID)
	if trimmedChannelID == "" {
		return badRequest("channelId is required")
	}

	trimmedWorkspaceID := strings.TrimSpace(workspaceID)
	_, _, err := store.resolveAuthorizedHumanMessageTarget(ctx, strings.TrimSpace(userID), trimmedWorkspaceID, trimmedChannelID, channelReadAction, dmReadAction, threadReadAction)
	return err
}

// ListRealtimeRoomIDsForChannel returns the parent channel room plus any reply-thread
// rooms that inherit membership from that channel.
func (store *Store) ListRealtimeRoomIDsForChannel(ctx context.Context, workspaceID string, channelID string) ([]string, error) {
	trimmedWorkspaceID := strings.TrimSpace(workspaceID)
	trimmedChannelID := strings.TrimSpace(channelID)
	if trimmedChannelID == "" {
		return nil, badRequest("channelId is required")
	}

	roomIDs := []string{trimmedChannelID}
	rows, err := store.db.Query(ctx, `
SELECT child.id
FROM scopes parent
JOIN scopes child
  ON child.parent_scope_id = parent.id
 AND child.workspace_id = parent.workspace_id
 AND child.type = 'thread'
 AND child.status = 'active'
 AND child.archived_at IS NULL
WHERE parent.workspace_id = $1
  AND parent.id = $2
  AND parent.type = 'channel'
  AND parent.status = 'active'
  AND parent.archived_at IS NULL
ORDER BY child.id ASC
`, trimmedWorkspaceID, trimmedChannelID)
	if err != nil {
		return nil, fmt.Errorf("list channel realtime rooms: %w", err)
	}
	defer rows.Close()

	for rows.Next() {
		var roomID string
		if err := rows.Scan(&roomID); err != nil {
			return nil, fmt.Errorf("scan channel realtime room: %w", err)
		}
		trimmedRoomID := strings.TrimSpace(roomID)
		if trimmedRoomID == "" {
			continue
		}
		roomIDs = append(roomIDs, trimmedRoomID)
	}
	if err := rows.Err(); err != nil {
		return nil, fmt.Errorf("iterate channel realtime rooms: %w", err)
	}
	return roomIDs, nil
}
