"""
Client self-service portal.
No account needed — verified by Surname + Email + Mobile + Postcode.
"""
import re
from decimal import Decimal
from django.shortcuts import render, redirect
from django.contrib import messages
from django.views.decorators.http import require_http_methods


# ── Helpers ───────────────────────────────────────────────────────────────────

def _normalise_phone(phone):
    """Strip everything except digits, keep last 9 for fuzzy match."""
    digits = re.sub(r'\D', '', phone or '')
    return digits[-9:] if len(digits) >= 9 else digits


def _normalise_postcode(postcode):
    """Uppercase, no spaces."""
    return re.sub(r'\s+', '', (postcode or '').upper())


def _portal_client(request):
    """Return the verified client email from session, or None."""
    return request.session.get('portal_client_email')


def _require_portal(request):
    """Redirect to login if not verified."""
    if not _portal_client(request):
        return redirect('portal_login')
    return None


# ── Views ─────────────────────────────────────────────────────────────────────

def portal_login(request):
    """4-field verification — Surname, Email, Mobile, Postcode."""
    if _portal_client(request):
        return redirect('portal_dashboard')

    error = None

    if request.method == 'POST':
        surname  = request.POST.get('surname', '').strip().lower()
        email    = request.POST.get('email', '').strip().lower()
        mobile   = _normalise_phone(request.POST.get('mobile', ''))
        postcode = _normalise_postcode(request.POST.get('postcode', ''))

        if not all([surname, email, mobile, postcode]):
            error = 'Please fill in all four fields.'
        else:
            from apps.ecommerce.models import Order
            # Find orders by email
            orders = Order.objects.filter(customer_email__iexact=email)
            if not orders.exists():
                error = 'We could not find any orders linked to that email address.'
            else:
                matched = False
                for order in orders:
                    name_ok     = surname in order.customer_name.lower()
                    phone_ok    = _normalise_phone(order.customer_phone).endswith(mobile) if mobile else False
                    postcode_ok = _normalise_postcode(order.customer_postcode) == postcode

                    # Require email + at least 2 of the other 3
                    score = sum([name_ok, phone_ok, postcode_ok])
                    if score >= 2:
                        matched = True
                        break

                if matched:
                    request.session['portal_client_email'] = email
                    request.session['portal_client_name']  = order.customer_name.split()[0]
                    return redirect('portal_dashboard')
                else:
                    error = 'The details you entered do not match our records. Please check and try again.'

    return render(request, 'public/portal/login.html', {'error': error})


def portal_logout(request):
    request.session.pop('portal_client_email', None)
    request.session.pop('portal_client_name', None)
    return redirect('portal_login')


def portal_dashboard(request):
    """Client dashboard — balances, payment history, order history."""
    redir = _require_portal(request)
    if redir:
        return redir

    email      = _portal_client(request)
    first_name = request.session.get('portal_client_name', 'there')

    from apps.ecommerce.models import Order
    orders = Order.objects.filter(
        customer_email__iexact=email
    ).prefetch_related('items').order_by('-created_at')

    # Split into sections
    outstanding = [o for o in orders if o.balance_due > 0]
    paid_orders = [o for o in orders if o.amount_paid > 0]
    all_orders  = list(orders)

    total_outstanding = sum(o.balance_due for o in outstanding)

    return render(request, 'public/portal/dashboard.html', {
        'first_name':       first_name,
        'outstanding':      outstanding,
        'paid_orders':      paid_orders,
        'all_orders':       all_orders,
        'total_outstanding': total_outstanding,
        'client_email':     email,
    })


def portal_ticket(request):
    """Submit a support ticket from the portal."""
    redir = _require_portal(request)
    if redir:
        return redir

    email      = _portal_client(request)
    first_name = request.session.get('portal_client_name', '')

    if request.method == 'POST':
        subject = request.POST.get('subject', '').strip()
        message = request.POST.get('message', '').strip()
        order_ref = request.POST.get('order_ref', '').strip()

        if not subject or not message:
            messages.error(request, 'Please fill in both subject and message.')
        else:
            from apps.ecommerce.models import Order
            from apps.tickets.models import Ticket

            # Try to link to order
            order = None
            if order_ref:
                try:
                    order = Order.objects.get(
                        order_number__iexact=order_ref,
                        customer_email__iexact=email
                    )
                except Order.DoesNotExist:
                    pass

            # Get customer name from orders
            name = first_name
            try:
                latest = Order.objects.filter(customer_email__iexact=email).latest('created_at')
                name = latest.customer_name
            except Order.DoesNotExist:
                pass

            full_message = message
            if order_ref and not order:
                full_message = f'[Reference: {order_ref}]\n\n{message}'

            Ticket.objects.create(
                source      = Ticket.SOURCE_ORDER,
                priority    = Ticket.PRIORITY_MEDIUM,
                sender_name = name,
                sender_email= email,
                subject     = subject,
                message     = full_message,
                order       = order,
            )
            messages.success(request, 'Your ticket has been submitted. We will get back to you shortly.')
            return redirect('portal_dashboard')

    # Pre-fill order ref from querystring
    order_ref = request.GET.get('order', '')
    return render(request, 'public/portal/ticket.html', {
        'first_name': first_name,
        'order_ref':  order_ref,
        'client_email': email,
    })
