"""PDF and Excel export helpers for list data."""
from io import BytesIO

from django.http import HttpResponse
from reportlab.lib.pagesizes import A4, landscape
from reportlab.lib.units import mm
from reportlab.pdfgen import canvas

import openpyxl
from openpyxl.styles import Font, PatternFill, Alignment


def build_pdf(title, headers, rows, orientation='landscape'):
    buffer = BytesIO()
    pagesize = landscape(A4) if orientation == 'landscape' else A4
    width, height = pagesize
    pdf = canvas.Canvas(buffer, pagesize=pagesize)
    margin = 15 * mm
    col_width = (width - 2 * margin) / max(len(headers), 1)
    row_height = 5 * mm

    def draw_page_header():
        nonlocal y
        pdf.setFont('Helvetica-Bold', 14)
        pdf.drawString(margin, y, title)
        y -= 10 * mm
        pdf.setFont('Helvetica-Bold', 8)
        for i, h in enumerate(headers):
            pdf.drawString(margin + i * col_width, y, str(h))
        y -= row_height
        pdf.line(margin, y + 2 * mm, width - margin, y + 2 * mm)

    y = height - margin
    draw_page_header()

    for row in rows:
        if y < margin + 10 * mm:
            pdf.showPage()
            y = height - margin
            draw_page_header()
        pdf.setFont('Helvetica', 8)
        for i, val in enumerate(row):
            text = str(val) if val is not None else ''
            if len(text) > 30:
                text = text[:28] + '…'
            pdf.drawString(margin + i * col_width, y, text)
        y -= row_height

    pdf.save()
    buffer.seek(0)
    return buffer


def build_xlsx(title, headers, rows):
    wb = openpyxl.Workbook()
    ws = wb.active
    ws.title = title[:31]

    header_font = Font(bold=True, color='FFFFFF')
    header_fill = PatternFill(start_color='3B82F6', end_color='3B82F6', fill_type='solid')

    for col_idx, header in enumerate(headers, 1):
        cell = ws.cell(row=1, column=col_idx, value=header)
        cell.font = header_font
        cell.fill = header_fill
        cell.alignment = Alignment(horizontal='center')

    for row_idx, row in enumerate(rows, 2):
        for col_idx, val in enumerate(row, 1):
            ws.cell(row=row_idx, column=col_idx, value=val)

    for col_idx in range(1, len(headers) + 1):
        ws.column_dimensions[openpyxl.utils.get_column_letter(col_idx)].width = 18

    buffer = BytesIO()
    wb.save(buffer)
    buffer.seek(0)
    return buffer


def pdf_response(title, headers, rows, filename):
    buf = build_pdf(title, headers, rows)
    response = HttpResponse(buf.read(), content_type='application/pdf')
    response['Content-Disposition'] = f'attachment; filename="{filename}.pdf"'
    return response


def xlsx_response(title, headers, rows, filename):
    buf = build_xlsx(title, headers, rows)
    response = HttpResponse(
        buf.read(),
        content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
    )
    response['Content-Disposition'] = f'attachment; filename="{filename}.xlsx"'
    return response
