"""
Management command that notifies business owners about time-based events
nothing else in the codebase watches for: an offer about to end, a
promotion campaign whose paid duration has elapsed, a paid subscription
period about to run out, and — since there's no auto-recurring billing here
(Flutterwave checkout is payer-initiated, not a stored card Discovr can
re-charge) — actually reverting an expired subscription back to Free once
its period has genuinely ended, rather than leaving it paid-forever with no
enforcement. Also publishes scheduled Posts, for the same reason — setting
a Post's status to 'scheduled' with a `scheduled_for` time was previously a
dead end; nothing ever flipped it to 'published'.

Run with: python manage.py check_expiring_items
Intended to run hourly (see the `scheduler` service in docker-compose.yml) —
a scheduled post can therefore go live up to ~59 minutes after its exact
scheduled time, same granularity as every other check in this command.
"""
from datetime import timedelta

from django.core.management.base import BaseCommand
from django.utils import timezone

from business.models import Offer, Campaign, Subscription, Post, Plan
from business.utils import create_notification
from business.views_admin import sync_featured_placement
from authentication.utils import send_subscription_expiring_email, send_subscription_expired_email

OFFER_WARNING_WINDOW = timedelta(hours=24)
SUBSCRIPTION_WARNING_WINDOW = timedelta(days=3)


class Command(BaseCommand):
    help = 'Notify owners about offers ending soon, campaigns that have finished their run, and subscriptions about to expire'

    def handle(self, *args, **options):
        now = timezone.now()

        ending_offers = Offer.objects.filter(
            is_active=True,
            ending_soon_notified=False,
            end_at__gt=now,
            end_at__lte=now + OFFER_WARNING_WINDOW,
        ).select_related('business')
        offer_count = 0
        for offer in ending_offers:
            create_notification(
                user=offer.business.owner,
                notification_type='offer_ending',
                title='Offer Ending Soon',
                message=f'Your offer "{offer.title}" ends within 24 hours.',
                business=offer.business,
                action_url='/offers',
            )
            offer.ending_soon_notified = True
            offer.save(update_fields=['ending_soon_notified'])
            offer_count += 1

        active_campaigns = Campaign.objects.filter(status='active', activated_at__isnull=False).select_related('business', 'offer')
        campaign_count = 0
        for campaign in active_campaigns:
            if now >= campaign.activated_at + timedelta(days=campaign.duration_days):
                campaign.status = 'completed'
                campaign.save(update_fields=['status'])
                sync_featured_placement(campaign, turn_on=False)
                create_notification(
                    user=campaign.business.owner,
                    notification_type='campaign_ended',
                    title='Campaign Ended',
                    message=f'Your campaign "{campaign.content_title}" has finished its run.',
                    business=campaign.business,
                    action_url='/promote',
                )
                campaign_count += 1

        expiring_subs = Subscription.objects.filter(
            status='active',
            renewal_reminder_sent=False,
            current_period_end__isnull=False,
            current_period_end__gt=now,
            current_period_end__lte=now + SUBSCRIPTION_WARNING_WINDOW,
            plan__price__gt=0,
        ).select_related('business', 'business__owner', 'plan')
        sub_count = 0
        for sub in expiring_subs:
            days_left = max(1, (sub.current_period_end - now).days)
            create_notification(
                user=sub.business.owner,
                notification_type='subscription_expiring',
                title='Subscription Expiring Soon',
                message=f'Your {sub.plan.name} plan for "{sub.business.title}" renews in less than 3 days — pay now to avoid losing access.',
                business=sub.business,
                action_url='/billing',
            )
            send_subscription_expiring_email(
                email=sub.business.owner.email,
                first_name=sub.business.owner.first_name or 'there',
                business_title=sub.business.title,
                plan_name=sub.plan.name,
                days_left=days_left,
            )
            sub.renewal_reminder_sent = True
            sub.save(update_fields=['renewal_reminder_sent'])
            sub_count += 1

        # No auto-recurring charge exists (Flutterwave checkout is
        # payer-initiated, no stored card to re-bill) — so once a paid
        # period genuinely ends without a fresh payment, actually revert the
        # business to Free rather than leaving it on paid entitlements
        # forever with nothing enforcing the expiry.
        expired_subs = Subscription.objects.filter(
            status='active',
            current_period_end__isnull=False,
            current_period_end__lte=now,
            plan__price__gt=0,
        ).select_related('business', 'business__owner', 'plan')
        expired_count = 0
        free_plan = Plan.objects.filter(slug='free').first()
        if free_plan:
            for sub in expired_subs:
                expired_plan_name = sub.plan.name
                sub.plan = free_plan
                sub.current_period_end = None
                sub.renewal_reminder_sent = False
                sub.save(update_fields=['plan', 'current_period_end', 'renewal_reminder_sent'])
                create_notification(
                    user=sub.business.owner,
                    notification_type='subscription_expired',
                    title='Plan Expired — Moved to Free',
                    message=f'Your {expired_plan_name} plan for "{sub.business.title}" has ended and your business is now on the Free plan.',
                    business=sub.business,
                    action_url='/billing',
                )
                send_subscription_expired_email(
                    email=sub.business.owner.email,
                    first_name=sub.business.owner.first_name or 'there',
                    business_title=sub.business.title,
                    plan_name=expired_plan_name,
                )
                expired_count += 1

        due_posts = Post.objects.filter(status='scheduled', scheduled_for__lte=now)
        post_count = 0
        for post in due_posts:
            post.publish()
            post_count += 1

        self.stdout.write(self.style.SUCCESS(
            f'Done! {offer_count} offer(s), {campaign_count} campaign(s), {sub_count} subscription(s) reminded, '
            f'{expired_count} subscription(s) reverted to Free, {post_count} post(s) published.'
        ))
