# -*- coding: utf-8 -*-
"""
Pages Views Module

This module contains views for the pages application.
Provides CRUD operations for user-created pages.

Author: Focus Development Team
Version: 1.0.0
Created: 2025-01-01
"""

import logging
from typing import Any, Dict

from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
from django.db.models import Q, Count
from django.http import HttpRequest, HttpResponse, JsonResponse, Http404
from django.shortcuts import get_object_or_404, redirect, render
from django.urls import reverse_lazy, reverse
from django.utils.translation import gettext_lazy as _
from django.views.generic import (
    ListView, DetailView, CreateView, UpdateView, DeleteView,
    TemplateView, View
)

from .models import Page, PageStatus, PageVisibility
from .forms import PageForm, PageSearchForm
from apps.common.utils import get_client_ip

# Configure logging for this module
logger = logging.getLogger(__name__)


class PageListView(LoginRequiredMixin, ListView):
    """
    Display a paginated list of user's pages with filtering and search capabilities.
    
    This view shows only the pages created by the current user,
    with options to filter by status, visibility, and search.
    """
    
    model = Page
    template_name = 'pages/page_list.html'
    context_object_name = 'pages'
    paginate_by = 12
    
    def get_queryset(self):
        """Get filtered queryset of user's pages."""
        queryset = Page.objects.filter(author=self.request.user)
        
        # Apply search and filters
        form = PageSearchForm(self.request.GET)
        if form.is_valid():
            search = form.cleaned_data.get('search')
            status = form.cleaned_data.get('status')
            visibility = form.cleaned_data.get('visibility')
            is_featured = form.cleaned_data.get('is_featured')
            tags = form.cleaned_data.get('tags')
            sort_by = form.cleaned_data.get('sort_by') or '-created_at'
            
            if search:
                queryset = queryset.filter(
                    Q(title__icontains=search) |
                    Q(content__icontains=search) |
                    Q(excerpt__icontains=search) |
                    Q(tags__icontains=search)
                )
            
            if status:
                queryset = queryset.filter(status=status)
            
            if visibility:
                queryset = queryset.filter(visibility=visibility)
            
            if is_featured == 'true':
                queryset = queryset.filter(is_featured=True)
            elif is_featured == 'false':
                queryset = queryset.filter(is_featured=False)
            
            if tags:
                queryset = queryset.filter(tags__icontains=tags)
            
            queryset = queryset.order_by(sort_by)
        else:
            queryset = queryset.order_by('-created_at')
        
        return queryset
    
    def get_context_data(self, **kwargs):
        """Add additional context data."""
        context = super().get_context_data(**kwargs)
        
        # Add search form
        context['search_form'] = PageSearchForm(self.request.GET)
        
        # Add statistics
        user_pages = Page.objects.filter(author=self.request.user)
        context['stats'] = {
            'total': user_pages.count(),
            'published': user_pages.filter(status=PageStatus.PUBLISHED).count(),
            'drafts': user_pages.filter(status=PageStatus.DRAFT).count(),
            'featured': user_pages.filter(is_featured=True).count(),
        }
        
        context['title'] = _('My Pages')
        return context


class PageDetailView(DetailView):
    """
    Display a single page.
    
    Shows the page content with view tracking.
    Handles visibility permissions.
    """
    
    model = Page
    template_name = 'pages/page_detail.html'
    context_object_name = 'page'
    slug_url_kwarg = 'slug'
    
    def get_object(self, queryset=None):
        """Get the page object with permission checking."""
        page = get_object_or_404(Page, slug=self.kwargs['slug'])
        
        # Check if user can view this page
        if not page.is_visible_to_user(self.request.user):
            raise Http404(_('Page not found'))
        
        return page
    
    def get(self, request, *args, **kwargs):
        """Handle GET request and increment view count."""
        response = super().get(request, *args, **kwargs)
        
        # Increment view count (only for non-authors)
        page = self.get_object()
        if request.user != page.author:
            page.increment_view_count()
        
        return response
    
    def get_context_data(self, **kwargs):
        """Add additional context data."""
        context = super().get_context_data(**kwargs)
        page = self.get_object()
        
        context.update({
            'title': page.title,
            'can_edit': self.request.user == page.author,
            'tags_list': page.get_tags_list(),
        })
        
        return context


class PageCreateView(LoginRequiredMixin, CreateView):
    """
    Create a new page.
    """
    
    model = Page
    form_class = PageForm
    template_name = 'pages/page_form.html'
    
    def get_form_kwargs(self):
        """Add user to form kwargs."""
        kwargs = super().get_form_kwargs()
        kwargs['user'] = self.request.user
        return kwargs
    
    def form_valid(self, form):
        """Handle successful form submission."""
        messages.success(self.request, _('Page created successfully!'))
        return super().form_valid(form)
    
    def get_success_url(self):
        """Redirect to page detail after creation."""
        return self.object.get_absolute_url()
    
    def get_context_data(self, **kwargs):
        """Add additional context data."""
        context = super().get_context_data(**kwargs)
        context.update({
            'title': _('Create New Page'),
            'submit_text': _('Create Page'),
        })
        return context


class PageUpdateView(LoginRequiredMixin, UpdateView):
    """
    Update an existing page.
    
    Only the page author can edit their pages.
    """
    
    model = Page
    form_class = PageForm
    template_name = 'pages/page_form.html'
    slug_url_kwarg = 'slug'
    
    def get_object(self, queryset=None):
        """Get the page object with permission checking."""
        page = get_object_or_404(Page, slug=self.kwargs['slug'])
        
        # Only author can edit
        if page.author != self.request.user:
            raise Http404(_('Page not found'))
        
        return page
    
    def get_form_kwargs(self):
        """Add user to form kwargs."""
        kwargs = super().get_form_kwargs()
        kwargs['user'] = self.request.user
        return kwargs
    
    def form_valid(self, form):
        """Handle successful form submission."""
        messages.success(self.request, _('Page updated successfully!'))
        return super().form_valid(form)
    
    def get_success_url(self):
        """Redirect to page detail after update."""
        return self.object.get_absolute_url()
    
    def get_context_data(self, **kwargs):
        """Add additional context data."""
        context = super().get_context_data(**kwargs)
        context.update({
            'title': _('Edit Page'),
            'submit_text': _('Update Page'),
            'page': self.get_object(),
        })
        return context


class PageDeleteView(LoginRequiredMixin, DeleteView):
    """
    Delete a page.
    
    Only the page author can delete their pages.
    """
    
    model = Page
    template_name = 'pages/page_confirm_delete.html'
    slug_url_kwarg = 'slug'
    success_url = reverse_lazy('pages:page_list')
    
    def get_object(self, queryset=None):
        """Get the page object with permission checking."""
        page = get_object_or_404(Page, slug=self.kwargs['slug'])
        
        # Only author can delete
        if page.author != self.request.user:
            raise Http404(_('Page not found'))
        
        return page
    
    def delete(self, request, *args, **kwargs):
        """Handle page deletion."""
        page = self.get_object()
        messages.success(request, _('Page "{title}" deleted successfully!').format(title=page.title))
        return super().delete(request, *args, **kwargs)
    
    def get_context_data(self, **kwargs):
        """Add additional context data."""
        context = super().get_context_data(**kwargs)
        context['title'] = _('Delete Page')
        return context


class PublicPageListView(ListView):
    """
    Display a list of public pages.
    
    Shows published public pages for all users to browse.
    """
    
    model = Page
    template_name = 'pages/public_page_list.html'
    context_object_name = 'pages'
    paginate_by = 12
    
    def get_queryset(self):
        """Get public published pages."""
        queryset = Page.objects.filter(
            status=PageStatus.PUBLISHED,
            visibility=PageVisibility.PUBLIC
        ).select_related('author')
        
        # Apply search if provided
        search = self.request.GET.get('search')
        if search:
            queryset = queryset.filter(
                Q(title__icontains=search) |
                Q(excerpt__icontains=search) |
                Q(tags__icontains=search)
            )
        
        # Apply tag filter if provided
        tag = self.request.GET.get('tag')
        if tag:
            queryset = queryset.filter(tags__icontains=tag)
        
        return queryset.order_by('-published_at')
    
    def get_context_data(self, **kwargs):
        """Add additional context data."""
        context = super().get_context_data(**kwargs)
        
        context.update({
            'title': _('Public Pages'),
            'search_query': self.request.GET.get('search', ''),
            'current_tag': self.request.GET.get('tag', ''),
        })
        
        return context


class PageDashboardView(LoginRequiredMixin, TemplateView):
    """
    Dashboard view for page management.
    
    Provides an overview of user's pages with quick actions.
    """
    
    template_name = 'pages/page_dashboard.html'
    
    def get_context_data(self, **kwargs):
        """Add dashboard context data."""
        context = super().get_context_data(**kwargs)
        
        user_pages = Page.objects.filter(author=self.request.user)
        
        # Recent pages
        recent_pages = user_pages.order_by('-created_at')[:5]
        
        # Popular pages
        popular_pages = user_pages.order_by('-view_count')[:5]
        
        # Statistics
        stats = {
            'total_pages': user_pages.count(),
            'published_pages': user_pages.filter(status=PageStatus.PUBLISHED).count(),
            'draft_pages': user_pages.filter(status=PageStatus.DRAFT).count(),
            'featured_pages': user_pages.filter(is_featured=True).count(),
            'total_views': sum(page.view_count for page in user_pages),
        }
        
        context.update({
            'title': _('Pages Dashboard'),
            'recent_pages': recent_pages,
            'popular_pages': popular_pages,
            'stats': stats,
        })
        
        return context


class PagePreviewView(LoginRequiredMixin, DetailView):
    """
    Preview a page without incrementing view count.
    
    Only the page author can preview their pages.
    """
    
    model = Page
    template_name = 'pages/page_preview.html'
    context_object_name = 'page'
    slug_url_kwarg = 'slug'
    
    def get_object(self, queryset=None):
        """Get the page object with permission checking."""
        page = get_object_or_404(Page, slug=self.kwargs['slug'])
        
        # Only author can preview
        if page.author != self.request.user:
            raise Http404(_('Page not found'))
        
        return page
    
    def get_context_data(self, **kwargs):
        """Add additional context data."""
        context = super().get_context_data(**kwargs)
        page = self.get_object()
        
        context.update({
            'title': _('Preview: {title}').format(title=page.title),
            'is_preview': True,
            'tags_list': page.get_tags_list(),
        })
        
        return context
