from io import BytesIO

from django.conf import settings
from reportlab.lib.pagesizes import A5
from reportlab.lib.units import mm
from reportlab.pdfgen import canvas


def generate_invoice_pdf(sale):
    """Render a Sale as a receipt-style PDF and return it as bytes."""
    buffer = BytesIO()
    width, height = A5
    pdf = canvas.Canvas(buffer, pagesize=A5)

    margin = 12 * mm
    y = height - margin

    def line(text, size=10, bold=False, gap=6 * mm):
        nonlocal y
        pdf.setFont('Helvetica-Bold' if bold else 'Helvetica', size)
        pdf.drawString(margin, y, text)
        y -= gap

    def hr():
        nonlocal y
        pdf.line(margin, y, width - margin, y)
        y -= 5 * mm

    line(settings.BUSINESS_NAME, size=14, bold=True, gap=8 * mm)
    hr()
    line(f'Invoice: {sale.invoice_number}', bold=True)
    line(f'Date: {sale.sold_at.strftime("%d/%m/%Y %H:%M")}')
    if sale.customer_name:
        line(f'Customer: {sale.customer_name}')
    if sale.customer_phone:
        line(f'Phone: {sale.customer_phone}')
    hr()

    pdf.setFont('Helvetica-Bold', 9)
    pdf.drawString(margin, y, 'Item')
    pdf.drawString(margin + 65 * mm, y, 'Qty')
    pdf.drawString(margin + 80 * mm, y, 'Price')
    pdf.drawString(margin + 105 * mm, y, 'Total')
    y -= 5 * mm
    hr()

    pdf.setFont('Helvetica', 9)
    total = 0
    for item in sale.items.all():
        subtotal = item.subtotal
        total += subtotal
        pdf.drawString(margin, y, item.spare_part.name[:32])
        pdf.drawRightString(margin + 75 * mm, y, str(item.quantity))
        pdf.drawRightString(margin + 95 * mm, y, f'{item.unit_price:,.0f}')
        pdf.drawRightString(margin + 120 * mm, y, f'{subtotal:,.0f}')
        y -= 5.5 * mm

    y -= 2 * mm
    hr()
    line(f'TOTAL: {total:,.0f}', bold=True, size=11)
    line(f'Payment Method: {sale.get_payment_method_display()}')
    line(f'Served by: {sale.sold_by.get_full_name() or sale.sold_by.username}')
    hr()
    line('Thank you for your business', size=9)

    pdf.showPage()
    pdf.save()
    return buffer.getvalue()
