from django.shortcuts import render, get_object_or_404, redirect
from django.contrib import messages
from django.http import Http404, JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django.conf import settings
from django.db import models
from .models import AuctionListing
from apps.tickets.models import Ticket
import math


def auction_list(request):
    listings = AuctionListing.objects.filter(
        status=AuctionListing.STATUS_ACTIVE,
        asset_type=AuctionListing.TYPE_DOMAIN,
    ).order_by('-is_premium', '-created_at')
    return render(request, 'public/auction.html', {'listings': listings})


def _find_listing(slug):
    """
    Resolve a listing from a URL slug, forgivingly.

    Slugs are built with slugify(name), which strips dots, so a listing named
    persiabet.com is stored as persiabetcom and the obvious URL, /auction/persiabet/,
    finds nothing. Match the stored slug first, then fall back to comparing the
    slugified name and the bare name with punctuation removed.
    """
    from django.utils.text import slugify

    listing = AuctionListing.objects.filter(slug__iexact=slug).first()
    if listing is not None:
        return listing

    wanted = slugify(slug)
    for candidate in AuctionListing.objects.all():
        name = (candidate.name or '').lower()
        if slugify(name) == wanted:
            return candidate
        # persiabet should also reach persiabet.com
        stem = name.split('.')[0]
        if stem and slugify(stem) == wanted:
            return candidate
    return None


def auction_detail(request, slug):
    # Status is not part of the lookup. A sold or reserved listing still has a
    # page, showing its badge with the enquiry form closed, which is what the
    # template is built for. Filtering on active turned those into 404s.
    listing = _find_listing(slug)
    if listing is None:
        raise Http404('No auction listing matches that address.')
    AuctionListing.objects.filter(pk=listing.pk).update(view_count=models.F('view_count') + 1)
    return render(request, 'public/auction_detail.html', {'listing': listing})


@csrf_exempt
def auction_enquiry(request, slug):
    """
    Guest-friendly enquiry for an auction listing.
    Supports three action types:
      interest  — Show Interest (just contact details + message)
      offer     — Make an Offer (includes offer_amount)
      buy_now   — Buy Now (willing to pay asking price)
    No login required. Creates a Ticket in the CMS inbox.
    """
    listing = get_object_or_404(AuctionListing, slug=slug, status=AuctionListing.STATUS_ACTIVE)

    if request.method != 'POST':
        return redirect('auction_detail', slug=slug)

    # --- Collect fields ---
    action_type  = request.POST.get('action_type', Ticket.ACTION_INTEREST)
    name         = request.POST.get('name', '').strip()
    email        = request.POST.get('email', '').strip()
    phone        = request.POST.get('phone', '').strip()
    company      = request.POST.get('company', '').strip()
    message      = request.POST.get('message', '').strip()
    offer_raw    = request.POST.get('offer_amount', '').strip()

    # Validate required fields
    if not name or not email:
        if request.headers.get('x-requested-with') == 'XMLHttpRequest':
            return JsonResponse({'ok': False, 'error': 'Name and email are required.'}, status=400)
        messages.error(request, 'Name and email are required.')
        return redirect('auction_detail', slug=slug)

    # Validate action_type
    valid_actions = [Ticket.ACTION_INTEREST, Ticket.ACTION_OFFER, Ticket.ACTION_BUY_NOW]
    if action_type not in valid_actions:
        action_type = Ticket.ACTION_INTEREST

    # Parse offer amount
    offer_amount = None
    if action_type == Ticket.ACTION_OFFER and offer_raw:
        try:
            offer_amount = float(offer_raw.replace(',', '').replace('£', '').replace('$', ''))
        except ValueError:
            offer_amount = None

    # Build subject line
    action_labels = {
        Ticket.ACTION_INTEREST: 'Interest',
        Ticket.ACTION_OFFER:    'Offer',
        Ticket.ACTION_BUY_NOW:  'Buy Now',
    }
    subject = f'Auction {action_labels[action_type]}: {listing.name}'
    if action_type == Ticket.ACTION_BUY_NOW and not listing.price_on_request:
        subject += f' @ {listing.display_price}'
    elif action_type == Ticket.ACTION_OFFER and offer_amount:
        subject += f' @ £{offer_amount:,.0f}'

    # Determine source
    source = Ticket.SOURCE_ORDER if action_type == Ticket.ACTION_BUY_NOW else Ticket.SOURCE_AUCTION

    # Priority: Buy Now = High, Offer = Medium, Interest = Low
    priority_map = {
        Ticket.ACTION_BUY_NOW:  Ticket.PRIORITY_HIGH,
        Ticket.ACTION_OFFER:    Ticket.PRIORITY_MEDIUM,
        Ticket.ACTION_INTEREST: Ticket.PRIORITY_LOW,
    }

    # If logged in, attach the user
    user = request.user if request.user.is_authenticated else None

    Ticket.objects.create(
        source=source,
        user=user,
        sender_name=name,
        sender_email=email,
        sender_phone=phone,
        sender_company=company,
        subject=subject,
        message=message or f'{action_labels[action_type]} submitted via auction page.',
        auction_listing=listing,
        action_type=action_type,
        offer_amount=offer_amount,
        category='Auction',
        priority=priority_map[action_type],
    )

    success_msg = {
        Ticket.ACTION_INTEREST: f'Thanks! We have noted your interest in {listing.name} and will be in touch shortly.',
        Ticket.ACTION_OFFER:    f'Your offer for {listing.name} has been received. We will review and get back to you.',
        Ticket.ACTION_BUY_NOW:  f'Great! Your purchase request for {listing.name} has been submitted. We will contact you to complete the transfer.',
    }[action_type]

    if request.headers.get('x-requested-with') == 'XMLHttpRequest':
        return JsonResponse({'ok': True, 'message': success_msg})

    messages.success(request, success_msg)
    return redirect('auction_detail', slug=slug)


def auction_reserve(request, slug):
    """
    Create a Stripe Checkout session for a 15% deposit on a priced domain.
    """
    listing = get_object_or_404(AuctionListing, slug=slug, status=AuctionListing.STATUS_ACTIVE)

    if not listing.asking_price:
        return redirect('auction_detail', slug=slug)

    try:
        import stripe
        from apps.ecommerce.stripe_utils import _get_stripe_secret_key
        stripe.api_key = _get_stripe_secret_key()

        deposit_pence = math.ceil(float(listing.asking_price) * 0.15 * 100)  # 15% in pence

        success_url = request.build_absolute_uri(f'/auction/{slug}/reserve/success/')
        cancel_url  = request.build_absolute_uri(f'/auction/{slug}/reserve/cancel/')

        session = stripe.checkout.Session.create(
            payment_method_types=['card'],
            line_items=[{
                'price_data': {
                    'currency': 'gbp',
                    'unit_amount': deposit_pence,
                    'product_data': {
                        'name': f'15% Reservation Deposit — {listing.name}',
                        'description': f'Secures {listing.name} for 48 hours. Remaining balance of £{float(listing.asking_price) * 0.85:,.0f} arranged directly.',
                    },
                },
                'quantity': 1,
            }],
            mode='payment',
            success_url=success_url + '?session_id={CHECKOUT_SESSION_ID}',
            cancel_url=cancel_url,
            metadata={'listing_slug': slug, 'listing_name': listing.name},
        )
        return redirect(session.url, permanent=False)

    except Exception as e:
        messages.error(request, 'Payment setup failed. Please contact us directly.')
        return redirect('auction_detail', slug=slug)


def auction_reserve_success(request, slug):
    listing = get_object_or_404(AuctionListing, slug=slug)
    # Create a high-priority ticket so the team knows
    session_id = request.GET.get('session_id', '')
    Ticket.objects.create(
        source=Ticket.SOURCE_ORDER,
        subject=f'Deposit Paid — {listing.name}',
        message=f'15% reservation deposit paid via Stripe. Session: {session_id}\nBalance due within 48 hours.',
        auction_listing=listing,
        action_type=Ticket.ACTION_BUY_NOW,
        category='Auction',
        priority=Ticket.PRIORITY_HIGH,
    )
    return render(request, 'public/auction_reserve_success.html', {'listing': listing})


def auction_reserve_cancel(request, slug):
    listing = get_object_or_404(AuctionListing, slug=slug, status=AuctionListing.STATUS_ACTIVE)
    return redirect('auction_detail', slug=slug)


def domain_landing(request):
    """
    Serves a branded 'Domain for Sale' page for any domain pointed at this server.
    Detects the hostname, strips www., looks up the matching AuctionListing.
    Add this as a catch-all URL and configure each domain's DNS to point here.
    """
    host = request.META.get('HTTP_HOST', '').lower().split(':')[0]
    host = host.removeprefix('www.')

    listing = AuctionListing.objects.filter(
        name__iexact=host,
        status=AuctionListing.STATUS_ACTIVE,
        asset_type=AuctionListing.TYPE_DOMAIN,
    ).first()

    if not listing:
        # Domain is pointed here but not in the system — show a generic page
        return render(request, 'public/domain_not_found.html', {'domain': host}, status=404)

    return render(request, 'public/auction_page.html', {
        'listing': listing,
        'is_domain_landing': True,
    })
