from rest_framework import status
from rest_framework.response import Response
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import AllowAny
from django.db.models import Q, Count
from django.db.models import Prefetch
from django.core.cache import cache
from django.conf import settings
from math import ceil
from developer.serializers import DeveloperTranslateSerializer, FilterDeveloperSerializer
from development.models import Development
from main.models import Language, SiteSettings
from .models import DeveloperTranslate

CACHE_TIME = settings.CACHE_TIME  # cache in second

@api_view(['GET'])
@permission_classes([AllowAny])
def developers_list(request):
    page = int(request.query_params.get('page', 1))
    page_size = int(request.query_params.get('page_size', 10))
    search = request.query_params.get('search')
    featured = request.query_params.get('featured')
    city = request.query_params.get('city')
    country = request.query_params.get('country')
    sort_by = request.query_params.get('sort_by', '-property_num')
    language = request.query_params.get('language', 'en')
    
    cache_key = f"developers_query_{page}_{page_size}_{search}_{featured}_{city}_{country}_{sort_by}_{language}"
    cached_result = cache.get(cache_key)
    if cached_result:
        return Response(cached_result)
        
    if page_size > 50:
        page_size = 50
        
    lang = Language.objects.filter(code=language).first()
    if lang is None:
        lang = Language.objects.filter(code="en").first()
        
    filters = Q(developer__is_active=True,
                developer__is_deleted=False, language=lang)
    if featured is not None:
        filters &= Q(developer__is_featured=featured)
    if search is not None and search != "":
        filters &= Q(developer__name__icontains=search) | Q(
            developer__translates__name__icontains=search)
    if city is not None and city != "":
        filters &= Q(developer__city__slug=city)
    if country is not None and country != "":
        filters = Q(developer__country__slug=country)
        
    developments_prefetch = Prefetch(
        'developer__developments',
        queryset=Development.objects.filter(
            is_active=True, is_deleted=False)
    )
    
    qs = DeveloperTranslate.objects.select_related(
        'language',
        'developer',
        'developer__city',
        'developer__country'
    ).prefetch_related(
        developments_prefetch,
        'developer__translates'
    ).annotate(property_num=Count('developer__developments')).filter(filters).exclude(Q(developer__name=None) | Q(developer__name="")).order_by(sort_by)
    
    count = qs.count()
    pages_count = ceil(count / page_size)
    if page > pages_count:
        page = pages_count
    if page < 1:
        page = 1

    start = 0 + (page - 1) * page_size
    end = start + page_size
    has_next_page = end < count

    canonical_url = f"https://entralon.com/{lang.code}/developers"
    title = "Developers"
    description = "list of Developer on Entralon."
    qp = ""
    if search:
        qp += f"{'&' if qp != '' else ''}search={search}"
        title = f"search {search} in Developers"
        description = f"list of search {search} in Developer on Entralon."
    if featured:
        qp += f"{'&' if qp != '' else ''}is_featured=true"
        title += f" is featured"
        description += f"list of featured Developers on Entralon."
    if country:
        qp += f"{'&' if qp != '' else ''}country={country}"
        title += f" in {country} country"
        description += f"list of developer in {country} country on Entralon."
    if city:
        qp += f"{'&' if qp != '' else ''}city={city}"
        title += f" in {city} city"
        description += f"list of developer in {city} city on Entralon."
    if page > 1:
        qp += f"{'&' if qp != '' else ''}page={page}"
        title += f" | Page {page}"
        description += f" | Page {page}"
    if qp != "":
        qp = "?" + qp
    canonical_url += qp
    title += " | Entralon"
    image = f"https://file.entralon.com/{SiteSettings.objects.first().default_developer_image}"
    
    out = {
        "node": qs[start:end],
        "page_info": {
            "has_next_page": has_next_page,
            "has_previous_page": page > 1,
            "current_page": page,
            "page_size": page_size,
            "count": count,
            "pages_count": pages_count,
        },
        "meta_tags": {
            "title": title,
            "description": description,
            "keywords": "developer, entralon, building, builder, real estate",
            "og_title": title,
            "og_description": description,
            "og_image": image,
            "og_type": "website",
            "twitter_card": "summary",
            "twitter_title": title,
            "twitter_description": description,
            "twitter_image": image,
            "canonical_url": canonical_url
        }
    }
    
    serializer = FilterDeveloperSerializer(out, context={'request': request})
    result = serializer.data
    cache.set(cache_key, result, CACHE_TIME)
    return Response(result)


@api_view(['GET'])
@permission_classes([AllowAny])
def developer_detail(request, slug):
    language = request.query_params.get('language', 'en')
    
    lang = Language.objects.filter(code=language).first()
    slug = slug.replace("developer-", "")
    if lang is None:
        lang = Language.objects.filter(code="en").first()
        
    developer = DeveloperTranslate.objects.filter(Q(developer__slug=slug) | Q(
        developer__translates__slug=slug), language=lang, developer__is_active=True, developer__is_deleted=False).first()
    if developer is None:
        developer = DeveloperTranslate.objects.select_related('language', 'developer').prefetch_related('developer__developments').filter(
            Q(developer__slug=slug) | Q(developer__translates__slug=slug), language__code="en", developer__is_active=True, developer__is_deleted=False).first()
    
    if not developer:
        return Response({"error": "Developer not found"}, status=status.HTTP_404_NOT_FOUND)
        
    serializer = DeveloperTranslateSerializer(developer, context={'request': request})
    return Response(serializer.data)