import time
import brevo_python
from brevo_python.rest import ApiException
from pprint import pprint
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import ssl
from models import Payment, PaymentDetails, Course, EventPayment, Parent, Participant
from sqlalchemy.orm import joinedload

def send_email(to_name,to_email_id,content):


    configuration = brevo_python.Configuration()
    configuration.api_key['api-key'] = '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'

    configuration.api_key['partner-key'] = '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'

    # create an instance of the API class
    api_instance = brevo_python.TransactionalEmailsApi(brevo_python.ApiClient(configuration))
    subject = "Order Confirmation"
    html_content = content
    sender = {"name":"WAC", "email": "noreply@aatoon.com"}
    to = [{"email": to_email_id, "name": to_name}]
    bcc = [{"name": "John Doe", "email": "example@example.com"}]
    reply_to = {"email": "noreply@aatoon.com", "name": "WAC"}
    headers = {"Some-Custom-Name": "unique-id-1234"}
    params = {"parameter": "My param value", "subject": "New Subject"}

    send_smtp_email = brevo_python.SendSmtpEmail(to=to, reply_to=reply_to, headers=headers, html_content=html_content,
                                                 sender=sender, subject=subject)

    try:
        # Get your account information, plan and credits details
        api_response = api_instance.send_transac_email(send_smtp_email)
        pprint(api_response)
    except ApiException as e:
        print("Exception when calling AccountApi->get_account: %s\n" % e)


def send_order_summary_email(payment_id: str):
    """
    Dependency function to send order summary email using payment ID
    """
    from jinja2 import Template
    import os
    from collections import defaultdict
    
    # Load email template first (outside session to avoid keeping session open)
    template_path = os.path.join(os.path.dirname(__file__), '../templates/order_purchase.html')
    with open(template_path, 'r') as file:
        template_content = file.read()
    
    template = Template(template_content)
    
    # Get payment details and prepare all data within session context
    from core.config import get_db
    from models.parent import Parent
    from models.participant import Participant
    
    with get_db() as db:
        payment = db.query(Payment).filter(
                Payment.id == payment_id
            ).first()
        
        # Eager load the required relationships including participant
        payment_details = db.query(PaymentDetails).\
            filter(PaymentDetails.payment_id == payment_id).\
            options(
                joinedload(PaymentDetails.course).joinedload(Course.time_slot),
                joinedload(PaymentDetails.purchased_participant)  # Use your relationship name
            ).\
            all()
        
        # Determine recipient email based on user_type
        to_email = None
        to_name = None
        
        if payment:
            if payment.user_type == 'parent':
                # Fetch parent using payment.created_by
                parent = db.query(Parent).filter(Parent.id == payment.created_by).first()
                if parent:
                    to_email = parent.email
                    to_name = parent.full_name
            elif payment.user_type == 'participant':
                # Fetch participant using payment.created_by
                participant = db.query(Participant).filter(Participant.id == payment.created_by).first()
                if participant:
                    to_email = participant.email
                    to_name = participant.full_name
        
        # If no email found, use default
        if not to_email:
            to_email = "tinspj1997@gmail.com"
            to_name = "John Doe"
        
        # Group courses by participant
        participant_courses = defaultdict(list)
        total_amount = 0
        total_discount = 0
        
        for detail in payment_details:
            course = detail.course
            time_slot = course.time_slot if course else None
            
            # Get participant information using your relationship name
            participant = detail.purchased_participant
            participant_id = detail.purchased_for_id
            participant_name = 'Unknown Participant'
            
            if participant:
                # Build full name from first_name and last_name
                participant_name = f"{participant.first_name} {participant.last_name}".strip()
                # Fallback to just first_name if last_name is empty
                if not participant_name or participant_name == ' ':
                    participant_name = participant.first_name or 'Unknown Participant'
            
            # Format course dates
            course_dates = 'To be determined'
            if course and course.start_date and course.end_date:
                course_dates = f"{course.start_date.strftime('%Y-%m-%d')} to {course.end_date.strftime('%Y-%m-%d')}"
            
            # Format course times
            course_times = 'To be determined'
            if time_slot:
                course_times = time_slot.title
            elif course and course.start_time and course.end_time:
                course_times = f"{course.start_time.strftime('%I:%M %p')} - {course.end_time.strftime('%I:%M %p')}"
            
            # Add course to participant's list
            participant_courses[participant_id].append({
                'participant_name': participant_name,
                'course_name': course.name if course else 'Unknown Course',
                'date': course_dates,
                'time': course_times,
                'actual_price': f"£{detail.course_original_amount:.2f}",
                'final_price': f"£{detail.final_amount:.2f}"
            })
            
            total_amount += detail.course_original_amount
            total_discount += (detail.course_original_amount - detail.final_amount)
        
        # Convert to list format for template
        participant_data = []
        for participant_id, courses in participant_courses.items():
            participant_data.append({
                'participant_name': courses[0]['participant_name'],  # Get name from first course
                'courses': courses
            })
    
    # Now render the template outside the session
    html_content = template.render(
        order_id=payment.transaction_batch_id if payment else 'N/A',
        date=payment.paid_on.strftime('%Y-%m-%d') if payment and payment.paid_on else 'N/A',
        time=payment.paid_on.strftime('%H:%M') if payment and payment.paid_on else 'N/A',
        participant_data=participant_data,  # Changed from course_data
        total_amount=f"£{total_amount:.2f}",
        total_discount=f"£{total_discount:.2f}",
        total_paid_amount=f"£{payment.total_paid_amount:.2f}" if payment else 'N/A'
    )
    
    send_email(to_name, to_email, html_content)
    return {"message": "Order summary email sent successfully", "payment_id": payment_id}


def send_event_order_summary_email(event_payment_id: str):
    """
    Send event order summary email using event payment ID
    """
    from jinja2 import Template
    import os
    
    # Load event-specific email template
    template_path = os.path.join(os.path.dirname(__file__), '../templates/event_purchase.html')
    with open(template_path, 'r') as file:
        template_content = file.read()
    
    template = Template(template_content)
    
    # Get event payment details and prepare all data within session context
    from core.config import get_db
    from models import Event, EventCart
    
    with get_db() as db:
        event_payment = db.query(EventPayment).filter(
            EventPayment.id == event_payment_id
        ).first()
        
        # Get event carts for this transaction
        event_carts = db.query(EventCart).filter(
            EventCart.transaction_batch_id == event_payment.transaction_batch_id
        ).options(joinedload(EventCart.event)).all()
        
        # Determine recipient email based on user_type
        to_email = None
        to_name = None
        
        if event_payment:
            if event_payment.user_type == 'parent':
                parent = db.query(Parent).filter(Parent.id == event_payment.user_id).first()
                if parent:
                    to_email = parent.email
                    to_name = f"{parent.first_name} {parent.last_name}"
            elif event_payment.user_type == 'participant':
                participant = db.query(Participant).filter(Participant.id == event_payment.user_id).first()
                if participant:
                    to_email = participant.email
                    to_name = f"{participant.first_name} {participant.last_name}"
        
        # If no email found, use default
        if not to_email:
            to_email = "tinspj1997@gmail.com"
            to_name = "John Doe"
        
        # Prepare template data within session context
        event_data = []
        total_amount = 0
        
        for cart in event_carts:
            event = cart.event
            if event:
                event_data.append({
                    'name': event.name,
                    'date': f"{event.event_start_date.strftime('%Y-%m-%d')} to {event.event_end_date.strftime('%Y-%m-%d')}" if event.event_start_date and event.event_end_date else 'To be determined',
                    'time': f"{event.event_start_time} - {event.event_end_time}" if event.event_start_time and event.event_end_time else 'To be determined',
                    'final_price': f"£{event.price}"
                })
                total_amount += event.price
        
    # Now render the template outside the session
    html_content = template.render(
        order_id=event_payment.transaction_batch_id if event_payment else 'N/A',
        date=event_payment.paid_on.strftime('%Y-%m-%d') if event_payment and event_payment.paid_on else 'N/A',
        time=event_payment.paid_on.strftime('%H:%M') if event_payment and event_payment.paid_on else 'N/A',
        course_data=event_data,
        total_amount=f"£{total_amount}",
        total_discount="£0.00",
        total_paid_amount=f"£{event_payment.total_amount}" if event_payment else 'N/A'
    )
    
    send_email(to_name, to_email, html_content)
    return {"message": "Event order summary email sent successfully", "event_payment_id": event_payment_id}


def send_email_smtp(to_name: str, to_email: str, subject: str, html_content: str) -> dict:
    """
    Send email using Brevo SMTP with HTML content
    
    Args:
        to_name: Recipient name
        to_email: Recipient email address
        subject: Email subject
        html_content: HTML content of the email
    
    Returns:
        dict: Status of the email sending operation
    """
    # SMTP Configuration
    smtp_server = "smtp-relay.brevo.com"
    smtp_port = 587
    smtp_username = "7383c9001@smtp-brevo.com"
    smtp_password = "kxqgrBLjdYAw9WnP"
    
    # Email setup
    msg = MIMEMultipart('alternative')
    msg['Subject'] = subject
    msg['From'] = "WAC <noreply@aatoon.com>"
    msg['To'] = f"{to_name} <{to_email}>"
    
    # Create HTML part
    html_part = MIMEText(html_content, 'html')
    msg.attach(html_part)
    
    try:
        # Create SSL context with certificate verification disabled
        context = ssl.create_default_context()
        context.check_hostname = False
        context.verify_mode = ssl.CERT_NONE
        
        # Connect to SMTP server with proper SSL handling
        with smtplib.SMTP(smtp_server, smtp_port) as server:
            server.ehlo()  # Identify ourselves to the SMTP server
            server.starttls(context=context)  # Secure the connection
            server.ehlo()  # Re-identify ourselves over TLS connection
            server.login(smtp_username, smtp_password)
            server.send_message(msg)
        
        return {
            "status": "success",
            "message": "Email sent successfully",
            "recipient": to_email
        }
        
    except Exception as e:
        return {
            "status": "error",
            "message": f"Failed to send email: {str(e)}",
            "recipient": to_email
        }


