import aiosmtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import os
import logging
from ...shared.config.settings import settings
from ...shared.config.database import SessionLocal
from ...system.models.system_settings import SystemSettings
logger = logging.getLogger(__name__)

def _get_smtp_settings_from_db():
    try:
        db = SessionLocal()
        try:
            smtp_settings = {}
            setting_keys = ['smtp_host', 'smtp_port', 'smtp_user', 'smtp_password', 'smtp_from_email', 'smtp_from_name', 'smtp_use_tls']
            for key in setting_keys:
                setting = db.query(SystemSettings).filter(SystemSettings.key == key).first()
                if setting and setting.value:
                    smtp_settings[key] = setting.value
            if smtp_settings.get('smtp_host') and smtp_settings.get('smtp_user') and smtp_settings.get('smtp_password'):
                return smtp_settings
            return None
        finally:
            db.close()
    except Exception as e:
        logger.debug(f'Could not fetch SMTP settings from database: {str(e)}')
        return None

async def send_email(to: str, subject: str, html: str=None, text: str=None):
    try:
        db_smtp_settings = _get_smtp_settings_from_db()
        if db_smtp_settings:
            mail_host = db_smtp_settings.get('smtp_host')
            mail_user = db_smtp_settings.get('smtp_user')
            mail_pass = db_smtp_settings.get('smtp_password')
            mail_port = int(db_smtp_settings.get('smtp_port', '587'))
            mail_use_tls = db_smtp_settings.get('smtp_use_tls', 'true').lower() == 'true'
            from_address = db_smtp_settings.get('smtp_from_email')
            from_name = db_smtp_settings.get('smtp_from_name', 'Hotel Booking')
            logger.info('Using SMTP settings from system_settings database')
        else:
            mail_host = settings.SMTP_HOST or os.getenv('MAIL_HOST')
            mail_user = settings.SMTP_USER or os.getenv('MAIL_USER')
            mail_pass = settings.SMTP_PASSWORD or os.getenv('MAIL_PASS')
            mail_port = settings.SMTP_PORT or int(os.getenv('MAIL_PORT', '587'))
            mail_secure = os.getenv('MAIL_SECURE', 'false').lower() == 'true'
            mail_use_tls = mail_secure
            client_url = settings.CLIENT_URL or os.getenv('CLIENT_URL', 'http://localhost:5173')
            from_address = settings.SMTP_FROM_EMAIL or os.getenv('MAIL_FROM')
            if not from_address:
                domain = client_url.replace('https://', '').replace('http://', '').split('/')[0]
                from_address = f'no-reply@{domain}'
            from_name = settings.SMTP_FROM_NAME or 'Hotel Booking'
            logger.info('Using SMTP settings from config/environment variables')
        from_header = f'{from_name} <{from_address}>'
        if not (mail_host and mail_user and mail_pass):
            error_msg = 'SMTP mailer not configured. Set SMTP_HOST, SMTP_USER and SMTP_PASSWORD in .env file.'
            logger.error(error_msg)
            raise ValueError(error_msg)
        message = MIMEMultipart('alternative')
        message['From'] = from_header
        message['To'] = to
        message['Subject'] = subject
        if text:
            message.attach(MIMEText(text, 'plain'))
        if html:
            message.attach(MIMEText(html, 'html'))
        if not text and (not html):
            message.attach(MIMEText('', 'plain'))
        if mail_port == 465 or mail_use_tls:
            use_tls = True
            start_tls = False
        elif mail_port == 587:
            use_tls = False
            start_tls = True
        else:
            use_tls = False
            start_tls = False
        logger.info(f'Attempting to send email to {to} via {mail_host}:{mail_port} (use_tls: {use_tls}, start_tls: {start_tls})')
        smtp_client = aiosmtplib.SMTP(hostname=mail_host, port=mail_port, use_tls=use_tls, start_tls=start_tls, username=mail_user, password=mail_pass)
        try:
            await smtp_client.connect()
            await smtp_client.send_message(message)
            logger.info(f'Email sent successfully to {to}')
        finally:
            await smtp_client.quit()
    except Exception as e:
        error_msg = f'Failed to send email to {to}: {type(e).__name__}: {str(e)}'
        logger.error(error_msg, exc_info=True)
        raise