#!/usr/bin/env python3
"""Generate the downloadable PDFs for the SwiftShip Express website."""
import os

from reportlab.lib import colors
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import ParagraphStyle
from reportlab.lib.units import mm
from reportlab.platypus import (HRFlowable, Paragraph, SimpleDocTemplate,
                                Spacer, Table, TableStyle)

NAVY = colors.HexColor("#0B2545")
ORANGE = colors.HexColor("#FF6B35")
LIGHT = colors.HexColor("#EEF3FA")
GREY = colors.HexColor("#5A6B7E")

BASE = os.path.dirname(os.path.abspath(__file__))
OUT = os.path.join(BASE, "downloads")
os.makedirs(OUT, exist_ok=True)

H1 = ParagraphStyle("H1", fontName="Helvetica-Bold", fontSize=19, leading=24, textColor=NAVY, spaceAfter=2)
H2 = ParagraphStyle("H2", fontName="Helvetica-Bold", fontSize=13, leading=17, textColor=NAVY, spaceBefore=12, spaceAfter=4)
BODY = ParagraphStyle("BODY", fontName="Helvetica", fontSize=10.5, leading=15, textColor=colors.HexColor("#22303F"), spaceAfter=6)
SMALL = ParagraphStyle("SMALL", fontName="Helvetica-Oblique", fontSize=8.5, leading=11, textColor=GREY, spaceBefore=8)
CELL = ParagraphStyle("CELL", fontName="Helvetica", fontSize=9.5, leading=12, textColor=colors.HexColor("#22303F"))
CELLB = ParagraphStyle("CELLB", fontName="Helvetica-Bold", fontSize=9.5, leading=12, textColor=NAVY)


def build_pdf(filename, title, subtitle, story):
    def on_page(canvas, doc):
        canvas.saveState()
        canvas.setFillColor(NAVY)
        canvas.rect(0, A4[1] - 18 * mm, A4[0], 18 * mm, fill=1, stroke=0)
        canvas.setFillColor(colors.white)
        canvas.setFont("Helvetica-Bold", 12)
        canvas.drawString(18 * mm, A4[1] - 11.5 * mm, "SwiftShip Express")
        canvas.setFont("Helvetica", 9)
        canvas.drawRightString(A4[0] - 18 * mm, A4[1] - 11.5 * mm, title)
        canvas.setFillColor(ORANGE)
        canvas.rect(0, A4[1] - 19 * mm, A4[0], 1 * mm, fill=1, stroke=0)
        canvas.setFillColor(GREY)
        canvas.setFont("Helvetica", 8)
        canvas.drawString(18 * mm, 10 * mm,
                          "SwiftShip Express  |  1200 Harbor Boulevard, Newark, NJ 07114  |  +1 (800) 555-0142  |  swiftship.example")
        canvas.drawRightString(A4[0] - 18 * mm, 10 * mm, f"Page {doc.page}")
        canvas.restoreState()

    doc = SimpleDocTemplate(os.path.join(OUT, filename), pagesize=A4,
                            leftMargin=18 * mm, rightMargin=18 * mm,
                            topMargin=28 * mm, bottomMargin=20 * mm,
                            title=f"{title} - SwiftShip Express")
    doc.build(story, onFirstPage=on_page, onLaterPages=on_page)
    print("Wrote", os.path.relpath(os.path.join(OUT, filename), BASE))


def rate_table(head, rows):
    data = [[Paragraph(f"<b>{h}</b>", CELLB) for h in head]]
    for r in rows:
        data.append([Paragraph(str(c), CELL) for c in r])
    t = Table(data, colWidths=[52 * mm, 24 * mm, 24 * mm, 28 * mm, 34 * mm])
    style = [
        ("BACKGROUND", (0, 0), (-1, 0), NAVY),
        ("TEXTCOLOR", (0, 0), (-1, 0), colors.white),
        ("ROWBACKGROUNDS", (0, 1), (-1, -1), [colors.white, LIGHT]),
        ("GRID", (0, 0), (-1, -1), 0.5, colors.HexColor("#C9D6E6")),
        ("VALIGN", (0, 0), (-1, -1), "MIDDLE"),
        ("TOPPADDING", (0, 0), (-1, -1), 5),
        ("BOTTOMPADDING", (0, 0), (-1, -1), 5),
    ]
    # header text color must be white
    t.setStyle(TableStyle(style))
    return t


# ------------------------------- 1. Rate card -------------------------------
rate_rows = [
    ["Domestic Next-Day", "$18.50", "$4.90 / kg", "$3.40 / kg", "Up to 30 kg"],
    ["Domestic Economy (2-4 days)", "$9.90", "$1.60 / kg", "$1.10 / kg", "Up to 30 kg"],
    ["Express International Air", "$42.00", "$6.80 / kg", "$4.90 / kg", "Up to 70 kg / pc"],
    ["International Economy Air", "$24.00", "$3.60 / kg", "$2.60 / kg", "Up to 70 kg / pc"],
    ["Ocean FCL (20ft / 40ft)", "-", "-", "$1,450 / $1,780", "Full container"],
    ["Ocean LCL (groupage)", "-", "-", "$95 / cbm", "Min 1 cbm"],
    ["Same-Day City Courier", "$12.00 flat + $0.85 / km", "-", "-", "Up to 15 kg"],
]
rate_story = [
    Paragraph("International &amp; Domestic Rate Card", H1),
    Paragraph("Effective 1 October 2026 - all prices in USD, exclusive of duties and taxes", ParagraphStyle(
        "sub", parent=BODY, textColor=GREY, spaceAfter=10)),
    Paragraph("Express parcel rates", H2),
    rate_table(["Service", "Base", "0-5 kg", "5 kg +", "Limits"], rate_rows),
    Paragraph("Fuel surcharge: 12.5% of freight charge. Remote-area surcharge: $14.50 per shipment. "
              "Rates exclude VAT/GST, customs duties and optional insurance (1.2% of declared value, minimum $4).", BODY),
    Paragraph("Zone summary", H2),
    rate_table(["Zone", "Coverage", "Express air ETA", "Economy air ETA", "Ocean ETA"],
               [["Zone A", "Domestic / in-country", "Next business day", "2-4 business days", "-"],
                ["Zone B", "Europe &amp; Mediterranean", "1-2 business days", "4-6 business days", "8-12 days"],
                ["Zone C", "North &amp; South America", "2-3 business days", "5-8 business days", "12-18 days"],
                ["Zone D", "Asia-Pacific", "2-4 business days", "6-10 business days", "16-24 days"],
                ["Zone E", "Middle East &amp; Africa", "3-5 business days", "7-12 business days", "18-28 days"]]),
    Paragraph("Volume discounts from 15% are available above 200 shipments per month. Contact "
              "sales@swiftship.example for a tailored agreement.", BODY),
    Paragraph("Prices are indicative and subject to change. This rate card is provided as a sample for "
              "demonstration purposes.", SMALL),
]
build_pdf("swiftship-rate-card-2026.pdf", "Rate Card 2026", "", rate_story)

# ------------------------------ 2. Shipping guide ---------------------------
guide_story = [
    Paragraph("Packaging &amp; Shipping Guide", H1),
    Paragraph("How to prepare parcels that arrive safely - SwiftShip Express, 2026 edition",
              ParagraphStyle("sub", parent=BODY, textColor=GREY, spaceAfter=10)),
    Paragraph("1. Choose the right box", H2),
    Paragraph("Use a corrugated box rated for the weight of its contents. New boxes are always "
              "stronger than re-used ones; if re-using, remove old labels and check that corners and "
              "seams are intact. Items heavier than 20 kg should ship in double-wall boxes.", BODY),
    Paragraph("2. Cushion the contents", H2),
    Paragraph("Wrap each item individually and fill all empty space with bubble wrap, foam or "
              "crumpled paper. The shake test applies: nothing should move when the sealed box is "
              "gently shaken. Keep a 6 cm cushion between contents and every wall of the box.", BODY),
    Paragraph("3. Seal properly", H2),
    Paragraph("Use pressure-sensitive packing tape at least 48 mm wide. Apply the H-taping method: "
              "one strip along the centre seam and one strip down each side seam. Do not use string, "
              "paper tape or masking tape.", BODY),
    Paragraph("4. Address for machines, not people", H2),
    Paragraph("Print the recipient address on a flat surface of the largest side, in sans-serif type "
              "at least 10 mm high. Place a duplicate copy of the address label inside the box. Remove "
              "or cross out any old barcodes on re-used packaging - a stray barcode is the number-one "
              "cause of mis-sort.", BODY),
    Paragraph("5. Lithium batteries and restricted goods", H2),
    Paragraph("Lithium-ion batteries contained in equipment are accepted under IATA provision II; "
              "standalone batteries require the lithium battery mark and a maximum 100 Wh rating. "
              "Aerosols, perfumes, flammables and perishables require prior approval. The full "
              "prohibited list is in our Terms of Service.", BODY),
    Paragraph("6. Declare value honestly", H2),
    Paragraph("Insurance claims are assessed against the declared value on the airway bill. "
              "Undeclared or under-declared shipments are covered to the carrier liability limit only.", BODY),
    Paragraph("7. Track proactively", H2),
    Paragraph("Every shipment gets up to eight tracking scans. Enable email notifications on the "
              "SwiftShip tracking page and monitor the estimated delivery date - if an exception scan "
              "appears, contact support within 24 hours to resolve it fastest.", BODY),
    Paragraph("Sample document for demonstration purposes.", SMALL),
]
build_pdf("swiftship-shipping-guide-2026.pdf", "Shipping Guide 2026", "", guide_story)

# ----------------------------- 3. Terms of service --------------------------
terms_story = [
    Paragraph("Terms &amp; Conditions of Carriage", H1),
    Paragraph("Effective 1 October 2026 - SwiftShip Express Logistics B.V. (sample document)",
              ParagraphStyle("sub", parent=BODY, textColor=GREY, spaceAfter=10)),
    Paragraph("1. Scope", H2),
    Paragraph("These Terms govern the carriage of documents and parcels by SwiftShip Express and its "
              "contracted carriers. By presenting a shipment to us, the shipper accepts these Terms on "
              "their own behalf and on behalf of the recipient.", BODY),
    Paragraph("2. Liability", H2),
    Paragraph("Our liability for loss of or damage to goods is limited to the greater of USD 100 per "
              "shipment or the declared value, unless a higher value is declared and the corresponding "
              "insurance fee is paid. Consequential damages, loss of profit and loss of goodwill are "
              "excluded. Claims must be notified in writing within 21 days of the delivery date.", BODY),
    Paragraph("3. Prohibited and restricted goods", H2),
    Paragraph("Shipments may not contain: explosives and munitions; compressed gases; flammable "
              "liquids and solids; oxidising materials; radioactive material; live animals; human "
              "remains; currency and bearer instruments; illegal narcotics; counterfeits; and any item "
              "prohibited by IATA, ICAO or applicable law of origin, transit or destination.", BODY),
    Paragraph("4. Customs", H2),
    Paragraph("The shipper is responsible for accurate customs declarations, HS codes and valuation. "
              "Duties and taxes are payable by the recipient unless the shipment is sent with duties "
              "paid (DDP) service. Where customs clearance is delayed by the shipper's documentation, "
              "storage charges may apply after 48 hours.", BODY),
    Paragraph("5. Delivery", H2),
    Paragraph("Delivery is completed when the shipment is handed over at the recipient address, to an "
              "adult present at that address, or to a neighbour / safe place where the service permits. "
              "Our records of the delivery scan and signature are prima facie evidence of delivery.", BODY),
    Paragraph("6. Payment", H2),
    Paragraph("Invoices are due within 14 days of issue. Overdue accounts accrue interest at 1.5% per "
              "month and may be suspended for further service.", BODY),
    Paragraph("7. Governing law", H2),
    Paragraph("These Terms are governed by the laws of the jurisdiction of the carrier's registered "
              "office, without prejudice to mandatory provisions of international carriage conventions, "
              "including the CMR Convention and the Montreal Convention where applicable.", BODY),
    Paragraph("8. Entire agreement", H2),
    Paragraph("These Terms, together with the applicable service guide, constitute the entire "
              "agreement between the parties regarding carriage. Nothing in these Terms limits liability "
              "where limitation is prohibited by law.", BODY),
    Paragraph("This is a sample document created for a demonstration website and is not legal advice.", SMALL),
]
build_pdf("swiftship-terms-of-service-2026.pdf", "Terms of Service 2026", "", terms_story)

print("All PDFs generated.")
