"""
Send scheduled stock/sales summary emails to registered recipients via Resend.

Intended to run every 5-15 minutes (or at least hourly) via cron (no Celery/beat needed). Each recipient has a
send time (hour + minute, evaluated in the time zone saved in Settings); the first run at or after
that time on a day matching their frequency sends one report, capped at max_emails_per_day.

Usage:
    python manage.py send_scheduled_reports --dry-run
    python manage.py send_scheduled_reports --test-to you@example.com   # verify Resend setup
    python manage.py send_scheduled_reports
"""
from django.core.management.base import BaseCommand, CommandError
from django.utils import timezone

from email_reports.models import ScheduledReportLog, ScheduledReportRecipient
from email_reports.services import EmailSendError, compose_summary_email, get_zone, is_due, send_test_email, send_via_resend, sends_today_count


class Command(BaseCommand):
    help = 'Send scheduled stock/sales summary emails. Use --dry-run to preview, --test-to to check the Resend setup.'

    def add_arguments(self, parser):
        parser.add_argument(
            '--test-to', metavar='EMAIL',
            help='Send a single test email to EMAIL and exit (checks RESEND_API_KEY / RESEND_FROM_EMAIL).',
        )
        parser.add_argument(
            '--dry-run', action='store_true',
            help='Compose and log what would be sent, without calling the Resend API.',
        )

    def handle(self, *args, **options):
        if options['test_to']:
            try:
                message_id = send_test_email(options['test_to'])
            except EmailSendError as exc:
                raise CommandError(f'Test email failed: {exc}')
            self.stdout.write(self.style.SUCCESS(f"Test email sent to {options['test_to']} (Resend id {message_id})."))
            return

        dry_run = options['dry_run']
        zone = get_zone()
        now = timezone.now().astimezone(zone)
        today = now.date()

        recipients = ScheduledReportRecipient.objects.filter(enabled=True)
        due = [r for r in recipients if is_due(r, now)]

        self.stdout.write(f'{len(recipients)} enabled recipient(s), {len(due)} due now ({now:%Y-%m-%d %H:%M} {zone.key}).')

        sent, skipped, failed = 0, 0, 0
        for recipient in due:
            already_sent = sends_today_count(recipient, today)
            if already_sent >= recipient.max_emails_per_day:
                self.stdout.write(f'  skip {recipient.email}: daily cap reached ({already_sent}/{recipient.max_emails_per_day})')
                skipped += 1
                continue

            period = 'today' if recipient.frequency == recipient.Frequency.DAILY else (
                'this_week' if recipient.frequency == recipient.Frequency.WEEKLY else 'this_month'
            )
            try:
                with timezone.override(zone):
                    subject, html = compose_summary_email(period)
            except Exception as exc:  # one bad report must not stop the other recipients
                ScheduledReportLog.objects.create(recipient=recipient, success=False, detail=f'compose failed: {exc}'[:255])
                self.stdout.write(self.style.ERROR(f'  failed for {recipient.email}: could not build report ({exc})'))
                failed += 1
                continue

            if dry_run:
                self.stdout.write(f'  [dry-run] would send to {recipient.email}: "{subject}"')
                sent += 1
                continue

            try:
                send_via_resend(recipient.email, subject, html)
                ScheduledReportLog.objects.create(recipient=recipient, success=True, detail=subject[:255])
                self.stdout.write(self.style.SUCCESS(f'  sent to {recipient.email}'))
                sent += 1
            except EmailSendError as exc:
                ScheduledReportLog.objects.create(recipient=recipient, success=False, detail=str(exc)[:255])
                self.stdout.write(self.style.ERROR(f'  failed for {recipient.email}: {exc}'))
                failed += 1

        self.stdout.write(f'Done: {sent} sent, {skipped} skipped, {failed} failed.')
