from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import permissions
from django.utils import timezone
from datetime import timedelta
from .models import PulseChannel, Pulse, PulseVote, HiddenGem, GemVote


def serialize_channel(c, user=None):
    return {
        "id": c.id, "name": c.name, "emoji": c.emoji,
        "description": c.description, "is_default": c.is_default,
        "pulse_count": c.pulses.filter(expires_at__gt=timezone.now()).count(),
        "created_by": c.created_by.username if c.created_by else None,
    }

def serialize_pulse(p, user=None):
    user_vote = None
    if user and user.is_authenticated:
        v = p.votes.filter(user=user).first()
        user_vote = v.vote if v else None
    return {
        "id": p.id, "channel_id": p.channel_id,
        "channel_name": p.channel.name, "channel_emoji": p.channel.emoji,
        "emoji": p.emoji, "label": p.label, "neighborhood": p.neighborhood,
        "note": p.note, "upvotes": p.upvotes, "downvotes": p.downvotes,
        "user": p.user.username, "user_vote": user_vote,
        "created_at": p.created_at, "expires_at": p.expires_at,
        "minutes_ago": int((timezone.now() - p.created_at).total_seconds() / 60),
    }

def serialize_gem(g, user=None):
    user_voted = False
    user_verified = False
    if user and user.is_authenticated:
        vote = g.gem_votes.filter(user=user).first()
        if vote:
            user_voted = True
            user_verified = vote.verify
    return {
        "id": g.id, "name": g.name, "category": g.category,
        "neighborhood": g.neighborhood, "tip": g.tip,
        "votes": g.votes, "verified_count": g.verified_count,
        "is_verified": g.is_verified, "created_at": g.created_at,
        "user_voted": user_voted, "user_verified": user_verified,
        "nominated_by": g.nominated_by.username if g.nominated_by else None,
    }

class PulseChannelListView(APIView):
    permission_classes = [permissions.IsAuthenticatedOrReadOnly]
    def get(self, request):
        channels = PulseChannel.objects.all()
        return Response([serialize_channel(c, request.user) for c in channels])
    def post(self, request):
        name = request.data.get("name", "").strip()
        emoji = request.data.get("emoji", "📡")
        description = request.data.get("description", "")
        if not name:
            return Response({"error": "Name required."}, status=400)
        if PulseChannel.objects.filter(name__iexact=name).exists():
            return Response({"error": "Channel already exists."}, status=400)
        c = PulseChannel.objects.create(name=name, emoji=emoji, description=description, created_by=request.user)
        return Response(serialize_channel(c, request.user), status=201)

class PulseFeedView(APIView):
    permission_classes = [permissions.IsAuthenticatedOrReadOnly]
    def get(self, request):
        channel_id = request.query_params.get("channel")
        neighborhood = request.query_params.get("neighborhood")
        qs = Pulse.objects.filter(expires_at__gt=timezone.now()).select_related("user","channel").order_by("-created_at")
        if channel_id: qs = qs.filter(channel_id=channel_id)
        if neighborhood: qs = qs.filter(neighborhood=neighborhood)
        user = request.user if request.user.is_authenticated else None
        return Response([serialize_pulse(p, user) for p in qs[:50]])
    def post(self, request):
        channel_id = request.data.get("channel_id")
        emoji = request.data.get("emoji", "📡")
        label = request.data.get("label", "")
        neighborhood = request.data.get("neighborhood", "other")
        note = request.data.get("note", "")
        hours = int(request.data.get("hours", 2))
        channel = PulseChannel.objects.filter(id=channel_id).first()
        if not channel:
            return Response({"error": "Channel not found."}, status=404)
        p = Pulse.objects.create(
            channel=channel, user=request.user, emoji=emoji, label=label,
            neighborhood=neighborhood, note=note,
            expires_at=timezone.now() + timedelta(hours=hours),
        )
        return Response(serialize_pulse(p, request.user), status=201)

class PulseVoteView(APIView):
    permission_classes = [permissions.IsAuthenticated]
    def post(self, request, pk):
        pulse = Pulse.objects.filter(id=pk).first()
        if not pulse: return Response({"error": "Not found."}, status=404)
        vote = request.data.get("vote")
        if vote not in ["up","down"]: return Response({"error": "Invalid vote."}, status=400)
        existing = PulseVote.objects.filter(pulse=pulse, user=request.user).first()
        if existing:
            if existing.vote == vote:
                existing.delete()
                if vote=="up": Pulse.objects.filter(id=pk).update(upvotes=max(0,pulse.upvotes-1))
                else: Pulse.objects.filter(id=pk).update(downvotes=max(0,pulse.downvotes-1))
            else:
                existing.vote = vote; existing.save()
                if vote=="up": Pulse.objects.filter(id=pk).update(upvotes=pulse.upvotes+1,downvotes=max(0,pulse.downvotes-1))
                else: Pulse.objects.filter(id=pk).update(upvotes=max(0,pulse.upvotes-1),downvotes=pulse.downvotes+1)
        else:
            PulseVote.objects.create(pulse=pulse, user=request.user, vote=vote)
            if vote=="up": Pulse.objects.filter(id=pk).update(upvotes=pulse.upvotes+1)
            else: Pulse.objects.filter(id=pk).update(downvotes=pulse.downvotes+1)
        pulse.refresh_from_db()
        return Response(serialize_pulse(pulse, request.user))

class HiddenGemListView(APIView):
    permission_classes = [permissions.IsAuthenticatedOrReadOnly]
    def get(self, request):
        user = request.user if request.user.is_authenticated else None
        followers_count = 0
        if user and user.is_authenticated:
            from followers.models import Follow
            followers_count = Follow.objects.filter(following=user).count()
        gems = HiddenGem.objects.all()
        data = [serialize_gem(g, user) for g in gems]
        if followers_count < 10:
            return Response({"gems":data[:3],"total":len(data),"locked":max(0,len(data)-3),"followers_count":followers_count,"can_nominate":False,"can_verify":False})
        return Response({"gems":data,"total":len(data),"locked":0,"followers_count":followers_count,"can_nominate":followers_count>=50,"can_verify":followers_count>=100})
    def post(self, request):
        from followers.models import Follow
        followers_count = Follow.objects.filter(following=request.user).count()
        if followers_count < 50:
            return Response({"error": f"You need 50 followers to nominate. You have {followers_count}."}, status=403)
        name = request.data.get("name","").strip()
        if not name: return Response({"error":"Name required."}, status=400)
        gem = HiddenGem.objects.create(
            name=name, category=request.data.get("category","other"),
            neighborhood=request.data.get("neighborhood","other"),
            tip=request.data.get("tip",""), nominated_by=request.user,
        )
        return Response(serialize_gem(gem, request.user), status=201)

class GemVoteView(APIView):
    permission_classes = [permissions.IsAuthenticated]
    def post(self, request, pk):
        gem = HiddenGem.objects.filter(id=pk).first()
        if not gem: return Response({"error":"Not found."}, status=404)
        verify = request.data.get("verify", False)
        existing = GemVote.objects.filter(gem=gem, user=request.user).first()
        if existing:
            existing.delete()
            HiddenGem.objects.filter(id=pk).update(votes=max(0,gem.votes-1))
            if existing.verify: HiddenGem.objects.filter(id=pk).update(verified_count=max(0,gem.verified_count-1))
        else:
            from followers.models import Follow
            fc = Follow.objects.filter(following=request.user).count()
            GemVote.objects.create(gem=gem, user=request.user, verify=verify and fc>=100)
            HiddenGem.objects.filter(id=pk).update(votes=gem.votes+1)
            if verify and fc>=100: HiddenGem.objects.filter(id=pk).update(verified_count=gem.verified_count+1)
        gem.refresh_from_db()
        if gem.verified_count >= 3: HiddenGem.objects.filter(id=pk).update(is_verified=True)
        return Response(serialize_gem(gem, request.user))


class PulseDeleteView(APIView):
    permission_classes = [permissions.IsAuthenticated]
    def delete(self, request, pk):
        pulse = Pulse.objects.filter(id=pk, user=request.user).first()
        if not pulse:
            return Response({"error": "Not found or not authorized."}, status=404)
        pulse.delete()
        return Response({"status": "deleted"})


class GemDeleteView(APIView):
    permission_classes = [permissions.IsAuthenticated]
    def delete(self, request, pk):
        gem = HiddenGem.objects.filter(id=pk).first()
        if not gem:
            return Response({"error": "Not found."}, status=404)
        if gem.nominated_by != request.user and not request.user.is_staff:
            return Response({"error": "Not authorized."}, status=403)
        gem.delete()
        return Response({"status": "deleted"})


class PulseChannelDeleteView(APIView):
    permission_classes = [permissions.IsAuthenticated]
    def delete(self, request, pk):
        channel = PulseChannel.objects.filter(id=pk).first()
        if not channel:
            return Response({"error": "Not found."}, status=404)
        if channel.is_default:
            return Response({"error": "Cannot delete default channels."}, status=400)
        if channel.created_by != request.user and not request.user.is_staff:
            return Response({"error": "Not authorized."}, status=403)
        channel.delete()
        return Response({"status": "deleted"})
