from decimal import Decimal

from django.contrib import messages
from django.db.models import Avg, Count, Q
from django.shortcuts import redirect, render

from accounts.forms import DeliveryPreferencesForm
from accounts.models import Profile
from products.models import Product


def _format_discount_offer(product):
    if not product or product.price == 0 or product.discount_price is None:
        return None
    savings = product.price - product.discount_price
    percent = int((savings / product.price * Decimal('100')).quantize(Decimal('1')))
    return {
        'title': f'{percent}% off',
        'description': f'{product.name} now available for Rs. {product.discount_price:.0f}',
        'note': f'Save Rs. {savings:.0f} on {product.category}',
    }


def _build_category_spotlights():
    top_categories = list(
        Product.objects.exclude(category='')
        .values('category')
        .annotate(
            total=Count('id'),
            featured_total=Count('id', filter=Q(featured=True)),
            avg_rating=Avg('rating'),
        )
        .order_by('-total', 'category')[:4]
    )

    for item in top_categories:
        category_products = Product.objects.filter(category=item['category'])
        item['avg_rating'] = item.get('avg_rating') or 0
        item['best_price'] = min((product.display_price for product in category_products), default=Decimal('0'))

    return top_categories


def home(request):
    trending_products = Product.objects.filter(featured=True).order_by('-created_at')[:4]
    if not trending_products.exists():
        trending_products = Product.objects.order_by('-created_at')[:4]

    aggregates = Product.objects.aggregate(avg_rating=Avg('rating'))
    discounted_products = list(Product.objects.filter(discount_price__isnull=False).order_by('discount_price')[:6])
    best_discount = None
    if discounted_products:
        best_discount = max(
            discounted_products,
            key=lambda p: ((p.price - p.discount_price) / p.price) if p.price else Decimal('0'),
        )

    featured_count = Product.objects.filter(featured=True).count()
    categories_count = Product.objects.values('category').exclude(category='').distinct().count()

    special_deals = []
    offer_deal = _format_discount_offer(best_discount)
    if offer_deal:
        special_deals.append(offer_deal)

    special_deals.append(
        {
            'title': f'{len(discounted_products)} offers live',
            'description': 'Discounts available across top Nepali categories.',
            'note': 'Browse products with extra savings today.',
        }
    )

    if featured_count:
        special_deals.append(
            {
                'title': 'Featured Seller Picks',
                'description': f'{featured_count} curated products from trusted sellers.',
                'note': 'Popular with Nepali shoppers.',
            }
        )
    else:
        special_deals.append(
            {
                'title': 'Daily Deals',
                'description': 'Fresh discount offers updated every day.',
                'note': 'Check back for more savings.',
            }
        )

    advertised_products = sorted(
        discounted_products,
        key=lambda p: ((p.price - p.discount_price) / p.price if p.price else Decimal('0')),
        reverse=True,
    )[:4]

    if not advertised_products:
        advertised_products = list(trending_products[:4])

    for product in advertised_products:
        savings = (product.price - product.discount_price) if product.discount_price else Decimal('0')
        percent = int((savings / product.price * Decimal('100')).quantize(Decimal('1'))) if product.price else 0
        if percent >= 50:
            label = 'Mega Deal'
        elif percent >= 30:
            label = 'Hot Deal'
        elif percent >= 15:
            label = 'Limited Time'
        else:
            label = 'Special Offer'
        if product.featured and percent >= 10:
            label = 'Featured Deal'
        product.deal_label = label

    experience_highlights = [
        {
            'title': 'Verified payments',
            'description': 'Orders are only marked paid after wallet or card verification is completed on the server.',
            'badge': 'Trusted checkout',
        },
        {
            'title': 'Flexible payment flow',
            'description': 'Customers can start with cash on delivery and later switch to eSewa or Khalti before shipment.',
            'badge': 'Wallet ready',
        },
        {
            'title': 'Smart product discovery',
            'description': 'Search, categories, sorting, wishlist, and featured filters make it easier to find the right item fast.',
            'badge': 'Fast browsing',
        },
        {
            'title': 'Trackable orders',
            'description': 'Order status, payment status, and next actions are visible from one clean dashboard-style experience.',
            'badge': 'Clear visibility',
        },
    ]

    return render(
        request,
        'core/home.html',
        {
            'trending_products': trending_products,
            'total_products': Product.objects.count(),
            'featured_products': featured_count,
            'categories_count': categories_count,
            'avg_rating': aggregates.get('avg_rating') or 0,
            'special_deals': special_deals,
            'advertised_products': advertised_products,
            'category_spotlights': _build_category_spotlights(),
            'experience_highlights': experience_highlights,
        },
    )


def about(request):
    return render(request, 'core/about.html')


def support(request):
    return render(request, 'core/support.html')


def set_language_preference(request):
    if request.method == 'POST':
        language = request.POST.get('language', 'en').strip().lower()
        next_url = request.POST.get('next', '/').strip()
    else:
        language = request.GET.get('language', 'en').strip().lower()
        next_url = request.GET.get('next', '/').strip()

    if language not in {'en', 'ne'}:
        language = 'en'

    request.session['site_language'] = language
    if next_url.startswith('/'):
        return redirect(next_url)
    return redirect('home')


def landing(request):
    return render(request, 'core/landing.html')


def settings_view(request):
    location_form = None
    guest_delivery_location = request.session.get('delivery_location', '').strip()
    profile = None

    if request.user.is_authenticated:
        profile = getattr(request.user, 'profile', None)
        if profile is None:
            profile = Profile.objects.create(user=request.user)

        if request.method == 'POST':
            location_form = DeliveryPreferencesForm(request.POST, instance=profile)
            if location_form.is_valid():
                profile = location_form.save()
                if profile.short_location:
                    request.session['delivery_location'] = profile.short_location
                else:
                    request.session.pop('delivery_location', None)
                messages.success(request, 'Delivery preferences updated successfully.')
                return redirect('settings')
            messages.error(request, 'Please correct the location details below.')
        else:
            location_form = DeliveryPreferencesForm(instance=profile)
    elif request.method == 'POST':
        guest_delivery_location = request.POST.get('delivery_location', '').strip()
        if guest_delivery_location:
            request.session['delivery_location'] = guest_delivery_location
            messages.success(request, 'Temporary delivery location saved for this browser.')
        else:
            request.session.pop('delivery_location', None)
            messages.info(request, 'Temporary delivery location cleared.')
        return redirect('settings')

    return render(
        request,
        'core/settings.html',
        {
            'location_form': location_form,
            'guest_delivery_location': guest_delivery_location,
            'location_saved_at': getattr(profile, 'location_updated_at', None),
        },
    )
