from django.shortcuts import render, redirect, get_object_or_404
from django.views import View
from django.views.generic import ListView, CreateView, DetailView, UpdateView, DeleteView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.urls import reverse_lazy, reverse
from django.db.models import Q
from django.db import transaction
from django.http import JsonResponse, HttpResponseRedirect
from .models import Bookmark, Team, Extraction, BookmarkShare, Summary
from .tasks import process_bookmark
from auditlog.models import LogEntry

class BookmarkListView(LoginRequiredMixin, ListView):
    model = Bookmark
    template_name = 'core/index.html'
    context_object_name = 'bookmarks'
    paginate_by = 20

    def get_queryset(self):
        queryset = Bookmark.objects.filter(user=self.request.user).order_by('-created_at')
        
        # Search filter
        query = self.request.GET.get('q')
        if query:
            queryset = queryset.filter(
                Q(title__icontains=query) |
                Q(url__icontains=query) |
                Q(notes__icontains=query) |
                Q(extraction__content_text__icontains=query)
            ).distinct()
        
        # Tag filter
        tag = self.request.GET.get('tag')
        if tag:
            queryset = queryset.filter(tags__name__in=[tag])
            
        return queryset

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        # Add all tags used by the user for a sidebar or filter list
        from taggit.models import Tag
        context['all_tags'] = Tag.objects.filter(bookmark__user=self.request.user).distinct()
        context['teams'] = self.request.user.teams.all()
        return context

class BookmarkCreateView(LoginRequiredMixin, CreateView):
    model = Bookmark
    fields = ['url', 'title', 'notes', 'is_favorite']
    template_name = 'core/bookmark_form.html'
    success_url = reverse_lazy('home')

    def form_valid(self, form):
        form.instance.user = self.request.user
        # Save first to get the object
        self.object = form.save()
        
        # Handle tags if provided in a separate field or as a comma-separated string
        tags = self.request.POST.get('tags_input')
        if tags:
            self.object.tags.add(*[t.strip() for t in tags.split(',')])
        
        # Trigger background task
        process_bookmark.delay(self.object.id)
        
        if self.request.headers.get('X-Requested-With') == 'XMLHttpRequest':
            return JsonResponse({'status': 'success', 'redirect_url': str(self.success_url)})
            
        return HttpResponseRedirect(self.get_success_url())

class BookmarkUpdateView(LoginRequiredMixin, UpdateView):
    model = Bookmark
    fields = ['url', 'title', 'notes', 'is_favorite']
    template_name = 'core/bookmark_form.html'
    
    def get_success_url(self):
        return reverse('bookmark-detail', kwargs={'pk': self.object.pk})

    def form_valid(self, form):
        # Handle tags update
        tags_input = self.request.POST.get('tags_input', '')
        
        with transaction.atomic():
            self.object = form.save()
            
            # Clear existing tags and set new ones
            self.object.tags.clear()
            if tags_input:
                tag_names = [t.strip() for t in tags_input.split(',') if t.strip()]
                if tag_names:
                    self.object.tags.add(*tag_names)
        
        return HttpResponseRedirect(self.get_success_url())

    def get_queryset(self):
        return Bookmark.objects.filter(user=self.request.user)

class BookmarkDeleteView(LoginRequiredMixin, DeleteView):
    model = Bookmark
    success_url = reverse_lazy('home')

    def get_queryset(self):
        return Bookmark.objects.filter(user=self.request.user)

class BookmarkDetailView(LoginRequiredMixin, DetailView):
    model = Bookmark
    template_name = 'core/bookmark_detail.html'
    context_object_name = 'bookmark'

    def get_queryset(self):
        # Allow viewing if it's the user's bookmark OR shared with one of their teams
        user_teams = self.request.user.teams.all()
        return Bookmark.objects.filter(
            Q(user=self.request.user) | 
            Q(shares__team__in=user_teams)
        ).distinct()

class BookmarkRegenerateView(LoginRequiredMixin, View):
    def post(self, request, pk):
        bookmark = get_object_or_404(Bookmark, pk=pk, user=request.user)
        # Delete existing summary and extraction to force regeneration and show loading states
        if hasattr(bookmark, 'summary'):
            bookmark.summary.delete()
        if hasattr(bookmark, 'extraction'):
            bookmark.extraction.delete()
            
        process_bookmark.delay(bookmark.id)
        return HttpResponseRedirect(reverse('bookmark-detail', args=[pk]))

class SummaryUpdateView(LoginRequiredMixin, View):
    def post(self, request, pk):
        bookmark = get_object_or_404(Bookmark, pk=pk, user=request.user)
        content = request.POST.get('content')
        if content:
            Summary.objects.update_or_create(
                bookmark=bookmark,
                defaults={'content': content}
            )
        return HttpResponseRedirect(reverse('bookmark-detail', args=[pk]))

class ExtractionUpdateView(LoginRequiredMixin, View):
    def post(self, request, pk):
        bookmark = get_object_or_404(Bookmark, pk=pk, user=request.user)
        content_text = request.POST.get('content_text')
        if content_text:
            Extraction.objects.update_or_create(
                bookmark=bookmark,
                defaults={'content_text': content_text}
            )
        return HttpResponseRedirect(reverse('bookmark-detail', args=[pk]))

class TeamListView(LoginRequiredMixin, ListView):
    model = Team
    template_name = 'core/team_list.html'
    context_object_name = 'teams'

    def get_queryset(self):
        return self.request.user.teams.all()

class TeamDetailView(LoginRequiredMixin, DetailView):
    model = Team
    template_name = 'core/team_detail.html'
    context_object_name = 'team'

    def get_queryset(self):
        return self.request.user.teams.all()

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        # Get bookmarks shared with this team
        context['shared_bookmarks'] = Bookmark.objects.filter(shares__team=self.object).order_by('-shares__shared_at')
        return context

class BookmarkShareToggleView(LoginRequiredMixin, View):
    def post(self, request, pk, team_id):
        bookmark = get_object_or_404(Bookmark, pk=pk, user=request.user)
        team = get_object_or_404(Team, pk=team_id, members=request.user)
        
        share, created = BookmarkShare.objects.get_or_create(
            bookmark=bookmark,
            team=team,
            defaults={'shared_by': request.user}
        )
        
        if not created:
            share.delete()
            shared = False
        else:
            shared = True
            
        return JsonResponse({'shared': shared})

class UserActivityLogView(LoginRequiredMixin, ListView):
    model = LogEntry
    template_name = 'core/activity_log.html'
    context_object_name = 'log_entries'
    paginate_by = 20

    def get_queryset(self):
        return LogEntry.objects.filter(actor=self.request.user).select_related('content_type', 'actor').order_by('-timestamp')
