"""
PDF generation utilities using ReportLab.
"""
from io import BytesIO
from datetime import datetime
from reportlab.lib import colors
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm, mm
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph, Spacer, Image
from reportlab.lib.enums import TA_CENTER, TA_RIGHT, TA_LEFT


def generate_invoice_pdf(folio) -> bytes:
    """
    Generate PDF invoice for a folio.

    Args:
        folio: Folio model with all relations loaded

    Returns:
        PDF content as bytes
    """
    buffer = BytesIO()
    doc = SimpleDocTemplate(
        buffer,
        pagesize=A4,
        rightMargin=2*cm,
        leftMargin=2*cm,
        topMargin=2*cm,
        bottomMargin=2*cm
    )

    styles = getSampleStyleSheet()
    story = []

    # Custom styles
    title_style = ParagraphStyle(
        'Title',
        parent=styles['Heading1'],
        fontSize=18,
        alignment=TA_CENTER,
        spaceAfter=20
    )

    header_style = ParagraphStyle(
        'Header',
        parent=styles['Normal'],
        fontSize=10,
        alignment=TA_LEFT
    )

    right_style = ParagraphStyle(
        'Right',
        parent=styles['Normal'],
        fontSize=10,
        alignment=TA_RIGHT
    )

    # Get related data
    reservation = folio.reservation
    client = reservation.client
    room = reservation.room
    establishment = room.establishment

    # Header - Establishment info
    establishment_info = f"""
    <b>{establishment.name}</b><br/>
    {establishment.address or ''}<br/>
    {establishment.postal_code or ''} {establishment.city or ''}<br/>
    {establishment.country or ''}<br/>
    Tél: {establishment.phone or 'N/A'}<br/>
    Email: {establishment.email or 'N/A'}<br/>
    {f'N° TVA: {establishment.tax_id}' if establishment.tax_id else ''}
    """
    story.append(Paragraph(establishment_info, header_style))
    story.append(Spacer(1, 1*cm))

    # Invoice title
    story.append(Paragraph(f"FACTURE N° FAC-{folio.folio_number}", title_style))
    story.append(Spacer(1, 0.5*cm))

    # Invoice date and client info in two columns
    invoice_date = datetime.now().strftime("%d/%m/%Y")

    client_info = f"""
    <b>Client:</b><br/>
    {client.full_name}<br/>
    {f'{client.company_name}<br/>' if client.company_name else ''}
    {client.address or ''}<br/>
    {client.postal_code or ''} {client.city or ''}<br/>
    {client.country or ''}<br/>
    {f'N° TVA: {client.tax_id}' if client.tax_id else ''}
    """

    invoice_info = f"""
    <b>Date:</b> {invoice_date}<br/>
    <b>N° Réservation:</b> {reservation.confirmation_number}<br/>
    <b>Chambre:</b> {room.room_number}<br/>
    <b>Arrivée:</b> {reservation.check_in_date.strftime('%d/%m/%Y')}<br/>
    <b>Départ:</b> {reservation.check_out_date.strftime('%d/%m/%Y')}<br/>
    <b>Nuitées:</b> {reservation.nights}
    """

    # Two column table for client/invoice info
    info_data = [[
        Paragraph(client_info, header_style),
        Paragraph(invoice_info, right_style)
    ]]

    info_table = Table(info_data, colWidths=[9*cm, 8*cm])
    info_table.setStyle(TableStyle([
        ('VALIGN', (0, 0), (-1, -1), 'TOP'),
    ]))
    story.append(info_table)
    story.append(Spacer(1, 1*cm))

    # Items table
    items_data = [['Description', 'Qté', 'P.U. HT', 'TVA %', 'Total HT', 'Total TTC']]

    subtotal_ht = 0
    total_tax = 0
    total_ttc = 0

    for item in folio.items:
        if item.is_voided:
            continue

        items_data.append([
            item.description,
            f"{item.quantity:.2f}",
            f"{item.unit_price:.2f}",
            f"{item.tax_rate:.1f}%",
            f"{item.total_ht:.2f}",
            f"{item.total_ttc:.2f}"
        ])

        subtotal_ht += item.total_ht
        total_tax += (item.total_ttc - item.total_ht)
        total_ttc += item.total_ttc

    items_table = Table(
        items_data,
        colWidths=[7*cm, 1.5*cm, 2*cm, 1.5*cm, 2.5*cm, 2.5*cm]
    )

    items_table.setStyle(TableStyle([
        ('BACKGROUND', (0, 0), (-1, 0), colors.grey),
        ('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
        ('ALIGN', (1, 0), (-1, -1), 'RIGHT'),
        ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
        ('FONTSIZE', (0, 0), (-1, -1), 9),
        ('BOTTOMPADDING', (0, 0), (-1, 0), 12),
        ('BACKGROUND', (0, 1), (-1, -1), colors.beige),
        ('GRID', (0, 0), (-1, -1), 1, colors.black),
        ('ROWBACKGROUNDS', (0, 1), (-1, -1), [colors.white, colors.lightgrey]),
    ]))

    story.append(items_table)
    story.append(Spacer(1, 0.5*cm))

    # Totals
    totals_data = [
        ['', '', '', '', 'Sous-total HT:', f"{subtotal_ht:.2f} {folio.currency}"],
        ['', '', '', '', 'Total TVA:', f"{total_tax:.2f} {folio.currency}"],
        ['', '', '', '', 'Total TTC:', f"{total_ttc:.2f} {folio.currency}"],
    ]

    # Add payments
    total_paid = sum(p.amount for p in folio.payments)
    if total_paid > 0:
        totals_data.append(['', '', '', '', 'Paiements reçus:', f"-{total_paid:.2f} {folio.currency}"])

    balance = total_ttc - total_paid
    totals_data.append(['', '', '', '', 'Solde dû:', f"{balance:.2f} {folio.currency}"])

    totals_table = Table(totals_data, colWidths=[4*cm, 2*cm, 2*cm, 2*cm, 3.5*cm, 3.5*cm])
    totals_table.setStyle(TableStyle([
        ('ALIGN', (4, 0), (-1, -1), 'RIGHT'),
        ('FONTNAME', (4, -1), (-1, -1), 'Helvetica-Bold'),
        ('LINEABOVE', (4, -1), (-1, -1), 1, colors.black),
    ]))

    story.append(totals_table)
    story.append(Spacer(1, 1*cm))

    # Payment details
    if folio.payments:
        story.append(Paragraph("<b>Détail des paiements:</b>", header_style))
        story.append(Spacer(1, 0.3*cm))

        payment_data = [['Date', 'Mode', 'Référence', 'Montant']]
        for payment in folio.payments:
            payment_data.append([
                payment.payment_date.strftime('%d/%m/%Y'),
                payment.payment_method.value,
                payment.reference or '-',
                f"{payment.amount:.2f} {payment.currency}"
            ])

        payment_table = Table(payment_data, colWidths=[4*cm, 4*cm, 4*cm, 4*cm])
        payment_table.setStyle(TableStyle([
            ('BACKGROUND', (0, 0), (-1, 0), colors.lightgrey),
            ('GRID', (0, 0), (-1, -1), 0.5, colors.grey),
            ('FONTSIZE', (0, 0), (-1, -1), 9),
            ('ALIGN', (-1, 0), (-1, -1), 'RIGHT'),
        ]))

        story.append(payment_table)

    # Footer
    story.append(Spacer(1, 2*cm))
    footer_text = """
    <i>Merci pour votre séjour. Nous espérons vous revoir bientôt.</i><br/><br/>
    <small>Cette facture a été générée automatiquement par FiHotelFlow.</small>
    """
    story.append(Paragraph(footer_text, ParagraphStyle('Footer', alignment=TA_CENTER, fontSize=9)))

    # Build PDF
    doc.build(story)
    return buffer.getvalue()
