"""
SMS Service using Twilio API for RateRight
Handles all SMS notifications for the platform
"""

from flask import current_app
import logging

logger = logging.getLogger(__name__)

# Twilio client - initialized lazily
_twilio_client = None


def init_twilio():
    """Initialize Twilio with credentials from config"""
    global _twilio_client

    account_sid = current_app.config.get('TWILIO_ACCOUNT_SID')
    auth_token = current_app.config.get('TWILIO_AUTH_TOKEN')

    if account_sid and auth_token:
        try:
            from twilio.rest import Client
            _twilio_client = Client(account_sid, auth_token)
            return True
        except ImportError:
            logger.warning("Twilio package not installed. Run: pip install twilio")
            return False
        except Exception as e:
            logger.error(f"Failed to initialize Twilio client: {e}")
            return False

    logger.warning("TWILIO credentials not configured. SMS sending will be logged only.")
    return False


def _get_twilio_client():
    """Get or initialize Twilio client"""
    global _twilio_client
    if _twilio_client is None:
        init_twilio()
    return _twilio_client


def format_australian_phone(phone_number: str) -> str:
    """
    Format Australian phone number to E.164 format (+614xxxxxxxx)

    Args:
        phone_number: Phone number in various formats

    Returns:
        E.164 formatted phone number or original if not Australian
    """
    if not phone_number:
        return None

    # Check if already in E.164 format before stripping
    if phone_number.startswith('+61') and len(phone_number) == 12:
        return phone_number

    # Remove all non-digit characters
    digits = ''.join(filter(str.isdigit, phone_number))

    # Handle Australian mobile numbers
    if digits.startswith('614') and len(digits) == 11:
        # Already in international format without +
        return f"+{digits}"
    elif digits.startswith('04') and len(digits) == 10:
        # Australian mobile starting with 04
        return f"+61{digits[1:]}"
    elif digits.startswith('4') and len(digits) == 9:
        # Australian mobile without leading 0
        return f"+61{digits}"

    # Return original if format not recognized
    logger.warning(f"Phone number format not recognized: {phone_number}")
    return phone_number


class SMSService:
    """SMS service using Twilio API"""

    # Welcome SMS templates (must be under 160 characters for single SMS)
    TEMPLATE_WELCOME_WORKER = (
        "Welcome to RateRight, {first_name}! "
        "Your account is ready. Find construction jobs that match your skills. "
        "Questions? Reply HELP."
    )

    TEMPLATE_WELCOME_CONTRACTOR = (
        "Welcome to RateRight, {first_name}! "
        "Post your first job and connect with skilled workers. "
        "Questions? Reply HELP."
    )

    @staticmethod
    def send_sms(to_phone: str, message: str) -> bool:
        """
        Send an SMS using Twilio

        Args:
            to_phone (str): Recipient phone number
            message (str): SMS message content (max 160 chars recommended)

        Returns:
            bool: True if SMS sent successfully, False otherwise
        """
        # Format phone number for Australian mobiles
        formatted_phone = format_australian_phone(to_phone)
        if not formatted_phone:
            logger.error("Cannot send SMS: No phone number provided")
            return False

        client = _get_twilio_client()
        if not client:
            logger.info(f"[SMS WOULD BE SENT] To: {formatted_phone}, Message: {message}")
            return False

        from_phone = current_app.config.get('TWILIO_PHONE_NUMBER')
        if not from_phone:
            logger.error("TWILIO_PHONE_NUMBER not configured")
            return False

        try:
            # Truncate message if too long (warn but still send)
            if len(message) > 160:
                logger.warning(f"SMS message exceeds 160 chars ({len(message)}), may be split into multiple segments")

            sms = client.messages.create(
                body=message,
                from_=from_phone,
                to=formatted_phone
            )

            logger.info(f"SMS sent successfully to {formatted_phone}. SID: {sms.sid}")
            return True

        except Exception as e:
            logger.error(f"Failed to send SMS to {formatted_phone}: {str(e)}")
            return False

    @staticmethod
    def send_welcome_sms_worker(user) -> bool:
        """
        Send welcome SMS to a new worker

        Args:
            user: User object with phone_number and first_name

        Returns:
            bool: True if SMS sent successfully, False otherwise
        """
        if not hasattr(user, 'phone_number') or not user.phone_number:
            logger.info(f"No phone number for user {user.id}, skipping welcome SMS")
            return False

        first_name = getattr(user, 'first_name', 'there') or 'there'
        message = SMSService.TEMPLATE_WELCOME_WORKER.format(first_name=first_name)

        return SMSService.send_sms(user.phone_number, message)

    @staticmethod
    def send_welcome_sms_contractor(user) -> bool:
        """
        Send welcome SMS to a new contractor

        Args:
            user: User object with phone_number and first_name

        Returns:
            bool: True if SMS sent successfully, False otherwise
        """
        if not hasattr(user, 'phone_number') or not user.phone_number:
            logger.info(f"No phone number for user {user.id}, skipping welcome SMS")
            return False

        first_name = getattr(user, 'first_name', 'there') or 'there'
        message = SMSService.TEMPLATE_WELCOME_CONTRACTOR.format(first_name=first_name)

        return SMSService.send_sms(user.phone_number, message)

    @staticmethod
    def send_notification_sms(user, notification_type: str, message: str) -> bool:
        """
        Send notification SMS to user

        Args:
            user: User object with phone_number
            notification_type: Type of notification for logging
            message: SMS message content

        Returns:
            bool: True if SMS sent successfully, False otherwise
        """
        if not hasattr(user, 'phone_number') or not user.phone_number:
            logger.info(f"No phone number for user {user.id}, skipping {notification_type} SMS")
            return False

        return SMSService.send_sms(user.phone_number, message)


# Create singleton instance
sms_service = SMSService()
