import logging
from celery import shared_task
from django.utils import timezone
from django.conf import settings
from django.core.mail import EmailMessage
from django.template.loader import get_template
from apps.appointments.models import OutboundMessage

logger = logging.getLogger(__name__)


@shared_task(
    bind=True,
    max_retries=3,
    default_retry_delay=30,
    name="apps.calls.tasks.email_task",
)
def send_email_task(
        self,
        subject: str,
        html_content: str,
        recipient_list: list,
        key: dict,
        files: list | None = None,
        bcc: list | None = None,
):
    delivery = OutboundMessage.objects.create(
        channel="email",
        to=",".join(recipient_list) if recipient_list else "",
        subject=subject,
        template_name=html_content,
        context=key,
        message_payload={
            "recipients": recipient_list,
            "bcc": bcc or [],
            "attachments": files or [],
        },
        status="pending",
    )

    try:
        try:
            message = get_template(html_content).render(key)
            delivery.message_payload["rendered_preview"] = message[:1000]
            delivery.save(update_fields=["message_payload"])
        except Exception as e:
            logger.warning("Error rendering email template: %s", str(e))
            message = html_content  # Fallback to raw content if template fails

        msg = EmailMessage(
            subject=subject,
            body=message,
            from_email=f"{settings.EMAIL_FROM_HEADER} <{settings.FROM_EMAIL}>",
            to=recipient_list,
            bcc=bcc or [],
        )

        msg.content_subtype = 'html'

        if files:
            for file in files:
                msg.attach_file(file)

        msg.send()
        delivery.status = "sent"
        delivery.sent_at = timezone.now()
        delivery.save(update_fields=["status", "sent_at"])
        logger.info("Email send to %s", recipient_list)

    except Exception as exc:
        delivery.status = "failed"
        delivery.error_message = str(exc)
        delivery.save(update_fields=["status", "error_message"])
        logger.error("Email failed to send to %s", exc)
        raise self.retry(exc=exc)
