import os
import platform

from django.shortcuts import render, redirect, get_object_or_404
from django.utils import timezone
from .models import (
    Profile, Intent, ValueTag, Message, Post, Comment, Reaction, 
    HiddenPost, Follow, ConnectionRequest, Like, Match, Thread, Block,
    Event, RSVP, EventTag, EventInvite
)
from .forms import EventForm
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth import login
from django.contrib.auth.decorators import login_required
from django.db.models import Q

def get_dashboard_context(request):
    """Helper to get consistent context for dashboard-like views."""
    stats = {}
    suggested_members = []
    suggested_events = []
    following_ids = []
    
    if request.user.is_authenticated:
        # Quick Stats
        stats = {
            'unread_messages': Message.objects.filter(recipient=request.user, is_read=False).count(),
            'pending_connections': ConnectionRequest.objects.filter(to_user=request.user, status='pending').count(),
            'upcoming_events_count': request.user.rsvps.filter(status='going', event__start_datetime__gt=timezone.now()).count(),
            'completion_percentage': request.user.profile.profile_completion_percentage,
            'streak': request.user.profile.win_streak,
            'followers_count': request.user.profile.followers_count,
            'following_count': request.user.profile.following_count,
        }

        following_ids = list(Follow.objects.filter(follower=request.user).values_list('followed_id', flat=True))

        # Suggestions
        user_intents = request.user.profile.intents.all()
        user_values = request.user.profile.value_tags.all()
        suggested_members = Profile.objects.filter(
            Q(intents__in=user_intents) | Q(value_tags__in=user_values)
        ).exclude(user=request.user).distinct()[:10]

        # Suggested Events
        suggested_events = Event.objects.filter(start_datetime__gt=timezone.now()).order_by('start_datetime')[:5]

    return {
        "stats": stats,
        "suggested_members": suggested_members,
        "suggested_events": suggested_events,
        "following_ids": following_ids,
        "post_types": Post.POST_TYPE_CHOICES,
        "current_time": timezone.now(),
        "deployment_timestamp": int(timezone.now().timestamp()),
        "project_name": "Roster",
    }

def home(request):
    """Render the landing screen or member dashboard."""
    
    # Simple logic to seed data for the first run
    if not Intent.objects.exists():
        intents_data = [
            ('Competitive', 'bi-trophy'),
            ('Casual/Social', 'bi-controller'),
            ('Ranked Climb', 'bi-graph-up-arrow'),
            ('Co-op/Story', 'bi-people-fill')
        ]
        for name, icon in intents_data:
            Intent.objects.create(name=name, icon=icon)
            
    if not Profile.objects.exists():
        # Create a demo user/profile
        demo_user, _ = User.objects.get_or_create(username='marcus_v', first_name='Marcus', last_name='V.')
        p = Profile.objects.create(
            user=demo_user,
            professional_headline='Architect & Urban Planner',
            bio='Passionate about competitive FPS. Recently moved here and looking for a long-term squad.',
            location_city='Austin, TX',
        )
        p.intents.add(Intent.objects.get(name='Networking'))
        
        demo_user2, _ = User.objects.get_or_create(username='sarah_l', first_name='Sarah', last_name='L.')
        p2 = Profile.objects.create(
            user=demo_user2,
            professional_headline='UX Researcher | Growth Mindset',
            bio='Rediscovering my love for MOBAs. Seeking competitive matches and team coordination.',
            location_city='Austin, TX',
        )
        p2.intents.add(Intent.objects.get(name='Friendship'))

    # Social Feed Logic
    hidden_post_ids = []
    if request.user.is_authenticated:
        hidden_post_ids = HiddenPost.objects.filter(user=request.user).values_list('post_id', flat=True)
    
    posts = Post.objects.exclude(id__in=hidden_post_ids).select_related('author', 'author__profile').prefetch_related('comments', 'comments__author', 'reactions')

    # Filtering by intent (for discovery)
    intent_filter = request.GET.get('intent')
    if intent_filter:
        profiles = Profile.objects.filter(intents__name__iexact=intent_filter)
    else:
        profiles = Profile.objects.all()

    intents = Intent.objects.all()

    context = get_dashboard_context(request)
    context.update({
        "profiles": profiles,
        "intents": intents,
        "current_intent": intent_filter,
        "posts": posts,
    })
    return render(request, "core/index.html", context)

@login_required
def create_post(request):
    if request.method == 'POST':
        content = request.POST.get('content')
        image = request.FILES.get('image')
        post_type = request.POST.get('post_type', 'lfg')
        if content or image:
            Post.objects.create(author=request.user, content=content, image=image, post_type=post_type)
    return redirect('home')

@login_required
def delete_post(request, post_id):
    post = get_object_or_404(Post, id=post_id, author=request.user)
    post.delete()
    return redirect(request.META.get('HTTP_REFERER', 'home'))

@login_required
def add_comment(request, post_id):
    if request.method == 'POST':
        post = get_object_or_404(Post, id=post_id)
        content = request.POST.get('content')
        if content:
            Comment.objects.create(post=post, author=request.user, content=content)
    return redirect(request.META.get('HTTP_REFERER', 'home'))

@login_required
def toggle_reaction(request, post_id):
    post = get_object_or_404(Post, id=post_id)
    reaction_type = request.GET.get('type', 'heart')
    reaction, created = Reaction.objects.get_or_create(
        post=post, user=request.user, reaction_type=reaction_type
    )
    if not created:
        reaction.delete()
    return redirect(request.META.get('HTTP_REFERER', 'home'))

@login_required
def toggle_follow(request, username):
    target_user = get_object_or_404(User, username=username)
    if target_user == request.user:
        return redirect(request.META.get('HTTP_REFERER', 'home'))
    
    follow, created = Follow.objects.get_or_create(follower=request.user, followed=target_user)
    if not created:
        follow.delete()
    
    return redirect(request.META.get('HTTP_REFERER', 'home'))

@login_required
def hide_post(request, post_id):
    post = get_object_or_404(Post, id=post_id)
    HiddenPost.objects.get_or_create(user=request.user, post=post)
    return redirect('home')

def about(request):
    return render(request, "core/about.html")

def signup(request):
    if request.method == 'POST':
        form = UserCreationForm(request.POST)
        if form.is_valid():
            user = form.save()
            # Create profile
            Profile.objects.get_or_create(user=user)
            login(request, user)
            return redirect('onboarding')
    else:
        form = UserCreationForm()
    return render(request, 'registration/signup.html', {'form': form})

@login_required
def onboarding(request):
    profile = request.user.profile
    if request.method == 'POST':
        profile.gamer_tag = request.POST.get('gamer_tag', '')
        profile.platform = request.POST.get('platform', 'pc')
        profile.primary_game_id = request.POST.get('primary_game')
        profile.bio = request.POST.get('bio', '')
        profile.onboarding_completed = True
        profile.save()
        return redirect('home')
    
    from .models import Game
    games = Game.objects.all().order_by('name')
    return render(request, 'core/onboarding.html', {
        'profile': profile,
        'games': games,
        'platforms': profile.PLATFORM_CHOICES
    })

@login_required
def settings_view(request):
    profile = request.user.profile
    if request.method == 'POST':
        profile.two_factor_enabled = 'two_factor' in request.POST
        profile.save()
        return redirect('settings')
    return render(request, 'core/settings.html', {'profile': profile})

def get_started(request):
    if not request.user.is_authenticated:
        return redirect('signup')
    if not request.user.profile.onboarding_completed:
        return redirect('onboarding')
    return redirect('home')

@login_required
def inbox(request):
    # Get all users the current user has messaged or received messages from
    sent_to = Message.objects.filter(sender=request.user).values_list('recipient', flat=True)
    received_from = Message.objects.filter(recipient=request.user).values_list('sender', flat=True)
    
    partner_ids = set(list(sent_to) + list(received_from))
    partners = User.objects.filter(id__in=partner_ids).select_related('profile')
    
    for partner in partners:
        last_message = Message.objects.filter(
            Q(sender=request.user, recipient=partner) | 
            Q(sender=partner, recipient=request.user)
        ).order_by('-timestamp').first()
        partner.last_message = last_message

    return render(request, 'core/inbox.html', {'partners': partners})

@login_required
def chat_detail(request, username):
    partner = get_object_or_404(User, username=username)
    if partner == request.user:
        return redirect('inbox')
        
    thread = Thread.objects.filter(participants=request.user).filter(participants=partner).first()
    if not thread:
        thread = Thread.objects.create()
        thread.participants.add(request.user, partner)

    if request.method == 'POST':
        body = request.POST.get('body')
        if body:
            Message.objects.create(sender=request.user, recipient=partner, body=body, thread=thread)
            thread.updated_at = timezone.now()
            thread.save()
            return redirect('chat_detail', username=username)
            
    messages = Message.objects.filter(thread=thread).order_by('timestamp')
    messages.filter(recipient=request.user, is_read=False).update(is_read=True)
    
    return render(request, 'core/chat.html', {
        'partner': partner,
        'chat_messages': messages,
        'thread': thread
    })

@login_required
def profile_view(request):
    return redirect('profile_detail', username=request.user.username)

def profile_detail(request, username):
    target_user = get_object_or_404(User, username=username)
    is_following = False
    if request.user.is_authenticated:
        is_following = Follow.objects.filter(follower=request.user, followed=target_user).exists()
    return render(request, 'core/profile_detail.html', {
        'target_user': target_user,
        'is_following': is_following
    })

@login_required
def edit_profile(request):
    profile = request.user.profile
    if request.method == 'POST':
        profile.professional_headline = request.POST.get('headline', '')
        profile.bio = request.POST.get('bio', '')
        profile.location_city = request.POST.get('location', '')
        profile.platform = request.POST.get('platform', '')
        profile.gamer_tag = request.POST.get('gamer_tag', '')
        profile.rank = request.POST.get('rank', '')
        profile.preferred_role = request.POST.get('preferred_role', '')
        
        primary_game_id = request.POST.get('primary_game')
        if primary_game_id:
            profile.primary_game_id = primary_game_id
            
        if 'avatar' in request.FILES:
            profile.avatar = request.FILES['avatar']
        profile.save()
        return redirect('my_profile')
    
    from .models import Game
    games = Game.objects.all().order_by('name')
    return render(request, 'core/edit_profile.html', {
        'profile': profile,
        'games': games,
        'platforms': profile.PLATFORM_CHOICES
    })

@login_required
def matches(request, tab=None):
    """Main hub for 'My Matches'."""
    if not tab:
        tab = request.GET.get('tab', 'mutual')
    search_query = request.GET.get('q', '')
    intent_filter = request.GET.get('intent', '')
    sort_by = request.GET.get('sort', 'newest')

    user = request.user
    
    if tab == 'requests':
        queryset = User.objects.filter(requests_sent__to_user=user, requests_sent__status='pending')
    elif tab == 'sent':
        queryset = User.objects.filter(requests_received__from_user=user, requests_received__status='pending')
    elif tab == 'liked':
        queryset = User.objects.filter(likes_received__from_user=user).exclude(
            Q(matches_a__user_b=user) | Q(matches_b__user_a=user)
        )
    elif tab == 'blocked':
        queryset = User.objects.filter(blocks_received__blocker=user)
    else: # mutual
        queryset = User.objects.filter(
            Q(matches_a__user_b=user, matches_a__status='active') | 
            Q(matches_b__user_a=user, matches_b__status='active')
        )

    if search_query:
        queryset = queryset.filter(
            Q(first_name__icontains=search_query) | 
            Q(last_name__icontains=search_query) |
            Q(username__icontains=search_query) |
            Q(profile__professional_headline__icontains=search_query) |
            Q(profile__location_city__icontains=search_query)
        )
    
    if intent_filter:
        queryset = queryset.filter(profile__intents__name=intent_filter)

    if sort_by == 'newest':
        queryset = queryset.order_by('-date_joined')
    elif sort_by == 'aligned':
        queryset = queryset.order_by('-profile__win_streak')

    queryset = queryset.select_related('profile').prefetch_related('profile__intents').distinct()

    context = get_dashboard_context(request)
    incoming_requests = ConnectionRequest.objects.filter(to_user=user, status='pending')
    request_map = {r.from_user_id: r.id for r in incoming_requests}

    context.update({
        'matches_list': queryset,
        'current_tab': tab,
        'search_query': search_query,
        'current_intent': intent_filter,
        'current_sort': sort_by,
        'intents': Intent.objects.all(),
        'title': 'My Matches',
        'request_map': request_map
    })
    return render(request, 'core/matches.html', context)

@login_required
def send_match_request(request, username):
    target_user = get_object_or_404(User, username=username)
    if target_user == request.user:
        return redirect('home')
    
    if Like.objects.filter(from_user=target_user, to_user=request.user).exists():
        Match.objects.get_or_create(
            user_a=min(request.user, target_user, key=lambda u: u.id),
            user_b=max(request.user, target_user, key=lambda u: u.id)
        )
        return redirect('matches')
    
    ConnectionRequest.objects.get_or_create(from_user=request.user, to_user=target_user, status='pending')
    return redirect(request.META.get('HTTP_REFERER', 'home'))

@login_required
def handle_match_request(request, request_id):
    conn_request = get_object_or_404(ConnectionRequest, id=request_id, to_user=request.user)
    action = request.GET.get('action')
    
    if action == 'accept':
        conn_request.status = 'accepted'
        conn_request.responded_at = timezone.now()
        conn_request.save()
        
        Match.objects.get_or_create(
            user_a=min(conn_request.from_user, conn_request.to_user, key=lambda u: u.id),
            user_b=max(conn_request.from_user, conn_request.to_user, key=lambda u: u.id)
        )
    elif action == 'decline':
        conn_request.status = 'declined'
        conn_request.responded_at = timezone.now()
        conn_request.save()
        
    return redirect('matches')

@login_required
def cancel_match_request(request, username):
    target_user = get_object_or_404(User, username=username)
    ConnectionRequest.objects.filter(from_user=request.user, to_user=target_user, status='pending').delete()
    return redirect('matches')

@login_required
def block_user(request, username):
    target_user = get_object_or_404(User, username=username)
    Block.objects.get_or_create(blocker=request.user, blocked=target_user)
    Match.objects.filter(
        Q(user_a=request.user, user_b=target_user) | 
        Q(user_a=target_user, user_b=request.user)
    ).delete()
    ConnectionRequest.objects.filter(
        Q(from_user=request.user, to_user=target_user) | 
        Q(from_user=target_user, to_user=request.user)
    ).delete()
    
    return redirect('matches')

@login_required
def toggle_like(request, username):
    target_user = get_object_or_404(User, username=username)
    if target_user == request.user:
        return redirect('home')
    
    like, created = Like.objects.get_or_create(from_user=request.user, to_user=target_user)
    if not created:
        like.delete()
    else:
        if Like.objects.filter(from_user=target_user, to_user=request.user).exists():
            Match.objects.get_or_create(
                user_a=min(request.user, target_user, key=lambda u: u.id),
                user_b=max(request.user, target_user, key=lambda u: u.id)
            )
    
    return redirect(request.META.get('HTTP_REFERER', 'home'))

@login_required
def groups(request):
    return render(request, 'core/placeholder.html', {'title': 'Groups'})

@login_required
def my_posts(request):
    posts = Post.objects.filter(author=request.user).select_related('author', 'author__profile').prefetch_related('comments', 'reactions')
    context = get_dashboard_context(request)
    context.update({
        'posts': posts, 
        'title': 'My Posts'
    })
    return render(request, 'core/index.html', context)

@login_required
def events(request):
    tab = request.GET.get('tab', 'upcoming')
    query = request.GET.get('q', '')
    
    events = Event.objects.all().order_by('start_datetime')
    
    if query:
        events = events.filter(
            Q(title__icontains=query) | Q(description__icontains=query) | Q(location_name__icontains=query)
        )
        
    if tab == 'mine':
        events = events.filter(creator=request.user)
    elif tab == 'attending':
        events = events.filter(rsvps__user=request.user, rsvps__status='going')
    elif tab == 'past':
        events = Event.objects.filter(start_datetime__lt=timezone.now()).order_by('-start_datetime')
    elif tab == 'calendar':
        # Simple grouping by date for calendar view
        events = events.filter(start_datetime__gt=timezone.now())
    else: # upcoming
        events = events.filter(start_datetime__gt=timezone.now())
        
    context = get_dashboard_context(request)
    
    # For calendar view, group events by date
    calendar_events = {}
    if tab == 'calendar':
        for event in events:
            date_key = event.start_datetime.date()
            if date_key not in calendar_events:
                calendar_events[date_key] = []
            calendar_events[date_key].append(event)
    
    context.update({
        'events': events,
        'calendar_events': calendar_events,
        'tab': tab,
        'query': query,
    })
    return render(request, 'core/events_list.html', context)

@login_required
def event_detail(request, event_id):
    event = get_object_or_404(Event, id=event_id)
    user_rsvp = RSVP.objects.filter(event=event, user=request.user).first()
    rsvps = event.rsvps.select_related('user', 'user__profile')
    
    context = get_dashboard_context(request)
    context.update({
        'event': event,
        'user_rsvp': user_rsvp,
        'rsvps': rsvps,
        'going_count': rsvps.filter(status='going').count(),
        'maybe_count': rsvps.filter(status='maybe').count(),
    })
    return render(request, 'core/event_detail.html', context)

@login_required
def event_create(request):
    if request.method == 'POST':
        form = EventForm(request.POST, request.FILES)
        if form.is_valid():
            event = form.save(commit=False)
            event.creator = request.user
            event.save()
            form.save_m2m()
            return redirect('event_detail', event_id=event.id)
    else:
        form = EventForm()
    
    context = get_dashboard_context(request)
    context.update({'form': form, 'title': 'Create Session'})
    return render(request, 'core/event_form.html', context)

@login_required
def event_edit(request, event_id):
    event = get_object_or_404(Event, id=event_id, creator=request.user)
    if request.method == 'POST':
        form = EventForm(request.POST, request.FILES, instance=event)
        if form.is_valid():
            form.save()
            return redirect('event_detail', event_id=event.id)
    else:
        form = EventForm(instance=event)
    
    context = get_dashboard_context(request)
    context.update({'form': form, 'title': 'Edit Session', 'event': event})
    return render(request, 'core/event_form.html', context)

@login_required
def event_delete(request, event_id):
    event = get_object_or_404(Event, id=event_id, creator=request.user)
    if request.method == 'POST':
        event.delete()
        return redirect('events')
    return render(request, 'core/event_confirm_delete.html', {'event': event})

@login_required
def event_rsvp(request, event_id):
    if request.method == 'POST':
        event = get_object_or_404(Event, id=event_id)
        status = request.POST.get('status')
        if status in ['going', 'maybe', 'not_going']:
            rsvp, created = RSVP.objects.update_or_create(
                event=event, user=request.user,
                defaults={'status': status}
            )
        elif status == 'cancel':
            RSVP.objects.filter(event=event, user=request.user).delete()
            
        return redirect(request.META.get('HTTP_REFERER', 'event_detail', event_id=event.id))
    return redirect('events')
