"""
pdf_generator.py — Premium branded "Business AI Score" PDF report with heatmap visuals.

Uses ReportLab to generate dark-themed, color-coded PDF reports with
gradient effects, score rings, recommendation cards, and strong CTAs.
"""

import math
import os
from datetime import datetime
from typing import Optional

from reportlab.lib.pagesizes import letter
from reportlab.lib.units import inch, mm
from reportlab.lib.colors import HexColor, white, black, Color
from reportlab.pdfgen import canvas
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_RIGHT
from reportlab.platypus import Paragraph, Frame
from reportlab.lib.styles import ParagraphStyle


# ---------------------------------------------------------------------------
# Brand Colors
# ---------------------------------------------------------------------------
BG_COLOR = HexColor("#0B0C0E")
BG_CARD = HexColor("#141519")
BG_CARD_LIGHT = HexColor("#1C1D24")
BG_CARD_HOVER = HexColor("#1E2028")
ACCENT_BLUE = HexColor("#3B82F6")
ACCENT_BLUE_DIM = HexColor("#2563EB")
ACCENT_BLUE_GLOW = HexColor("#1D4ED8")
ACCENT_BLUE_FAINT = HexColor("#172554")
ACCENT_ORANGE = HexColor("#F97316")
ACCENT_ORANGE_DIM = HexColor("#C2410C")
ACCENT_PURPLE = HexColor("#8B5CF6")
ACCENT_CYAN = HexColor("#06B6D4")
TEXT_WHITE = HexColor("#F8FAFC")
TEXT_GRAY = HexColor("#94A3B8")
TEXT_LIGHT_GRAY = HexColor("#CBD5E1")
TEXT_DIM = HexColor("#64748B")
SCORE_RED = HexColor("#EF4444")
SCORE_RED_DIM = HexColor("#7F1D1D")
SCORE_YELLOW = HexColor("#F59E0B")
SCORE_YELLOW_DIM = HexColor("#78350F")
SCORE_GREEN = HexColor("#22C55E")
SCORE_GREEN_DIM = HexColor("#14532D")
DIVIDER = HexColor("#2D2E36")
DIVIDER_LIGHT = HexColor("#383944")


def _score_color(score: int):
    """Return color based on score range."""
    if score <= 33:
        return SCORE_RED
    elif score <= 66:
        return SCORE_YELLOW
    else:
        return SCORE_GREEN


def _score_color_dim(score: int):
    """Return a dimmed version of the score color for backgrounds."""
    if score <= 33:
        return SCORE_RED_DIM
    elif score <= 66:
        return SCORE_YELLOW_DIM
    else:
        return SCORE_GREEN_DIM


def _score_label(score: int) -> str:
    """Return text label for score."""
    if score <= 20:
        return "Critical"
    elif score <= 33:
        return "Poor"
    elif score <= 50:
        return "Below Average"
    elif score <= 66:
        return "Needs Improvement"
    elif score <= 80:
        return "Good"
    elif score <= 90:
        return "Very Good"
    else:
        return "Excellent"


CATEGORY_LABELS = {
    "website_speed": "Website Speed",
    "mobile_experience": "Mobile Experience",
    "online_presence": "Online Presence",
    "seo_basics": "SEO Basics",
    "ai_readiness": "AI Opportunity",
}

CATEGORY_ICONS = {
    "website_speed": "SPEED",
    "mobile_experience": "MOBILE",
    "online_presence": "VISIBILITY",
    "seo_basics": "SEO",
    "ai_readiness": "AI",
}

# Map categories to accent colors for visual variety
CATEGORY_COLORS = {
    "website_speed": HexColor("#3B82F6"),     # Blue
    "mobile_experience": HexColor("#8B5CF6"), # Purple
    "online_presence": HexColor("#06B6D4"),   # Cyan
    "seo_basics": HexColor("#22C55E"),        # Green
    "ai_readiness": HexColor("#F97316"),      # Orange
}


def _lerp_color(c1, c2, t):
    """Linearly interpolate between two ReportLab colors. t in [0,1]."""
    r = c1.red + (c2.red - c1.red) * t
    g = c1.green + (c2.green - c1.green) * t
    b = c1.blue + (c2.blue - c1.blue) * t
    return Color(r, g, b)


def generate_pdf(
    business_name: str,
    scores: dict,
    recommendations: list,
    output_path: str,
    phone_cta: str = "",
    website_url: str = "",
) -> str:
    """
    Generate a branded Business AI Score PDF report.

    Args:
        business_name: Name of the business
        scores: Dict from analyzer with category scores
        recommendations: List of recommendation dicts
        output_path: Full path for the output PDF
        phone_cta: Phone number for CTA (optional)
        website_url: The business URL analyzed

    Returns:
        Path to generated PDF
    """
    # Ensure output directory exists
    os.makedirs(os.path.dirname(output_path) or ".", exist_ok=True)

    w, h = letter  # 612 x 792 points
    c = canvas.Canvas(output_path, pagesize=letter)

    overall_score = scores.get("overall", {}).get("score", 0)

    # ---- PAGE 1: Cover + Score Overview ----
    _draw_page_background(c, w, h)
    _draw_page_decorations(c, w, h)
    _draw_header(c, w, h)

    # Report type subtitle
    y = h - 100
    c.setFont("Helvetica", 10)
    c.setFillColor(ACCENT_BLUE)
    c.drawString(50, y, "BUSINESS INTELLIGENCE REPORT")

    # Decorative accent dots after subtitle
    dot_x = 50 + c.stringWidth("BUSINESS INTELLIGENCE REPORT", "Helvetica", 10) + 10
    for i in range(3):
        alpha_col = _lerp_color(ACCENT_BLUE, BG_COLOR, i * 0.3)
        c.setFillColor(alpha_col)
        c.circle(dot_x + i * 8, y + 3, 2, fill=1, stroke=0)

    # Business name
    y -= 30
    c.setFont("Helvetica-Bold", 22)
    c.setFillColor(TEXT_WHITE)
    display_name = business_name[:48] + ("..." if len(business_name) > 48 else "")
    c.drawString(50, y, display_name)

    # Thin accent line under business name
    y -= 10
    c.setFillColor(ACCENT_BLUE)
    c.rect(50, y, 60, 2, fill=1, stroke=0)
    c.setFillColor(ACCENT_PURPLE)
    c.rect(110, y, 30, 2, fill=1, stroke=0)

    if website_url:
        y -= 16
        c.setFont("Helvetica", 9)
        c.setFillColor(TEXT_GRAY)
        c.drawString(50, y, website_url[:80])

    # Date
    y -= 16
    c.setFont("Helvetica", 9)
    c.setFillColor(TEXT_DIM)
    c.drawString(50, y, f"Generated: {datetime.now().strftime('%d %B %Y')}")

    # ---- Overall Score Ring Section ----
    y -= 20
    # Score section background card
    score_card_y = y - 145
    score_card_h = 155
    c.setFillColor(BG_CARD)
    c.roundRect(40, score_card_y, w - 80, score_card_h, 10, fill=1, stroke=0)

    # Subtle border for card
    c.setStrokeColor(DIVIDER_LIGHT)
    c.setLineWidth(0.5)
    c.roundRect(40, score_card_y, w - 80, score_card_h, 10, fill=0, stroke=1)

    cx = 160  # Circle center X (left side of card)
    cy = score_card_y + score_card_h / 2

    score_col = _score_color(overall_score)
    score_col_dim = _score_color_dim(overall_score)

    # Outer glow rings (gradient effect with concentric circles)
    glow_steps = 6
    for i in range(glow_steps, 0, -1):
        radius = 58 + i * 5
        glow_col = _lerp_color(BG_CARD, score_col, 0.05 * i)
        c.setFillColor(glow_col)
        c.circle(cx, cy, radius, fill=1, stroke=0)

    # Score circle background
    c.setFillColor(HexColor("#0D0E12"))
    c.circle(cx, cy, 55, fill=1, stroke=0)

    # Score ring (thick colored arc)
    c.setStrokeColor(score_col)
    c.setLineWidth(8)
    c.circle(cx, cy, 55, fill=0, stroke=1)

    # Inner decorative ring
    c.setStrokeColor(DIVIDER_LIGHT)
    c.setLineWidth(0.5)
    c.circle(cx, cy, 44, fill=0, stroke=1)

    # Score number
    c.setFont("Helvetica-Bold", 40)
    c.setFillColor(TEXT_WHITE)
    score_text = str(overall_score)
    tw = c.stringWidth(score_text, "Helvetica-Bold", 40)
    c.drawString(cx - tw / 2, cy + 2, score_text)

    # "/100" below number
    c.setFont("Helvetica", 12)
    c.setFillColor(TEXT_GRAY)
    sub = "/100"
    tw2 = c.stringWidth(sub, "Helvetica", 12)
    c.drawString(cx - tw2 / 2, cy - 18, sub)

    # Right side of score card: label and description
    text_x = 250
    text_cy = cy + 20

    c.setFont("Helvetica-Bold", 16)
    c.setFillColor(TEXT_WHITE)
    c.drawString(text_x, text_cy, "Your Business AI Score")

    text_cy -= 24
    c.setFont("Helvetica-Bold", 18)
    c.setFillColor(score_col)
    c.drawString(text_x, text_cy, _score_label(overall_score))

    text_cy -= 22
    c.setFont("Helvetica", 9)
    c.setFillColor(TEXT_GRAY)
    if overall_score <= 33:
        desc = "Significant improvements needed across multiple areas."
    elif overall_score <= 50:
        desc = "Below average — key areas need attention to stay competitive."
    elif overall_score <= 66:
        desc = "Room for improvement — some strengths, some gaps."
    elif overall_score <= 80:
        desc = "Good foundation — optimizations will drive more results."
    else:
        desc = "Strong position — fine-tuning will maximize your edge."
    c.drawString(text_x, text_cy, desc)

    # Small colored bar under description
    text_cy -= 14
    bar_total_w = 200
    filled_w = bar_total_w * (overall_score / 100)
    c.setFillColor(BG_CARD_LIGHT)
    c.roundRect(text_x, text_cy, bar_total_w, 5, 2, fill=1, stroke=0)
    c.setFillColor(score_col)
    c.roundRect(text_x, text_cy, max(3, filled_w), 5, 2, fill=1, stroke=0)

    # ---- Category Score Bars ----
    y = score_card_y - 30
    _draw_section_header(c, w, y, "Score Breakdown")

    y -= 32

    categories = ["website_speed", "mobile_experience", "online_presence", "seo_basics", "ai_readiness"]

    for cat in categories:
        cat_data = scores.get(cat, {})
        cat_score = cat_data.get("score", 0) if isinstance(cat_data, dict) else 0
        cat_label = CATEGORY_LABELS.get(cat, cat)
        cat_icon = CATEGORY_ICONS.get(cat, "")
        color = _score_color(cat_score)
        accent = CATEGORY_COLORS.get(cat, ACCENT_BLUE)

        # Row background
        c.setFillColor(BG_CARD)
        c.roundRect(44, y - 16, w - 88, 34, 5, fill=1, stroke=0)

        # Icon badge (small colored rectangle)
        c.setFillColor(accent)
        badge_w = c.stringWidth(cat_icon, "Helvetica-Bold", 7) + 10
        c.roundRect(54, y + 2, badge_w, 14, 3, fill=1, stroke=0)
        c.setFont("Helvetica-Bold", 7)
        c.setFillColor(TEXT_WHITE)
        c.drawString(59, y + 5.5, cat_icon)

        # Category label
        c.setFont("Helvetica-Bold", 10)
        c.setFillColor(TEXT_WHITE)
        c.drawString(54 + badge_w + 8, y + 5, cat_label)

        # Score value at end of bar
        c.setFont("Helvetica-Bold", 11)
        c.setFillColor(color)
        score_str = str(cat_score)
        stw = c.stringWidth(score_str, "Helvetica-Bold", 11)
        c.drawString(w - 58 - stw, y + 5, score_str)

        # Bar background
        bar_x = 54
        bar_y = y - 12
        bar_w = w - 112
        bar_h = 10

        c.setFillColor(BG_CARD_LIGHT)
        c.roundRect(bar_x, bar_y, bar_w, bar_h, 4, fill=1, stroke=0)

        # Filled portion with category accent color
        fill_w = max(5, bar_w * (cat_score / 100))
        c.setFillColor(color)
        c.roundRect(bar_x, bar_y, fill_w, bar_h, 4, fill=1, stroke=0)

        # Small bright tip at end of fill
        if fill_w > 10:
            tip_col = _lerp_color(color, TEXT_WHITE, 0.4)
            c.setFillColor(tip_col)
            c.roundRect(bar_x + fill_w - 6, bar_y + 1, 6, bar_h - 2, 2, fill=1, stroke=0)

        y -= 46

    # ---- Provider Intel Callout (if competitor detected) ----
    provider_intel = scores.get("_provider_intel", {})
    detected = provider_intel.get("detected_provider")
    est_cost = provider_intel.get("est_monthly_cost")
    if detected and est_cost:
        y -= 6
        box_h = 70
        box_y = y - box_h + 10

        # Alert box background with border
        c.setFillColor(HexColor("#1A1520"))
        c.roundRect(40, box_y, w - 80, box_h, 8, fill=1, stroke=0)

        # Warning border
        c.setStrokeColor(ACCENT_ORANGE)
        c.setLineWidth(1.5)
        c.roundRect(40, box_y, w - 80, box_h, 8, fill=0, stroke=1)

        # Left accent bar (orange)
        c.setFillColor(ACCENT_ORANGE)
        c.roundRect(40, box_y, 5, box_h, 3, fill=1, stroke=0)

        # Warning icon placeholder text
        c.setFont("Helvetica-Bold", 16)
        c.setFillColor(ACCENT_ORANGE)
        c.drawString(58, y - 6, "!")

        # Circle around the warning icon
        c.setStrokeColor(ACCENT_ORANGE)
        c.setLineWidth(1.5)
        c.circle(63, y - 1, 11, fill=0, stroke=1)

        # Provider header
        c.setFont("Helvetica-Bold", 11)
        c.setFillColor(ACCENT_ORANGE)
        c.drawString(82, y - 3, f"Current Provider Detected: {detected}")

        # Estimated spend — bold the dollar amount
        c.setFont("Helvetica", 9)
        c.setFillColor(TEXT_LIGHT_GRAY)
        c.drawString(82, y - 20,
            f"Estimated spend: ")
        spend_x = 82 + c.stringWidth("Estimated spend: ", "Helvetica", 9)
        c.setFont("Helvetica-Bold", 10)
        c.setFillColor(ACCENT_ORANGE)
        c.drawString(spend_x, y - 20, f"~${est_cost}/mo")
        after_spend = spend_x + c.stringWidth(f"~${est_cost}/mo", "Helvetica-Bold", 10)

        c.setFont("Helvetica", 9)
        c.setFillColor(TEXT_LIGHT_GRAY)
        c.drawString(82, y - 36,
            "We can match this site + add an AI receptionist for the same price.")

        # "SWITCH & SAVE" badge
        badge_text = "SWITCH & SAVE"
        badge_w2 = c.stringWidth(badge_text, "Helvetica-Bold", 7) + 12
        badge_x = w - 50 - badge_w2
        badge_y = y - 7
        c.setFillColor(ACCENT_ORANGE_DIM)
        c.roundRect(badge_x, badge_y, badge_w2, 16, 3, fill=1, stroke=0)
        c.setFont("Helvetica-Bold", 7)
        c.setFillColor(TEXT_WHITE)
        c.drawString(badge_x + 6, badge_y + 4.5, badge_text)

        y = box_y - 10

    # ---- Footer (page 1) ----
    _draw_footer(c, w)

    # ---- PAGE 2: Recommendations + CTA ----
    c.showPage()
    _draw_page_background(c, w, h)
    _draw_page_decorations(c, w, h)
    _draw_header(c, w, h)

    y = h - 100
    _draw_section_header(c, w, y, "Recommendations")

    y -= 30

    for i, rec in enumerate(recommendations[:5]):
        if y < 220:
            break  # Leave room for CTA

        # Impact badge setup
        impact_raw = rec.get("impact", "medium")
        impact = impact_raw.upper() if isinstance(impact_raw, str) else "MEDIUM"

        if impact == "HIGH":
            badge_col = SCORE_RED
            badge_bg = SCORE_RED_DIM
            badge_text = "HIGH IMPACT"
            border_col = SCORE_RED
        elif impact in ("MEDIUM", "MODERATE"):
            badge_col = SCORE_YELLOW
            badge_bg = SCORE_YELLOW_DIM
            badge_text = "MODERATE"
            border_col = SCORE_YELLOW
        else:
            badge_col = SCORE_GREEN
            badge_bg = SCORE_GREEN_DIM
            badge_text = "QUICK WIN"
            border_col = SCORE_GREEN

        # Card dimensions
        card_x = 44
        card_w = w - 88
        card_h = 105
        card_y = y - card_h + 15

        # Card background
        c.setFillColor(BG_CARD)
        c.roundRect(card_x, card_y, card_w, card_h, 8, fill=1, stroke=0)

        # Card subtle border
        c.setStrokeColor(DIVIDER)
        c.setLineWidth(0.5)
        c.roundRect(card_x, card_y, card_w, card_h, 8, fill=0, stroke=1)

        # Left accent bar (colored by impact)
        c.setFillColor(border_col)
        c.roundRect(card_x, card_y, 4, card_h, 2, fill=1, stroke=0)

        # Impact badge (pill shape)
        badge_text_w = c.stringWidth(badge_text, "Helvetica-Bold", 7) + 14
        c.setFillColor(badge_bg)
        c.roundRect(62, y + 1, badge_text_w, 16, 8, fill=1, stroke=0)
        c.setFont("Helvetica-Bold", 7)
        c.setFillColor(badge_col)
        c.drawString(69, y + 5, badge_text)

        # Category label (after badge)
        cat_name = rec.get("category", "")
        cat_display = CATEGORY_LABELS.get(cat_name, cat_name.replace("_", " ").title())
        c.setFont("Helvetica", 8)
        c.setFillColor(TEXT_DIM)
        c.drawString(62 + badge_text_w + 8, y + 5, cat_display)

        # Recommendation number
        c.setFont("Helvetica-Bold", 8)
        c.setFillColor(TEXT_DIM)
        num_text = f"#{i + 1}"
        num_w = c.stringWidth(num_text, "Helvetica-Bold", 8)
        c.drawString(card_x + card_w - 14 - num_w, y + 5, num_text)

        # Title
        c.setFont("Helvetica-Bold", 11)
        c.setFillColor(TEXT_WHITE)
        title = rec.get("title", "")
        c.drawString(62, y - 14, title[:68])

        # Description text (use "description" key, fall back to "detail")
        detail = rec.get("description", rec.get("detail", ""))
        c.setFont("Helvetica", 11)
        c.setFillColor(TEXT_WHITE)
        _draw_wrapped_text(c, detail, 62, y - 32, card_w - 40, 11, max_lines=3)

        y -= card_h + 14

    # ---- CTA Section ----
    cta_h = 120
    cta_y = 80

    # CTA outer glow
    c.setFillColor(ACCENT_BLUE_FAINT)
    c.roundRect(35, cta_y - 5, w - 70, cta_h + 10, 14, fill=1, stroke=0)

    # CTA main box
    c.setFillColor(ACCENT_BLUE_DIM)
    c.roundRect(42, cta_y, w - 84, cta_h, 10, fill=1, stroke=0)

    # CTA border
    c.setStrokeColor(ACCENT_BLUE)
    c.setLineWidth(2)
    c.roundRect(42, cta_y, w - 84, cta_h, 10, fill=0, stroke=1)

    # Inner accent line top
    c.setFillColor(ACCENT_BLUE)
    c.rect(60, cta_y + cta_h - 4, w - 120, 2, fill=1, stroke=0)

    # CTA headline
    cta_center = cta_y + cta_h / 2
    c.setFont("Helvetica-Bold", 17)
    c.setFillColor(TEXT_WHITE)
    cta_title = "Hear What Your AI Receptionist Sounds Like"
    ttw = c.stringWidth(cta_title, "Helvetica-Bold", 17)
    c.drawString((w - ttw) / 2, cta_center + 25, cta_title)

    # CTA subtitle
    c.setFont("Helvetica", 10)
    c.setFillColor(HexColor("#BFDBFE"))
    cta_sub = "Free 2-minute demo call. No obligations. Your AI answers in your business name."
    stw = c.stringWidth(cta_sub, "Helvetica", 10)
    c.drawString((w - stw) / 2, cta_center + 6, cta_sub)

    if phone_cta:
        # Phone number — large and prominent
        c.setFont("Helvetica-Bold", 26)
        c.setFillColor(TEXT_WHITE)
        ptw = c.stringWidth(phone_cta, "Helvetica-Bold", 26)
        phone_x = (w - ptw) / 2
        c.drawString(phone_x, cta_center - 28, phone_cta)

        # Decorative dots flanking phone number
        for i in range(4):
            dot_alpha = _lerp_color(ACCENT_BLUE, BG_COLOR, i * 0.25)
            c.setFillColor(dot_alpha)
            c.circle(phone_x - 12 - i * 7, cta_center - 20, 2, fill=1, stroke=0)
            c.circle(phone_x + ptw + 12 + i * 7, cta_center - 20, 2, fill=1, stroke=0)

        # "CALL NOW" micro-label
        c.setFont("Helvetica-Bold", 8)
        c.setFillColor(HexColor("#93C5FD"))
        call_text = "CALL NOW — FREE DEMO"
        ctw = c.stringWidth(call_text, "Helvetica-Bold", 8)
        c.drawString((w - ctw) / 2, cta_center - 44, call_text)
    else:
        c.setFont("Helvetica-Bold", 16)
        c.setFillColor(TEXT_WHITE)
        visit_text = "Visit receptionistai.au"
        vtw = c.stringWidth(visit_text, "Helvetica-Bold", 16)
        c.drawString((w - vtw) / 2, cta_center - 20, visit_text)

    # ---- Footer (page 2) ----
    _draw_footer(c, w)

    c.save()
    return output_path


# ---------------------------------------------------------------------------
# Drawing helpers
# ---------------------------------------------------------------------------

def _draw_page_background(c, w, h):
    """Fill page with dark background."""
    c.setFillColor(BG_COLOR)
    c.rect(0, 0, w, h, fill=1, stroke=0)


def _draw_page_decorations(c, w, h):
    """Add subtle decorative elements to the page for a premium feel."""
    # Top-right corner gradient glow (layered rectangles fading out)
    glow_colors = [
        (HexColor("#0F172A"), 160),
        (HexColor("#0D1320"), 120),
        (HexColor("#0B1018"), 80),
    ]
    for col, size in glow_colors:
        c.setFillColor(col)
        c.circle(w - 20, h - 20, size, fill=1, stroke=0)

    # Bottom-left subtle glow
    c.setFillColor(HexColor("#0E0F1A"))
    c.circle(30, 50, 100, fill=1, stroke=0)

    # Subtle dot grid pattern (very faint)
    c.setFillColor(HexColor("#15161D"))
    for gx in range(0, int(w), 40):
        for gy in range(0, int(h), 40):
            c.circle(gx, gy, 0.5, fill=1, stroke=0)


def _draw_header(c, w, h):
    """Draw top header bar with ReceptionistAI branding."""
    # Header bar background
    c.setFillColor(BG_CARD)
    c.rect(0, h - 65, w, 65, fill=1, stroke=0)

    # Gradient accent line under header (blue to purple)
    steps = 20
    line_h = 3
    segment_w = w / steps
    for i in range(steps):
        t = i / (steps - 1)
        col = _lerp_color(ACCENT_BLUE, ACCENT_PURPLE, t)
        c.setFillColor(col)
        c.rect(i * segment_w, h - 68, segment_w + 1, line_h, fill=1, stroke=0)

    # Brand name
    c.setFont("Helvetica-Bold", 20)
    c.setFillColor(ACCENT_BLUE)
    c.drawString(50, h - 45, "ReceptionistAI")

    # ".au" in lighter style
    brand_w = c.stringWidth("ReceptionistAI", "Helvetica-Bold", 20)
    c.setFont("Helvetica", 11)
    c.setFillColor(TEXT_GRAY)
    c.drawString(50 + brand_w + 2, h - 45, ".au")

    # Right side tagline
    c.setFont("Helvetica", 9)
    c.setFillColor(TEXT_DIM)
    tagline = "AI-Powered Business Intelligence"
    ttw = c.stringWidth(tagline, "Helvetica", 9)
    c.drawString(w - 50 - ttw, h - 42, tagline)

    # Small accent dot before tagline
    c.setFillColor(ACCENT_BLUE)
    c.circle(w - 50 - ttw - 8, h - 39, 2.5, fill=1, stroke=0)


def _draw_section_header(c, w, y, title):
    """Draw a styled section header with decorative underline."""
    c.setFont("Helvetica-Bold", 15)
    c.setFillColor(TEXT_WHITE)
    c.drawString(50, y, title)

    title_w = c.stringWidth(title, "Helvetica-Bold", 15)

    # Decorative underline: colored segments
    line_y = y - 8
    c.setFillColor(ACCENT_BLUE)
    c.rect(50, line_y, title_w * 0.5, 2.5, fill=1, stroke=0)
    c.setFillColor(ACCENT_PURPLE)
    c.rect(50 + title_w * 0.5, line_y, title_w * 0.3, 2.5, fill=1, stroke=0)
    c.setFillColor(ACCENT_CYAN)
    c.rect(50 + title_w * 0.8, line_y, title_w * 0.2, 2.5, fill=1, stroke=0)

    # Fading dots after the line
    dot_start = 50 + title_w + 10
    for i in range(5):
        dot_col = _lerp_color(TEXT_DIM, BG_COLOR, i * 0.2)
        c.setFillColor(dot_col)
        c.circle(dot_start + i * 7, line_y + 1, 1.5, fill=1, stroke=0)


def _draw_footer(c, w):
    """Draw footer with branding and decorative elements."""
    # Footer divider with gradient effect
    steps = 20
    segment_w = w / steps
    for i in range(steps):
        t = i / (steps - 1)
        col = _lerp_color(ACCENT_BLUE, ACCENT_PURPLE, t)
        # Make it very subtle
        col = _lerp_color(BG_COLOR, col, 0.3)
        c.setFillColor(col)
        c.rect(i * segment_w, 42, segment_w + 1, 1, fill=1, stroke=0)

    c.setFont("Helvetica-Bold", 8)
    c.setFillColor(TEXT_GRAY)
    c.drawString(50, 26, "Powered by ReceptionistAI")

    c.setFont("Helvetica", 8)
    c.setFillColor(TEXT_DIM)
    c.drawString(50 + c.stringWidth("Powered by ReceptionistAI  ", "Helvetica-Bold", 8), 26,
                 f"|  receptionistai.au  |  {datetime.now().strftime('%Y')}")

    c.setFont("Helvetica", 7)
    c.setFillColor(HexColor("#475569"))
    disclaimer = "This report was generated using publicly available data and automated analysis."
    dtw = c.stringWidth(disclaimer, "Helvetica", 7)
    c.drawString(w - 50 - dtw, 26, disclaimer)


def _draw_wrapped_text(
    c, text: str, x: float, y: float, max_width: float,
    font_size: float = 9, max_lines: int = 3
):
    """Draw text with word wrapping."""
    if not text:
        return

    words = text.split()
    lines = []
    current_line = ""

    for word in words:
        test_line = f"{current_line} {word}".strip()
        if c.stringWidth(test_line, "Helvetica", font_size) <= max_width:
            current_line = test_line
        else:
            if current_line:
                lines.append(current_line)
            current_line = word

    if current_line:
        lines.append(current_line)

    for i, line in enumerate(lines[:max_lines]):
        if i == max_lines - 1 and len(lines) > max_lines:
            line = line[:len(line) - 3] + "..."
        c.drawString(x, y - (i * (font_size + 3)), line)
