"""
Public feed endpoint — returns the latest publicly shared items from each
content type. No authentication required.
"""
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import AllowAny
from rest_framework.response import Response

from apps.photos.models import GroupPhoto
from apps.sessions.models import FreePracticeSession, PRSSession, SpeedShootingSession
from apps.tools.models import ChronographAnalysis
from apps.gears.models import ReloadRecipe


def _session_row(s, kind):
    label = getattr(s, 'competition_name', None) or s.name or '(unnamed)'
    return {
        'id':       s.id,
        'type':     kind,
        'label':    label,
        'date':     str(s.date) if s.date else None,
        'location': s.location or None,
    }


@api_view(['GET'])
@permission_classes([AllowAny])
def public_feed(request):
    limit = min(int(request.query_params.get('limit', 8)), 20)

    # ── Sessions (merge all types) ──────────────────────────────────────────
    prs  = list(PRSSession.objects.filter(is_public=True).order_by('-date')[:limit])
    fp   = list(FreePracticeSession.objects.filter(is_public=True).order_by('-date')[:limit])
    ss   = list(SpeedShootingSession.objects.filter(is_public=True).order_by('-date')[:limit])

    sessions_raw = (
        [_session_row(s, 'PRS')      for s in prs] +
        [_session_row(s, 'Practice') for s in fp]  +
        [_session_row(s, 'Speed')    for s in ss]
    )
    sessions = sorted(sessions_raw, key=lambda x: x['date'] or '', reverse=True)[:limit]

    # ── Analyses ────────────────────────────────────────────────────────────
    analyses_qs = (
        ChronographAnalysis.objects
        .filter(is_public=True)
        .order_by('-date')[:limit]
    )
    analyses = [
        {
            'id':   a.id,
            'name': a.name,
            'date': str(a.date) if a.date else None,
        }
        for a in analyses_qs
    ]

    # ── Photos ──────────────────────────────────────────────────────────────
    photos_qs = (
        GroupPhoto.objects
        .filter(is_public=True)
        .select_related('photo', 'analysis')
        .order_by('-photo__uploaded_at')[:limit]
    )
    photos = []
    for gp in photos_qs:
        an = getattr(gp, 'analysis', None)
        photos.append({
            'id':             gp.id,
            'photo_id':       gp.photo_id,
            'caption':        gp.caption or None,
            'group_size_mm':  str(an.group_size_mm) if an and an.group_size_mm is not None else None,
            'group_size_moa': str(an.group_size_moa) if an and an.group_size_moa is not None else None,
        })

    # ── Reload recipes ──────────────────────────────────────────────────────
    recipes_qs = (
        ReloadRecipe.objects
        .filter(is_public=True)
        .select_related('caliber', 'bullet', 'primer', 'brass')
        .order_by('-created_at')[:limit]
    )
    recipes = []
    for r in recipes_qs:
        recipes.append({
            'id':      r.id,
            'name':    r.name,
            'caliber': r.caliber.name if r.caliber_id else None,
            'bullet':  str(r.bullet) if r.bullet_id else None,
            'date':    str(r.created_at.date()),
        })

    return Response({
        'sessions': sessions,
        'analyses': analyses,
        'photos':   photos,
        'recipes':  recipes,
    })
