import xbmc


def _build_custom_group_sets(group_channels):
    group_links = set()
    group_tvg_ids = set()
    group_titles = set()

    for channel in group_channels:
        link = channel.get('link')
        tvg_id = channel.get('tvg_id')
        title = channel.get('title')
        if link:
            group_links.add(link)
        if tvg_id:
            group_tvg_ids.add(tvg_id)
        if title:
            group_titles.add(title.lower())

    return group_links, group_tvg_ids, group_titles


def filter_channels_by_category(all_channels, category, get_custom_groups_fn, debug_log_fn):
    """Return filtered channels for standard or custom category filters."""
    if not category:
        return all_channels[:]

    if category.startswith("CUSTOM:"):
        group_name = category[7:]
        custom_groups = get_custom_groups_fn()
        selected_group = next((g for g in custom_groups if g.get('name') == group_name), None)
        if not selected_group:
            return all_channels[:]

        group_channels = selected_group.get('channels', [])
        group_links, group_tvg_ids, group_titles = _build_custom_group_sets(group_channels)

        filtered = []
        for channel in all_channels:
            channel_url = channel.get('url', '') or channel.get('stream_url', '')
            channel_tvg_id = channel.get('tvg_id', '')
            channel_name = channel.get('name', '').lower()
            if (
                channel_url in group_links
                or channel_tvg_id in group_tvg_ids
                or channel_name in group_titles
                or any(link in channel_url or channel_url in link for link in group_links)
            ):
                filtered.append(channel)

        debug_log_fn(
            f"DEBUG: Custom group '{group_name}' filtered to {len(filtered)} channels "
            f"(links: {len(group_links)}, tvg_ids: {len(group_tvg_ids)}, titles: {len(group_titles)})",
            xbmc.LOGINFO,
        )
        return filtered

    return [c for c in all_channels if c.get('group', '').lower() == category.lower()]
