import csv
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
from reportlab.lib import colors
from reportlab.lib.units import inch
from reportlab.lib.utils import ImageReader
import qrcode
from PIL import Image
import os
import io
import logging
from dotenv import load_dotenv
import requests
import json
import uuid
import base64
import urllib.parse

# Load environment variables
load_dotenv()

# Infobip API settings
INFOBIP_API_KEY = os.getenv('INFOBIP_API_KEY')
# Use hardcoded sender number in E.164 format
INFOBIP_WHATSAPP_SENDER = "447860088970"

# Format title and name for the message
def format_greeting(title, name):
    # If title contains 'Mr & Mrs', format it as a single unit
    if "&" in title:
        return f"Dear {title} {name.split()[0]}"
    # For single titles, format as "Dear Mr. Edmund"
    return f"Dear {title}. {name.split()[0]}"

# Create message template with formatted greeting
MESSAGE_TEMPLATE = "{greeting},\n\nHere is your wedding invitation e-vite. Please save it and present it at the event.\n\nBest regards,\nWedding Organizers"

# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# Send WhatsApp document message using Infobip API
def send_whatsapp_document(phone, name, title, pdf_path):
    """Send WhatsApp document message using Infobip API."""
    try:
        # Format message
        greeting = format_greeting(title, name)
        # Format message as a single line without newlines
        message = MESSAGE_TEMPLATE.format(greeting=greeting).replace('\n', ' ').strip()
        
        # Prepare the API request
        headers = {
            'Authorization': f'App {INFOBIP_API_KEY}',
            'Content-Type': 'application/json',
            'Accept': 'application/json'
        }

        # Use sender number from environment variable and ensure proper formatting
        sender_number = INFOBIP_WHATSAPP_SENDER
        logger.info(f"Using sender number: {sender_number}")
        import uuid
        message_id = str(uuid.uuid4())
        
        # Create the message payload
        payload = {
            "messages": [
                {
                    "from": sender_number,
                    "to": phone,
                    "messageId": message_id,
                    "content": {
                        "filename": "evite.pdf",
                        "caption": message,
                        "mediaUrl": f"https://events.angstrom-technologies.ug/{name.replace(' ', '_')}_evite.pdf"
                    }
                }
            ]
        }
        logger.info(payload)
        
        # Send the message
        response = requests.post(
            "https://yp936p.api.infobip.com/whatsapp/1/message/document",
            headers=headers,
            json=payload
        )
        
        if response.status_code == 200:
            logger.info(f"Successfully sent document to {phone}")
            logger.info(response.json())
        else:
            logger.error(f"Failed to send document to {phone}: {response.text}")
            
    except Exception as e:
        logger.error(f"Error sending WhatsApp document to {phone}: {str(e)}")
        raise

# Send SMS message using Infobip API
def send_sms(phone, name, title, download_url):
    """Send SMS message using Infobip API."""
    try:
        # Format message with download URL
        greeting = format_greeting(title, name)
        url = download_url
        message = f"{greeting},\n\nHere is your wedding invitation e-vite. Please save it and present it at the event.\n\nE-vite URL: {url}\n\nBest regards,\nWedding Organizers".replace('\n', ' ').strip()
        
        # Prepare the API request
        headers = {
            'Authorization': f'App {INFOBIP_API_KEY}',
            'Content-Type': 'application/json',
            'Accept': 'application/json'
        }

        # Create the message payload
        payload = {
            "messages": [
                {
                    "destinations": [{"to": phone}],
                    "from": "12036358403",
                    "text": message
                }
            ]
        }
        logger.info(f"Sending SMS to {phone}")
        logger.info(f"SMS payload: {payload}")
        
        # Send the message
        response = requests.post(
            "https://yp936p.api.infobip.com/sms/2/text/advanced",
            headers=headers,
            json=payload
        )
        
        if response.status_code == 200:
            logger.info(f"Successfully sent SMS to {phone}")
            logger.info(response.json())
        else:
            logger.error(f"Failed to send SMS to {phone}: {response.text}")
            logger.error(f"Response status code: {response.status_code}")
            logger.error(f"Response content: {response.content}")
            
    except Exception as e:
        logger.error(f"Error sending SMS to {phone}: {str(e)}")
        raise

# Send WhatsApp text message using Infobip API
def send_whatsapp_text(phone, name, title):
    """Send WhatsApp text message using Infobip API."""
    try:
        # Prepare the API request
        headers = {
            'Authorization': f'App {INFOBIP_API_KEY}',
            'Content-Type': 'application/json',
            'Accept': 'application/json'
        }

        # Use sender number from environment variable and ensure proper formatting
        sender_number = INFOBIP_WHATSAPP_SENDER
        if not sender_number.startswith('+'):
            sender_number = '+' + sender_number
        logger.info(f"Using sender number: {sender_number}")
        import uuid
        message_id = str(uuid.uuid4())
        
        # Create the message payload
        payload = {
            "messages": [
                {
                    "from": sender_number,
                    "to": phone,
                    "messageId": message_id,
                    "content": {
                        "text": f"Hello, Please RSVP for {name}_Wedding to receive your invite"
                    }
                }
            ]
        }
        logger.info(payload)
        
        # Send the message
        response = requests.post(
            "https://yp936p.api.infobip.com/whatsapp/1/message/text",
            headers=headers,
            json=payload
        )
        
        if response.status_code == 200:
            logger.info(f"Successfully sent text message to {phone}")
            logger.info(response.json())
        else:
            logger.error(f"Failed to send text message to {phone}: {response.text}")
            logger.error(f"Response status code: {response.status_code}")
            logger.error(f"Response content: {response.content}")
            
    except Exception as e:
        logger.error(f"Error sending WhatsApp text to {phone}: {str(e)}")
        raise

        import uuid
        message_id = str(uuid.uuid4())
        
        # Create the message payload
        payload = {
            "from": INFOBIP_WHATSAPP_SENDER,
            "to": phone,
            "messageId": message_id,
            "entityId":"evenzon3",
            "applicationId": "evenzon3",
            "content": {
                "text": f"Hello, Please RSVP for {name}_Wedding to receive your invite"
            },
            "callbackData": "Callback data",
            "notifyUrl": "https://events.angstrom-technologies.ug/infobip_webhook.php",
            "urlOptions": {
                "shortenUrl": True,
                "trackClicks": True,
                "trackingUrl": "https://events.angstrom-technologies.ug/infobip_webhook.php",
                "removeProtocol": True
            }
        }
        logger.info(payload)
        
        # Send the message
        response = requests.post(
            "https://yp936p.api.infobip.com/whatsapp/1/message/text",
            headers=headers,
            json=payload
        )
        
        if response.status_code == 200:
            logger.info(f"Successfully sent text message to {phone}")
            logger.info(response.json())
        else:
            logger.error(f"Failed to send text message to {phone}: {response.text}")
            
    except Exception as e:
        logger.error(f"Error sending WhatsApp text to {phone}: {str(e)}")
        raise



# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# Wedding event details
EVENT_TITLE = "EDMUND WEDS JUDITH"
EVENT_DATE = "Sat 30th Aug 2025 15:30 - 23:59 (EAT)"
EVENT_LOCATION = "Kigo Gardens, Kigo Road, Kampala, Uganda"

# PDF dimensions
PAGE_WIDTH, PAGE_HEIGHT = letter
MARGIN = inch * 0.5

# Color settings
TEXT_COLOR = colors.Color(0.373, 0.529, 0.678)  # #5F87AD in RGB

def generate_pdf(name, title, phone, admits, output_path):
    """Generate a PDF e-vite."""
    try:
        # Generate UUID
        evite_uuid = str(uuid.uuid4())
        
        # Create canvas
        c = canvas.Canvas(output_path, pagesize=letter)
        
        # Set font sizes
        title_font_size = 36
        section_font_size = 18
        detail_font_size = 14
        
        # Set text color
        c.setFillColor(TEXT_COLOR)
        
        # Draw title
        c.setFont("Helvetica-Bold", title_font_size)
        c.drawCentredString(PAGE_WIDTH/2, PAGE_HEIGHT - MARGIN - title_font_size, EVENT_TITLE)
        
        # Draw ticket holder section
        y = PAGE_HEIGHT - MARGIN - title_font_size - 40
        c.setFont("Helvetica-Bold", section_font_size)
        c.drawString(MARGIN, y, "TICKET HOLDER")
        
        y -= 30
        c.setFont("Helvetica", detail_font_size)
        c.drawString(MARGIN, y, f"{title} {name}")
        y -= 20
        c.drawString(MARGIN, y, f"Phone: {phone}")
        
        # Draw date and time
        y -= 40
        c.setFont("Helvetica-Bold", section_font_size)
        c.drawString(MARGIN, y, "DATE & TIME:")
        y -= 20
        c.setFont("Helvetica", detail_font_size)
        c.drawString(MARGIN, y, EVENT_DATE)
        
        # Draw location
        y -= 40
        c.setFont("Helvetica-Bold", section_font_size)
        c.drawString(MARGIN, y, "LOCATION:")
        y -= 20
        c.setFont("Helvetica", detail_font_size)
        c.drawString(MARGIN, y, EVENT_LOCATION)
        
        # Draw admits
        y -= 40
        c.setFont("Helvetica-Bold", section_font_size)
        c.drawString(MARGIN, y, "ADMIT:")
        y -= 20
        c.setFont("Helvetica", detail_font_size)
        c.drawString(MARGIN, y, f"{admits} person(s)")
        
        # Create QR code with verification URL
        verify_data = f"{title}:{name}:{phone}:{evite_uuid}"
        verify_url = f"https://events.angstrom-technologies.ug/evite/verify/{base64.urlsafe_b64encode(verify_data.encode()).decode()}"
        
        qr = qrcode.QRCode(
            version=1,
            error_correction=qrcode.constants.ERROR_CORRECT_L,
            box_size=10,
            border=4,
        )
        qr.add_data(verify_url)
        qr.make(fit=True)
        qr_img = qr.make_image(fill_color="black", back_color="white")
        
        # Convert PIL image to bytes
        qr_bytes = io.BytesIO()
        qr_img.save(qr_bytes, format='PNG')
        qr_bytes.seek(0)
        
        # Convert to ReportLab image
        qr_reportlab = ImageReader(qr_bytes)
        
        # Draw QR code
        qr_x = PAGE_WIDTH - MARGIN - 150
        qr_y = PAGE_HEIGHT - MARGIN - 250
        c.drawImage(qr_reportlab, qr_x, qr_y, width=150, height=150)
        
        # Draw wedding image at bottom
        wedding_image = Image.open("EJ Wedding E-Card1.jpg")
        img_buffer = io.BytesIO()
        wedding_image.save(img_buffer, format='PNG')
        img_buffer.seek(0)
        wedding_reportlab = ImageReader(img_buffer)
        
        # Draw image centered at bottom
        img_width = wedding_image.width * 0.5  # Scale down to 50%
        img_height = wedding_image.height * 0.5
        img_x = (PAGE_WIDTH - img_width) / 2
        img_y = MARGIN
        c.drawImage(wedding_reportlab, img_x, img_y, width=img_width, height=img_height)
        
        # Save PDF
        c.save()
        logger.info(f"Successfully generated e-vite for {name}")
        
        return evite_uuid
        
    except Exception as e:
        logger.error(f"Error generating e-vite for {name}: {str(e)}")
        raise



def generate_evites(data_path, output_dir="download"):
    """Generate personalized e-vites from CSV data and send via WhatsApp."""
    try:
        # Create output directory if it doesn't exist
        os.makedirs(output_dir, exist_ok=True)
        
        logger.info("Starting e-vite generation...")
        
        with open(data_path, 'r') as csvfile:
            reader = csv.DictReader(csvfile)
            for row in reader:
                name = row['Name']
                phone = row['Phone']
                title = row.get('Title', '')
                admits = row.get('Admits', '')
                
                # Generate UUID first
                evite_uuid = str(uuid.uuid4())
                
                # Generate UUID first
                evite_uuid = str(uuid.uuid4())
                
                # Create base64 encoded filename
                filename_data = f"{title}:{name}:{phone}:{evite_uuid}"
                encoded_filename = base64.urlsafe_b64encode(filename_data.encode()).decode()
                
                # Generate PDF
                output_path = os.path.join(output_dir, f"{encoded_filename}.pdf")
                generate_pdf(name, title, phone, admits, output_path)
                logger.info(f"Successfully generated e-vite for {name} with UUID: {evite_uuid}")
                logger.info(f"Successfully generated e-vite for {name} with UUID: {evite_uuid}")
                
                # Send SMS message with UUID
                filename_data = f"{title}:{name}:{phone}:{evite_uuid}"
                encoded_filename = base64.urlsafe_b64encode(filename_data.encode()).decode()
                download_url = f"https://events.angstrom-technologies.ug/evite/download/{encoded_filename}.pdf"
                
                # Send SMS message
                send_sms(phone, name, title, download_url)
                
                # Send document message (disabled for now)
                # send_whatsapp_document(phone, name, title, output_path)
                
        logger.info("E-vite generation complete!")
        
    except Exception as e:
        logger.error(f"Error processing {name}: {str(e)}")
        raise

if __name__ == "__main__":
    try:
        DATA_PATH = "guests.csv"
        
        logger.info("Starting e-vite generation...")
        generate_evites(DATA_PATH)
        logger.info("E-vite generation complete!")
    except Exception as e:
        logger.error(f"Error in main: {str(e)}")
        raise
