"""
api/v1/web/views/binary_node_detail.py

GET /api/v1/web/binary-node/<distributor_id>/
    Returns full details for a binary tree node for the popup overlay.
    - Admin users: always accessible.
    - Regular users: only if PlatformFeatureFlag.BINARY_TREE_DETAILS is enabled.
    No mobile/email is returned for other users — only display-safe fields.
"""
from rest_framework import permissions
from rest_framework.response import Response
from rest_framework.views import APIView

from apps.business.distributor.models import DistributorID
from apps.business.schema_compat import defer_missing_product_part_payment_fields
from apps.business.schemes.models import OpportunityBundleLevel
from apps.platform.settings.models import PlatformFeatureFlag


def _build_node_detail(dist):
    """Build the full popup payload for a DistributorID."""
    user = dist.user
    sponsor = dist.sponsor_distributor
    sponsor_user = sponsor.user if sponsor else None

    # Level progress
    from apps.business.binary_tree.services.metrics_service import compute_binary_level_snapshot
    snapshot = None
    try:
        snapshot = compute_binary_level_snapshot(dist)
    except Exception:
        pass

    current_level = snapshot.current_level if snapshot else 0
    positions_to_next = snapshot.positions_to_next if snapshot else None
    subtree_total = snapshot.subtree_total if snapshot else 0
    next_level = snapshot.next_level if snapshot else None

    # Bundle levels
    bundle_levels = []
    if dist.product and dist.product.opportunity_bundle:
        try:
            levels_qs = OpportunityBundleLevel.objects.filter(
                opportunity_bundle=dist.product.opportunity_bundle
            ).order_by('level_number').values('level_number', 'required_positions')
            cumulative = 0
            for lvl in levels_qs:
                positions = int(lvl['required_positions'] or 0)
                cumulative += positions
                bundle_levels.append({
                    'level': lvl['level_number'],
                    'positions': positions,
                    'cumulative': cumulative,
                })
        except Exception:
            pass

    return {
        'distributor_id': str(dist.id),
        'distributor_code': dist.distributor_code,
        'global_position': dist.global_position,
        'binary_position': dist.binary_position,
        'is_active': dist.is_active,
        # Owner — safe public identity only
        'owner_full_name': (
            f"{getattr(user, 'first_name', '') or ''} "
            f"{getattr(user, 'last_name', '') or ''}".strip()
            or 'Member'
        ),
        'owner_referral_code': getattr(user, 'referral_code', None),
        # Sponsor
        'sponsor_distributor_code': sponsor.distributor_code if sponsor else None,
        'sponsor_global_position': sponsor.global_position if sponsor else None,
        'sponsor_owner_name': (
            f"{getattr(sponsor_user, 'first_name', '') or ''} "
            f"{getattr(sponsor_user, 'last_name', '') or ''}".strip()
            if sponsor_user else None
        ),
        'sponsor_referral_code': getattr(sponsor_user, 'referral_code', None) if sponsor_user else None,
        # Level info
        'current_level': current_level,
        'subtree_total': subtree_total,
        'positions_to_next': positions_to_next,
        'next_level': next_level,
        'bundle_levels': bundle_levels,
    }


class BinaryNodeDetailView(APIView):
    permission_classes = [permissions.IsAuthenticated]

    def get(self, request, distributor_id):
        user = request.user
        is_admin = user.is_staff or user.is_superuser

        # Feature-flag check for non-admins
        if not is_admin:
            if not PlatformFeatureFlag.is_on(PlatformFeatureFlag.BINARY_TREE_DETAILS):
                return Response(
                    {'success': False, 'error': 'This feature is not enabled.'},
                    status=403,
                )

        try:
            dist = defer_missing_product_part_payment_fields(
                DistributorID.objects.select_related(
                    'user', 'product__opportunity_bundle',
                    'sponsor_distributor__user',
                ),
                relation_prefix='product',
            ).get(pk=distributor_id)
        except DistributorID.DoesNotExist:
            return Response({'success': False, 'error': 'Distributor not found.'}, status=404)

        return Response({'success': True, 'data': _build_node_detail(dist)})
