"""
Survey Delivery Service - Sends surveys to patients via SMS/Email

This service handles:
- Generating secure survey URLs
- Sending SMS with survey links
- Sending emails with survey links
- Tracking delivery status

Uses NotificationService for all delivery operations.
"""

from django.conf import settings
from django.utils import timezone
import logging

logger = logging.getLogger(__name__)


class SurveyDeliveryService:
    """Service for delivering surveys to patients"""

    @staticmethod
    def generate_survey_url(survey_instance) -> str:
        """
        Generate secure survey URL with access token.

        Args:
            survey_instance: SurveyInstance object

        Returns:
            Full survey URL
        """
        base_url = getattr(settings, "SURVEY_BASE_URL", "http://localhost:8000")
        survey_path = survey_instance.get_survey_url()
        full_url = f"{base_url}{survey_path}"
        logger.info(f"Generated survey URL for {survey_instance.id}: {full_url}")
        return full_url

    @staticmethod
    def generate_sms_message(
        recipient_name: str,
        survey_url: str,
        hospital_name: str = None,
        hospital_name_ar: str = None,
        is_staff: bool = False,
        language: str = "en",
    ) -> str:
        """
        Generate SMS message with survey link.

        Args:
            recipient_name: Recipient's first name (patient or staff) - not used in new format
            survey_url: Survey link
            hospital_name: Hospital name (English)
            hospital_name_ar: Hospital name (Arabic)
            is_staff: Whether recipient is staff member - not used, same format for all
            language: Language code ('en' or 'ar') - not used, bilingual format for all

        Returns:
            SMS message text
        """
        facility = hospital_name or "our facility"
        facility_ar = hospital_name_ar or facility

        message = f"شكراً على زيارتك {facility_ar} والحمد لله على سلامتك\n\n"
        message += f"نتطلع لسماع رأيك حول تجربتك الأخيرة عبر الرابط التالي لنسهم في تحسين خدماتنا\n"
        message += f"{survey_url}\n\n"
        message += f"دمتم بصحة\n\n"
        message += "---\n\n"
        message += f"Thank you for choosing {facility}\n\n"
        message += f"Please help us improve the patient experience by telling us about your visit via this survey\n"
        message += f"{survey_url}\n\n"
        message += "We value your trust and look forward to receiving your invaluable feedback"

        return message

    @staticmethod
    def generate_email_message(
        recipient_name: str, survey_url: str, hospital_name: str = None, is_staff: bool = False
    ) -> str:
        """
        Generate email message with survey link.

        Args:
            recipient_name: Recipient's first name (patient or staff)
            survey_url: Survey link
            hospital_name: Optional hospital name
            is_staff: Whether recipient is staff member

        Returns:
            Email message text
        """
        message = f"Dear {recipient_name},\n\n"

        if hospital_name:
            message += f"Thank you for being part of {hospital_name}.\n\n"
        else:
            message += "Thank you for being part of our hospital.\n\n"

        if is_staff:
            message += "We value your feedback and would appreciate it if you could take a moment to complete our staff experience survey.\n\n"
            message += "Your feedback helps us improve our services and create a better work environment.\n\n"
        else:
            message += "We value your feedback and would appreciate it if you could take a moment to complete our patient experience survey.\n\n"
            message += "Your feedback helps us improve our services and provide better care for all our patients.\n\n"

        message += f"Survey Link: {survey_url}\n\n"
        message += "This survey will take approximately 2-3 minutes to complete.\n\n"
        message += "If you have any questions or concerns, please don't hesitate to contact us.\n\n"
        message += "Thank you for helping us improve our services!\n\n"

        if is_staff:
            message += "Best regards,\n"
            message += "Hospital Administration Team"
        else:
            message += "Best regards,\n"
            message += "Patient Experience Team"

        return message

    @staticmethod
    def send_survey_sms(survey_instance, language: str = "en") -> bool:
        """
        Send survey via SMS using NotificationService API.

        Args:
            survey_instance: SurveyInstance object
            language: Language code ('en' or 'ar')

        Returns:
            True if sent successfully, False otherwise
        """
        logger.info(
            f"Sending SMS for survey {survey_instance.id}, phone={survey_instance.recipient_phone}, language={language}"
        )

        if not survey_instance.recipient_phone:
            logger.warning(f"No phone number for survey {survey_instance.id}")
            return False

        try:
            # Generate survey URL and message
            survey_url = SurveyDeliveryService.generate_survey_url(survey_instance)
            full_name = survey_instance.get_recipient_name()
            recipient_name = full_name.split()[0] if full_name and full_name.strip() else "there"
            is_staff = survey_instance.staff is not None
            hospital_name = survey_instance.hospital.get_display_name() if survey_instance.hospital else None
            hospital_name_ar = survey_instance.hospital.get_display_name_ar() if survey_instance.hospital else None
            message = SurveyDeliveryService.generate_sms_message(
                recipient_name, survey_url, hospital_name, hospital_name_ar, is_staff, language
            )

            # Use NotificationService for delivery (supports API backend)
            from apps.notifications.services import NotificationService

            # Build metadata
            metadata = {
                "survey_id": str(survey_instance.id),
                "hospital_id": str(survey_instance.hospital.id),
                "is_staff_survey": is_staff,
            }

            if survey_instance.patient:
                metadata["patient_id"] = str(survey_instance.patient.id)
            if survey_instance.staff:
                metadata["staff_id"] = str(survey_instance.staff.id)

            # Send SMS via notification service (uses Mshastra if configured)
            notification_log = NotificationService.send_sms(
                phone=survey_instance.recipient_phone,
                message=message,
                related_object=survey_instance,
                metadata=metadata,
            )

            # Update survey instance based on notification status
            if notification_log and (notification_log.status == "sent" or notification_log.status == "pending"):
                from apps.surveys.models import SurveyStatus

                survey_instance.status = SurveyStatus.SENT
                survey_instance.sent_at = timezone.now()
                survey_instance.save(update_fields=["status", "sent_at"])
                logger.info(f"Survey SMS sent successfully to {survey_instance.recipient_phone}")
                return True
            else:
                logger.warning(f"Survey SMS delivery failed for {survey_instance.id}")
                return False

        except Exception as e:
            logger.error(f"Error sending SMS for survey {survey_instance.id}: {str(e)}", exc_info=True)
            return False

    @staticmethod
    def send_survey_email(survey_instance, language: str = "en") -> bool:
        """
        Send survey via Email using NotificationService API.

        Args:
            survey_instance: SurveyInstance object
            language: Language code ('en' or 'ar')

        Returns:
            True if sent successfully, False otherwise
        """
        logger.info(
            f"Sending Email for survey {survey_instance.id}, email={survey_instance.recipient_email}, language={language}"
        )

        if not survey_instance.recipient_email:
            logger.warning(f"No email address for survey {survey_instance.id}")
            return False

        try:
            # Generate survey URL and message
            survey_url = SurveyDeliveryService.generate_survey_url(survey_instance)
            full_name = survey_instance.get_recipient_name()
            recipient_name = full_name.split()[0] if full_name and full_name.strip() else "there"  # First name only
            is_staff = survey_instance.staff is not None
            hospital_name = survey_instance.hospital.get_display_name() if survey_instance.hospital else None
            message = SurveyDeliveryService.generate_email_message(recipient_name, survey_url, hospital_name, is_staff)

            # Use NotificationService for delivery (supports API backend)
            from apps.notifications.services import NotificationService

            # Build metadata
            metadata = {
                "survey_id": str(survey_instance.id),
                "hospital_id": str(survey_instance.hospital.id),
                "is_staff_survey": is_staff,
            }

            if survey_instance.patient:
                metadata["patient_id"] = str(survey_instance.patient.id)
            if survey_instance.staff:
                metadata["staff_id"] = str(survey_instance.staff.id)

            # Set email subject
            hospital_display = survey_instance.hospital.get_display_name() if survey_instance.hospital else ""
            if is_staff:
                subject = f"Staff Experience Survey - {hospital_display}"
            else:
                subject = f"Patient Experience Survey - {hospital_display}"

            # Try API first, fallback to regular email
            notification_log = NotificationService.send_email_via_api(
                message=message,
                email=survey_instance.recipient_email,
                subject=subject,
                html_message=None,  # Plain text for now
                related_object=survey_instance,
                metadata=metadata,
            )

            # If API is disabled or failed, fallback to regular send_email
            if notification_log is None:
                logger.info("Email API disabled or returned None, falling back to regular email")
                notification_log = NotificationService.send_email(
                    email=survey_instance.recipient_email,
                    subject=subject,
                    message=message,
                    related_object=survey_instance,
                    metadata=metadata,
                )

            # Update survey instance based on notification status
            if notification_log and (notification_log.status == "sent" or notification_log.status == "pending"):
                from apps.surveys.models import SurveyStatus

                survey_instance.status = SurveyStatus.SENT
                survey_instance.sent_at = timezone.now()
                survey_instance.save(update_fields=["status", "sent_at"])
                logger.info(f"Survey email sent successfully to {survey_instance.recipient_email}")
                return True
            else:
                logger.warning(f"Survey email delivery failed for {survey_instance.id}")
                return False

        except Exception as e:
            logger.error(f"Error sending email for survey {survey_instance.id}: {str(e)}")
            return False

    @staticmethod
    def deliver_survey(survey_instance, language: str = None) -> bool:
        """
        Deliver survey based on configured delivery channel.

        Args:
            survey_instance: SurveyInstance object
            language: Language code ('en' or 'ar') - if not provided, auto-detect from patient

        Returns:
            True if delivered successfully, False otherwise
        """
        logger.info(
            f"Delivering survey {survey_instance.id}, channel={survey_instance.delivery_channel}, phone={survey_instance.recipient_phone}"
        )

        # Auto-detect language from patient if not provided
        if not language and survey_instance.patient:
            language = getattr(survey_instance.patient, "preferred_language", "en")

        # Normalize delivery channel to lowercase for comparison
        delivery_channel = (survey_instance.delivery_channel or "").lower()

        # Get recipient (patient or staff)
        recipient = survey_instance.get_recipient()
        logger.info(f"Survey {survey_instance.id} recipient: {recipient}")

        # Ensure contact info is set
        if delivery_channel == "sms":
            if recipient:
                survey_instance.recipient_phone = survey_instance.recipient_phone or recipient.phone
            logger.info(f"Survey {survey_instance.id} SMS - recipient_phone: {survey_instance.recipient_phone}")
        elif delivery_channel == "email":
            if recipient:
                survey_instance.recipient_email = survey_instance.recipient_email or getattr(recipient, "email", None)

        # Save contact info
        survey_instance.save()

        # Send based on channel
        if delivery_channel == "sms":
            return SurveyDeliveryService.send_survey_sms(survey_instance, language=language)
        elif delivery_channel == "email":
            return SurveyDeliveryService.send_survey_email(survey_instance, language=language)
        elif delivery_channel == "whatsapp":
            return SurveyDeliveryService.send_survey_whatsapp(survey_instance, language=language)
        else:
            logger.error(f"Unknown delivery channel: {survey_instance.delivery_channel}")
            return False

    @staticmethod
    def send_survey_whatsapp(survey_instance, language: str = "en") -> bool:
        """
        Send survey via WhatsApp using NotificationService API.

        Args:
            survey_instance: SurveyInstance object
            language: Language code ('en' or 'ar')

        Returns:
            True if sent successfully, False otherwise
        """
        logger.info(f"Sending WhatsApp for survey {survey_instance.id}, phone={survey_instance.recipient_phone}")

        if not survey_instance.recipient_phone:
            logger.warning(f"No phone number for WhatsApp survey {survey_instance.id}")
            return False

        try:
            # Generate survey URL and message
            survey_url = SurveyDeliveryService.generate_survey_url(survey_instance)
            full_name = survey_instance.get_recipient_name()
            recipient_name = full_name.split()[0] if full_name and full_name.strip() else "there"
            is_staff = survey_instance.staff is not None
            hospital_name = survey_instance.hospital.get_display_name() if survey_instance.hospital else None
            hospital_name_ar = survey_instance.hospital.get_display_name_ar() if survey_instance.hospital else None

            if language == "ar":
                facility = hospital_name_ar or hospital_name or "our facility"
                message = f"مرحباً {recipient_name}،\n\n"
                if facility:
                    message += f"شكراً لكونك جزءاً من {facility}. "
                if is_staff:
                    message += "نقدر ملاحظاتك! يرجى إكمال استبيان تجربة الموظفين:\n\n"
                else:
                    message += "نقدر ملاحظاتك! يرجى إكمال استبيان تجربة المريض:\n\n"
                message += f"{survey_url}\n\n"
                message += "سيستغرق هذا الاستبيان حوالي 2-3 دقائق."
            else:
                facility = hospital_name or "our facility"
                message = f"Hello {recipient_name},\n\n"
                if facility:
                    message += f"Thank you for being part of {facility}. "
                if is_staff:
                    message += "We value your feedback! Please complete our staff experience survey:\n\n"
                else:
                    message += "We value your feedback! Please complete our patient experience survey:\n\n"
                message += f"{survey_url}\n\n"
                message += "This survey will take approximately 2-3 minutes."

            # Use NotificationService for WhatsApp delivery
            from apps.notifications.services import NotificationService

            metadata = {
                "survey_id": str(survey_instance.id),
                "hospital_id": str(survey_instance.hospital.id) if survey_instance.hospital else None,
                "is_staff_survey": is_staff,
                "channel": "whatsapp",
            }

            if survey_instance.patient:
                metadata["patient_id"] = str(survey_instance.patient.id)
            if survey_instance.staff:
                metadata["staff_id"] = str(survey_instance.staff.id)

            notification_log = NotificationService.send_whatsapp(
                phone=survey_instance.recipient_phone,
                message=message,
                related_object=survey_instance,
                metadata=metadata,
            )

            # Update survey instance based on notification status
            if notification_log and (notification_log.status == "sent" or notification_log.status == "pending"):
                from apps.surveys.models import SurveyStatus

                survey_instance.status = SurveyStatus.SENT
                survey_instance.sent_at = timezone.now()
                survey_instance.save(update_fields=["status", "sent_at"])
                logger.info(f"Survey WhatsApp sent successfully to {survey_instance.recipient_phone}")
                return True
            else:
                logger.warning(f"Survey WhatsApp delivery failed for {survey_instance.id}")
                return False

        except Exception as e:
            logger.error(f"Error sending WhatsApp for survey {survey_instance.id}: {str(e)}", exc_info=True)
            return False
