import logging

from celery import shared_task
from django.utils import timezone

logger = logging.getLogger(__name__)


@shared_task
def process_scheduled_reports():
    from apps.reports.models import ReportSchedule

    now = timezone.now()

    for schedule in ReportSchedule.objects.filter(is_active=True, next_run_at__isnull=True):
        schedule.next_run_at = schedule.calculate_next_run()
        if schedule.next_run_at:
            schedule.save(update_fields=["next_run_at"])

    schedules = ReportSchedule.objects.filter(
        is_active=True,
        next_run_at__lte=now,
    ).select_related("report")

    dispatched = 0
    for schedule in schedules:
        generate_and_deliver_report.delay(str(schedule.id))
        dispatched += 1

    logger.info(f"Dispatched {dispatched} scheduled reports")
    return {"dispatched": dispatched}


@shared_task
def generate_and_deliver_report(schedule_id):
    from apps.reports.models import ReportSchedule, GeneratedReport
    from apps.reports.services import ReportBuilderService
    from apps.notifications.services import NotificationService, get_email_header_html

    try:
        schedule = ReportSchedule.objects.select_related("report").get(id=schedule_id)
    except ReportSchedule.DoesNotExist:
        logger.error(f"ReportSchedule {schedule_id} not found")
        return {"status": "error", "reason": "not_found"}

    try:
        report = schedule.report

        report_data = ReportBuilderService.generate_report_data(
            data_source=report.data_source,
            filter_config=report.filter_config,
            column_config=report.column_config,
            grouping_config=report.grouping_config,
            sort_config=report.sort_config,
        )
        summary = ReportBuilderService.generate_summary(
            data_source=report.data_source,
            filter_config=report.filter_config,
        )

        row_count = len(report_data.get("rows", []))

        generated = GeneratedReport.objects.create(
            saved_report=report,
            name=report.name,
            data_source=report.data_source,
            filter_config=report.filter_config,
            column_config=report.column_config,
            grouping_config=report.grouping_config,
            chart_config=report.chart_config,
            data=report_data,
            summary=summary,
            chart_data={},
            row_count=row_count,
            hospital=report.hospital,
        )

        report.last_run_at = timezone.now()
        report.last_run_count = row_count
        report.save(update_fields=["last_run_at", "last_run_count"])

        schedule.last_run_at = timezone.now()
        schedule.last_error = ""

        next_run = schedule.calculate_next_run()
        if schedule.frequency == "once":
            schedule.is_active = False
            schedule.next_run_at = None
        else:
            schedule.next_run_at = next_run

        schedule.save(update_fields=["last_run_at", "next_run_at", "is_active", "last_error"])

        subject = f"Scheduled Report: {report.name}"
        message = (
            f"Report: {report.name}\n"
            f"Data Source: {report.get_data_source_display()}\n"
            f"Rows: {row_count}\n"
            f"Generated: {timezone.now().strftime('%Y-%m-%d %H:%M')}\n\n"
            f"View the full report in the PX360 dashboard."
        )

        for recipient in schedule.recipients:
            try:
                NotificationService.send_email(
                    email=recipient,
                    subject=subject,
                    message=message,
                    related_object=generated,
                    notification_type="report",
                    html_message=f"""
<div style="font-family: 'Segoe UI', Tahoma, sans-serif; max-width: 600px; margin: 0 auto; border: 1px solid #e5e7eb; border-radius: 8px; overflow: hidden;">
    {get_email_header_html()}
    <div style="padding: 20px;">
        <h2 style="color: #005696; font-size: 18px; margin: 0 0 12px 0;">Scheduled Report: {report.name}</h2>
        <table style="width: 100%; border-collapse: collapse; margin: 0 0 12px 0;">
            <tr><td style="padding: 4px 0; color: #6b7280; width: 140px;">Data Source:</td><td style="padding: 4px 0;">{report.get_data_source_display()}</td></tr>
            <tr><td style="padding: 4px 0; color: #6b7280;">Rows:</td><td style="padding: 4px 0;">{row_count}</td></tr>
            <tr><td style="padding: 4px 0; color: #6b7280;">Generated:</td><td style="padding: 4px 0;">{timezone.now().strftime('%Y-%m-%d %H:%M')}</td></tr>
        </table>
        <p style="margin: 0; color: #6b7280;">View the full report in the PX360 dashboard.</p>
    </div>
</div>
""",
                )
            except Exception as email_err:
                logger.error(f"Failed to send report email to {recipient}: {email_err}")

        logger.info(f"Generated and delivered report for schedule {schedule_id}")
        return {"status": "success", "generated_report_id": str(generated.id), "row_count": row_count}

    except Exception as e:
        error_msg = str(e)
        logger.error(f"Error generating report for schedule {schedule_id}: {error_msg}", exc_info=True)

        schedule.last_error = error_msg
        schedule.save(update_fields=["last_error"])

        return {"status": "error", "reason": error_msg}
