from reportlab.lib.pagesizes import A4
from reportlab.pdfgen import canvas
from reportlab.platypus import Table, TableStyle, Paragraph, SimpleDocTemplate, Spacer, Image
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet
import io
import os
import logging

# --- helpers ---------------------------------------------------------------

def _resolve_logo_path(logo_path: str | None) -> str | None:
    """Return a readable logo path or None. Tries multiple fallbacks.
    This avoids crashes when a caller passes a path that exists only in the
    client container (e.g., '/client/assets/...') while we're running in the
    server container on Fly.
    """
    here = os.path.dirname(__file__)
    project_root = os.path.abspath(os.path.join(here, "..", ".."))

    candidates = []

    # 1) if caller provided a path, try it as-is
    if logo_path:
        candidates.append(logo_path)
        # also try without a leading slash inside our image tree
        stripped = logo_path.lstrip("/\\")
        candidates.append(os.path.join(project_root, stripped))

    # 2) Known locations in this repo layout
    candidates.append(os.path.join(project_root, "client", "assets", "images", "truck_logo_black.png"))
    candidates.append(os.path.join(project_root, "assets", "images", "truck_logo_black.png"))

    # 3) Allow override via env
    env_path = os.getenv("DEFAULT_LOGO_PATH")
    if env_path:
        candidates.insert(0, env_path)

    for p in candidates:
        try:
            if p and os.path.isfile(p):
                return p
        except Exception:
            # some paths may be malformed on certain platforms
            continue
    return None

def generate_order_pdf(order, user_data, transporter_data, logo_path, save_to_disk=True):
    #print(order)
    #print(f'user data: {user_data}')
    if 'address' in user_data:
        address = user_data.get("address")
        if address:
            address = address.replace(" %",", ")
        else:
            address = ''
    else:
        address=''
    buffer = io.BytesIO()
    doc = SimpleDocTemplate(buffer, pagesize=A4)
    elements = []
    styles = getSampleStyleSheet()

    # Resolve logo path robustly across local/dev and Fly
    logo_path = _resolve_logo_path(logo_path)

    # Prepare texts
    user_text = f"""<b>{user_data.get("name", "")}</b><br/>
{user_data.get("register_number", "")}<br/>
{user_data.get("vat", "")}<br/>
{address}<br/>
{""}<br/>
{user_data.get("contact_name", "")}<br/>
{user_data.get("phone", "")}<br/>
{user_data.get("email", "")}
"""
    transporter_text = f"""<b>{transporter_data.get("name", "")}</b><br/>
{transporter_data.get("contact_person", "")}<br/>
{transporter_data.get("phone", "")}<br/>
{transporter_data.get("email", "")}
"""

    # Logo (centered), tolerate missing file
    logo = None
    if logo_path:
        try:
            logo = Image(logo_path, width=120, mask='auto', height=60)
            logo.hAlign = 'CENTER'
        except Exception as e:
            logging.warning("PDF: failed to load logo at %s: %s", logo_path, e)
            logo = None

    # Top section: transporter - logo - user
    top_section = Table([
        [
            Paragraph(transporter_text, styles['Normal']),
            logo,
            Paragraph(user_text, styles['Normal'])
        ]
    ], colWidths=[200, 150, 200])
    top_section.setStyle(TableStyle([
        ("VALIGN", (0, 0), (-1, -1), "MIDDLE"),
        ("ALIGN", (0, 0), (0, 0), "LEFT"),
        ("ALIGN", (1, 0), (1, 0), "CENTER"),
        ("ALIGN", (2, 0), (2, 0), "RIGHT"),
        ("LEFTPADDING", (0, 0), (0, 0), 20),
    ]))
    elements.append(top_section)
    elements.append(Spacer(1, 12))

    # Order number and current date (centered, vertically stacked)
    from datetime import datetime
    header_info = Table([
        [Paragraph(f"<b>Loading Order</b>: {order['order_number']}", styles["Normal"])],
        [Paragraph(f"Date: {datetime.now().strftime('%d/%m/%Y')}", styles["Normal"])]
    ], colWidths=[450])
    header_info.setStyle(TableStyle([
        ("ALIGN", (0, 0), (-1, -1), "CENTER")
    ]))
    elements.append(header_info)
    elements.append(Spacer(1, 12))

    # Order Summary Table
    elements.append(Paragraph("Summary", styles['Heading3']))
    summary_data = [
        ["Details", Paragraph("Values", styles["Normal"])],
        ["Truck Reg. No.", Paragraph(str(order["track_reg_number"]), styles["Normal"])],
        ["Trailer Reg. No.", Paragraph(str(order["trailer_reg_number"]), styles["Normal"])],
        ["Product Description", Paragraph(str(order["products_description"]), styles["Normal"])],
        ["LDM", Paragraph(str(order["ldb_quantity"]), styles["Normal"])],
        ["KG", Paragraph(str(order["kg_quantity"]), styles["Normal"])],
        ["Price", Paragraph(str(order["paid_price"])+ " " +order["currency_paid"], styles["Normal"])],
    ]
    summary_table = Table(summary_data, colWidths=[150, 350])
    summary_table.setStyle(TableStyle([
        ("GRID", (0, 0), (-1, -1), 0.5, colors.black),
        ("BACKGROUND", (0, 0), (-1, 0), colors.lightgrey),
        ("VALIGN", (0, 0), (-1, -1), "MIDDLE"),
        ("WORDWRAP", (0, 0), (-1, -1), "CJK"),
        ("ALIGN", (0, 0), (-1, -1), "LEFT"),
    ]))
    elements.append(summary_table)
    elements.append(Spacer(1, 24))

    # Loading Points
    elements.append(Paragraph("Loading Sequence", styles['Heading3']))
    loading_data = [[Paragraph("Address", styles["Normal"]), Paragraph("Date & Hour", styles["Normal"]), Paragraph("Instructions", styles["Normal"])]]
    for l in order["loading_addresses"]:
        loading_data.append([
            Paragraph(f"{l["loading_address_name"]}: {l["loading_address"]}", styles["Normal"]),
            Paragraph(f"{l['loading_date']} {l['loading_hour']}", styles["Normal"]),
            Paragraph(str(l["loading_informatins"]), styles["Normal"])
        ])
    loading_table = Table(loading_data, colWidths=[200, 100, 200])
    loading_table.setStyle(TableStyle([
        ("GRID", (0, 0), (-1, -1), 0.5, colors.black),
        ("BACKGROUND", (0, 0), (-1, 0), colors.lightgrey),
        ("VALIGN", (0, 0), (-1, -1), "TOP"),
        ("WORDWRAP", (0, 0), (-1, -1), "CJK"),
        ("ALIGN", (0, 0), (-1, -1), "LEFT"),
    ]))
    elements.append(loading_table)
    elements.append(Spacer(1, 24))

    # Unloading Points
    elements.append(Paragraph("Unloading Sequence", styles['Heading3']))
    unloading_data = [[Paragraph("Address", styles["Normal"]), Paragraph("Date & Hour", styles["Normal"]), Paragraph("Instructions", styles["Normal"])]]
    for u in order["unloading_addresses"]:
        unloading_data.append([
            Paragraph(f"{u["unloading_address_name"]}: {u["unloading_address"]}", styles["Normal"]),
            Paragraph(f"{u['unloading_date']} {u['unloading_hour']}", styles["Normal"]),
            Paragraph(str(u["unloading_informatins"]), styles["Normal"])
        ])
    unloading_table = Table(unloading_data, colWidths=[200, 100, 200])
    unloading_table.setStyle(TableStyle([
        ("GRID", (0, 0), (-1, -1), 0.5, colors.black),
        ("BACKGROUND", (0, 0), (-1, 0), colors.lightgrey),
        ("VALIGN", (0, 0), (-1, -1), "TOP"),
        ("WORDWRAP", (0, 0), (-1, -1), "CJK"),
        ("ALIGN", (0, 0), (-1, -1), "LEFT"),
    ]))
    elements.append(unloading_table)

    elements.append(Spacer(1, 24))

    elements.append(Paragraph("Terms and Conditions", styles["Heading3"]),)

    elements.append(
        Paragraph(str(order["terms"]), styles["Normal"])
    )

    doc.build(elements)
    buffer.seek(0)
    user_id = order['user_id']
    if user_data['user_role'] == 'company_user':
        user_id = user_data['company_id']
    if save_to_disk:
        save_path=f"generated_pdfs/order_{user_id}_{order['order_number']}.pdf"
        with open(save_path, "wb") as f:
            f.write(buffer.getvalue())

    return buffer

