from celery import shared_task
from django.utils import timezone
from .models import CustomerWallet, LoyaltySubscription, KhataAccount, DeadHourDrop


@shared_task
def expire_loyalty_coins():
    """Hourly: expire stale coins across all wallets."""
    from .loyalty_services import WalletService
    now = timezone.now()
    wallets_with_expiring = CustomerWallet.objects.filter(
        transactions__is_expired=False,
        transactions__expires_at__isnull=False,
        transactions__expires_at__lte=now,
        transactions__coins__gt=0,
    ).distinct()

    total_expired = 0
    for wallet in wallets_with_expiring:
        expired = WalletService.expire_stale_coins(wallet)
        if expired > 0:
            total_expired += 1

    return f"Expired coins for {total_expired} wallets."


@shared_task
def expire_old_subscriptions():
    """Daily: mark subscriptions whose valid_until has passed as EXPIRED."""
    today = timezone.now().date()
    expired = LoyaltySubscription.objects.filter(
        status='ACTIVE',
        valid_until__lt=today,
    ).update(status='EXPIRED')
    return f"Expired {expired} subscriptions."


@shared_task
def reset_khata_lifelines():
    """1st of month: reset lifelines_used to 0 for all ACTIVE/OVERDUE khata accounts."""
    updated = KhataAccount.objects.filter(
        status__in=('ACTIVE', 'OVERDUE')
    ).update(lifelines_used=0)
    return f"Reset lifelines for {updated} accounts."


@shared_task
def check_overdue_khata():
    """Daily: check all khata accounts for overdue/blocked status."""
    from .loyalty_services import KhataService
    today = timezone.now().date()
    accounts = KhataAccount.objects.filter(
        current_tab_amount__gt=0,
        tab_due_date__isnull=False,
    ).select_related('wallet')
    updated = 0
    for account in accounts:
        old_status = account.status
        KhataService.check_overdue(account.wallet)
        account.refresh_from_db()
        if account.status != old_status:
            updated += 1
    return f"Updated status for {updated} khata accounts."


@shared_task
def send_coin_expiry_warnings():
    """Every 6 hours: warn customers about coins expiring in 24 hours."""
    from .whatsapp_service import send_coin_expiry_warning
    sent = 0
    wallets = CustomerWallet.objects.filter(
        transactions__is_expired=False,
        transactions__expires_at__isnull=False,
        transactions__expires_at__lte=timezone.now() + timezone.timedelta(hours=24),
        transactions__coins__gt=0,
    ).distinct()
    for wallet in wallets:
        if send_coin_expiry_warning(wallet):
            sent += 1
    return f"Sent expiry warnings to {sent} customers."


@shared_task
def process_dead_hour_drop(drop_id: int):
    """Async: send WhatsApp messages for a dead-hour drop campaign."""
    from .whatsapp_service import send_dead_hour_drop
    try:
        drop = DeadHourDrop.objects.select_related('restaurant').get(pk=drop_id)
    except DeadHourDrop.DoesNotExist:
        return f"Drop {drop_id} not found."

    valid_hours = 2
    if drop.valid_until:
        delta = drop.valid_until - timezone.now()
        valid_hours = max(1, int(delta.total_seconds() / 3600))

    sent = send_dead_hour_drop(drop.restaurant, drop.message, drop.discount_code, valid_hours)
    DeadHourDrop.objects.filter(pk=drop_id).update(total_recipients=sent)
    return f"Sent dead-hour drop to {sent} customers."


@shared_task
def loyalty_daily_summary():
    """11 PM daily: log summary of the day's loyalty activity (placeholder for owner WhatsApp report)."""
    from .models import CoinTransaction, Restaurant
    from django.db.models import Sum, Count
    today = timezone.now().date()
    start = timezone.datetime.combine(today, timezone.datetime.min.time(), tzinfo=timezone.get_current_timezone())

    stats = CoinTransaction.objects.filter(
        created_at__gte=start,
    ).aggregate(
        earned=Sum('coins', filter=__import__('django.db.models', fromlist=['Q']).Q(coins__gt=0)),
        redeemed=Sum('coins', filter=__import__('django.db.models', fromlist=['Q']).Q(coins__lt=0)),
        count=Count('id'),
    )
    return (
        f"Daily summary — earned: {stats['earned'] or 0}, "
        f"redeemed: {abs(stats['redeemed'] or 0)}, "
        f"transactions: {stats['count']}"
    )


def send_restaurant_bill_email_task(booking_id):
    from django.core.mail import EmailMultiAlternatives
    from django.template.loader import render_to_string
    from django.utils.html import strip_tags
    from django.conf import settings
    import logging
    logger = logging.getLogger(__name__)
    
    try:
        from .models import Booking
        booking = Booking.objects.get(id=booking_id)
        if not booking.email:
            logger.warning(f"No email provided for restaurant booking {booking_id}")
            return False

        context = {
            'restaurant_name': booking.restaurant.name,
            'customer_name': booking.customer_name,
            'order_date': booking.created_at,
            'booking_type': booking.get_booking_type_display(),
            'status': booking.get_status_display(),
            'payment_status': booking.get_payment_status_display(),
            'items': booking.items.all(),
            'subtotal': booking.subtotal,
            'tax_amount': booking.tax_amount,
            'delivery_charge': booking.delivery_charge,
            'booking_fee': booking.booking_fee,
            'total_amount': booking.total_amount,
        }

        html_content = render_to_string('restaurant/emails/restaurant_bill.html', context)
        text_content = strip_tags(html_content)
        
        subject = f"Your Bill/Receipt for {booking.restaurant.name}"
        from_email = settings.DEFAULT_FROM_EMAIL
        to_email = booking.email

        email = EmailMultiAlternatives(subject, text_content, from_email, [to_email])
        email.attach_alternative(html_content, "text/html")
        email.send()
        
        logger.info(f"Successfully sent restaurant bill email for booking {booking_id} to {to_email}")
        return True
    except Exception as exc:
        logger.error(f"Exception during sending restaurant bill email for booking {booking_id}: {str(exc)}")
        return False

def send_restaurant_bill_whatsapp_task(booking_id):
    import logging
    logger = logging.getLogger(__name__)
    try:
        from .models import Booking
        booking = Booking.objects.get(id=booking_id)
        
        phone = getattr(booking, 'contact_number', None)
        if not phone and booking.customer:
            phone = getattr(booking.customer, 'phone', None) or getattr(booking.customer, 'phone_number', None) or getattr(booking.customer, 'contact', None)
            
        if not phone:
            logger.warning(f"No phone provided for restaurant booking {booking_id}")
            return False

        message = (
            f"Thank you for dining at {booking.restaurant.name}!\n"
            f"Your order (ID: {booking.id}) is now completed.\n"
            f"Total Bill Amount: Rs {booking.total_amount}\n"
            f"We have also sent a detailed receipt to your email."
        )

        from .whatsapp_service import send_reply
        success = send_reply(phone, message)
        
        if success:
            logger.info(f"Successfully sent restaurant bill whatsapp for booking {booking_id} to {phone}")
        return success
    except Booking.DoesNotExist:
        logger.error(f"Booking {booking_id} does not exist. Cannot send whatsapp.")
        return False
    except Exception as exc:
        logger.error(f"Exception during sending restaurant bill whatsapp for booking {booking_id}: {str(exc)}")
        return False

