import json
from django.shortcuts import render, get_object_or_404
from django.core.paginator import Paginator
from django.db.models import Q
from .models import City, Place, SimilarPlace, PlaceImage, ImageFeature


def city_list(request):
    cities = City.objects.all().order_by('name')
    city_data = []
    for city in cities:
        top_image = PlaceImage.objects.filter(place__city=city).first()
        city_data.append({
            'city': city,
            'top_image': top_image,
        })
    context = {
        'city_data': city_data,
    }
    return render(request, 'places/city_list.html', context)


def city_detail(request, slug):
    city = get_object_or_404(City, slug=slug)
    query = request.GET.get('q', '').strip()
    sort = request.GET.get('sort', 'score')
    order = request.GET.get('order', '')

    # Default direction: interest → desc, name → asc
    if sort == 'name':
        default_order = 'asc'
    else:
        default_order = 'desc'
    if order not in ('asc', 'desc'):
        order = default_order

    places_qs = Place.objects.filter(city=city).prefetch_related('categories', 'images')

    if query:
        places_qs = places_qs.filter(name__icontains=query)

    if sort == 'name':
        places_qs = places_qs.order_by('name' if order == 'asc' else '-name')
    else:
        places_qs = places_qs.order_by('-interest_score' if order == 'desc' else 'interest_score')

    paginator = Paginator(places_qs, 20)
    page_number = request.GET.get('page', 1)
    page_obj = paginator.get_page(page_number)

    context = {
        'city': city,
        'page_obj': page_obj,
        'query': query,
        'sort': sort,
        'order': order,
        'total_count': places_qs.count(),
    }
    return render(request, 'places/city_detail.html', context)


def place_detail(request, place_id):
    place = get_object_or_404(
        Place.objects.prefetch_related('categories', 'images'),
        pk=place_id
    )

    # Get similar places by each method
    structural_similar = (
        SimilarPlace.objects
        .filter(main_place=place, method='structural')
        .select_related('similar_place__city')
        .prefetch_related('similar_place__images')
        .order_by('-score')[:10]
    )

    image_same_city = (
        SimilarPlace.objects
        .filter(main_place=place, method='image_same_city')
        .select_related('similar_place__city')
        .prefetch_related('similar_place__images')
        .order_by('-score')[:5]
    )

    image_other_city = (
        SimilarPlace.objects
        .filter(main_place=place, method='image_other_city')
        .select_related('similar_place__city')
        .prefetch_related('similar_place__images')
        .order_by('-score')[:5]
    )

    # Get primary image
    primary_image = place.images.first()

    # Build color palette from KMeans feature vector
    color_palette = []
    if primary_image:
        feat = ImageFeature.objects.filter(image_path=primary_image.image_path).first()
        if feat:
            try:
                vec = json.loads(feat.feature_vector)  # 30 floats: 10 colors × RGB, normalized [0,1]
                for i in range(0, len(vec), 3):
                    r, g, b = int(vec[i] * 255), int(vec[i+1] * 255), int(vec[i+2] * 255)
                    color_palette.append(f'#{r:02x}{g:02x}{b:02x}')
            except Exception:
                pass

    context = {
        'place': place,
        'primary_image': primary_image,
        'color_palette': color_palette,
        'structural_similar': structural_similar,
        'image_same_city': image_same_city,
        'image_other_city': image_other_city,
        'google_maps_url': place.get_google_maps_url(),
    }
    return render(request, 'places/place_detail.html', context)
