#!/usr/bin/env python3
"""Generate Sunday meal prep PDF — 3 well-designed A4 pages."""

from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm, mm
from reportlab.lib import colors
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, PageBreak,
    Table, TableStyle, HRFlowable,
)
from reportlab.lib.enums import TA_LEFT, TA_CENTER
from datetime import datetime, timezone, timedelta
from pathlib import Path

OUTPUT = Path(__file__).parent / "sunday-meal-prep.pdf"
NOW = datetime.now(timezone(timedelta(hours=10)))

# ===== Color palette =====
INK = colors.HexColor('#1a1a2e')
BLUE = colors.HexColor('#1e5fb0')
ORANGE = colors.HexColor('#c75300')
TEAL = colors.HexColor('#0a7670')
GREY_700 = colors.HexColor('#444')
GREY_500 = colors.HexColor('#777')
GREY_200 = colors.HexColor('#e6e6ea')
TINT_BLUE = colors.HexColor('#eaf2fb')
TINT_ORANGE = colors.HexColor('#fdf1e7')
TINT_TEAL = colors.HexColor('#e7f4f3')
TINT_GREY = colors.HexColor('#f5f5f7')

# ===== Styles =====
base = getSampleStyleSheet()

TITLE = ParagraphStyle('Title', parent=base['Heading1'],
    fontName='Helvetica-Bold', fontSize=22, leading=26,
    spaceAfter=2, textColor=INK)
SUBTITLE = ParagraphStyle('Sub', parent=base['Normal'],
    fontName='Helvetica', fontSize=10, leading=13,
    textColor=GREY_500, spaceAfter=10)
H2 = ParagraphStyle('H2', parent=base['Heading2'],
    fontName='Helvetica-Bold', fontSize=11.5, leading=14,
    spaceBefore=0, spaceAfter=0, textColor=colors.white,
    leftIndent=4)
H2_INK = ParagraphStyle('H2Ink', parent=base['Heading2'],
    fontName='Helvetica-Bold', fontSize=12, leading=15,
    spaceBefore=0, spaceAfter=4, textColor=INK)
BODY = ParagraphStyle('Body', parent=base['Normal'],
    fontName='Helvetica', fontSize=10, leading=14, textColor=INK)
ITEM = ParagraphStyle('Item', parent=base['Normal'],
    fontName='Helvetica', fontSize=10, leading=15,
    leftIndent=4, textColor=INK)
ITEM_BIG = ParagraphStyle('ItemBig', parent=base['Normal'],
    fontName='Helvetica', fontSize=10.5, leading=17,
    leftIndent=4, textColor=INK)
NOTE = ParagraphStyle('Note', parent=base['Normal'],
    fontName='Helvetica-Oblique', fontSize=9, leading=12,
    textColor=GREY_500)
STEP_TIME = ParagraphStyle('StepTime', parent=base['Normal'],
    fontName='Helvetica-Bold', fontSize=11, leading=13,
    textColor=colors.white)
STEP_TITLE = ParagraphStyle('StepTitle', parent=base['Normal'],
    fontName='Helvetica-Bold', fontSize=11.5, leading=14,
    textColor=ORANGE)
DAY_LABEL = ParagraphStyle('Day', parent=base['Normal'],
    fontName='Helvetica-Bold', fontSize=10, leading=13,
    textColor=BLUE)

doc = SimpleDocTemplate(
    str(OUTPUT), pagesize=A4,
    leftMargin=1.5 * cm, rightMargin=1.5 * cm,
    topMargin=1.4 * cm, bottomMargin=1.3 * cm,
    title="Sunday Meal Prep",
    author="Kim Hansen",
)

story = []
PAGE_W = A4[0] - 3.0 * cm  # 18cm usable width


# ===== Helpers =====
def section_header(text, color):
    """Coloured bar with white bold title."""
    t = Table(
        [[Paragraph(text, H2)]],
        colWidths=[PAGE_W],
        rowHeights=[0.78 * cm],
    )
    t.setStyle(TableStyle([
        ('BACKGROUND', (0, 0), (-1, -1), color),
        ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
        ('LEFTPADDING', (0, 0), (-1, -1), 8),
    ]))
    return t


def section_header_col(text, color, width):
    t = Table(
        [[Paragraph(text, H2)]],
        colWidths=[width],
        rowHeights=[0.78 * cm],
    )
    t.setStyle(TableStyle([
        ('BACKGROUND', (0, 0), (-1, -1), color),
        ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
        ('LEFTPADDING', (0, 0), (-1, -1), 8),
    ]))
    return t


def checklist(items, indent=4):
    """List of items with checkbox squares."""
    style = ParagraphStyle(
        'CheckItem', parent=ITEM_BIG,
        leftIndent=indent, bulletIndent=indent)
    paragraphs = []
    for it in items:
        paragraphs.append(Paragraph(f"&#9744;&nbsp;&nbsp;{it}", style))
    return paragraphs


def bullets(items):
    paragraphs = []
    for it in items:
        paragraphs.append(Paragraph(f"&bull;&nbsp;&nbsp;{it}", ITEM))
    return paragraphs


# =====================================================
# PAGE 1: SHOPPING LIST
# =====================================================
story.append(Paragraph("Sunday Coles Shop", TITLE))
story.append(Paragraph(
    f"{NOW.strftime('%A, %d %B %Y')} &nbsp;&middot;&nbsp; Brisbane "
    "&nbsp;&middot;&nbsp; Bryan-Johnson-influenced longevity protocol",
    SUBTITLE))
story.append(HRFlowable(
    width="100%", thickness=0.6, color=GREY_200, spaceBefore=0, spaceAfter=8))

# === Two-column shopping list ===
COL_W = (PAGE_W - 0.8 * cm) / 2

left_items = []
left_items.append(section_header_col("WEEKLY FRESH", BLUE, COL_W))
left_items.append(Spacer(1, 4))
for it in [
    "Tomatoes (8&ndash;10)",
    "Red onions (2)",
    "Bananas (4)",
    "Lemons (2)",
    "Limes (4)",
    "Garlic (1 bulb)",
    "Ginger root (~50g)",
    "Kale (1 bunch)",
    "Swiss brown / shiitake mushrooms (250g)",
    "Sweet potato (~800g)",
    "Zucchini (3)",
    "Avocados (4&ndash;5)",
]:
    left_items.append(Paragraph(f"&#9744;&nbsp;&nbsp;{it}", ITEM_BIG))

left_items.append(Spacer(1, 6))
left_items.append(section_header_col("REFRIGERATED", BLUE, COL_W))
left_items.append(Spacer(1, 4))
for it in [
    "Chobani 0% Plain Greek Yoghurt 1kg",
    "Free range eggs (12 pack)",
    "Suzie's Macadamia Milk Unsweetened 1L &times; 2",
    "Vitasoy Unsweetened Soy Milk 1L  (for oats)",
]:
    left_items.append(Paragraph(f"&#9744;&nbsp;&nbsp;{it}", ITEM_BIG))

left_items.append(Spacer(1, 6))
left_items.append(section_header_col("FISH / CHICKEN", BLUE, COL_W))
left_items.append(Spacer(1, 4))
for it in [
    "Salmon fillet skin-on (600g)",
    "Barramundi fillet (200g)",
    "Chicken thigh fillet (400g)",
]:
    left_items.append(Paragraph(f"&#9744;&nbsp;&nbsp;{it}", ITEM_BIG))

left_items.append(Spacer(1, 6))
left_items.append(section_header_col("FROZEN", BLUE, COL_W))
left_items.append(Spacer(1, 4))
for it in [
    "Macro Frozen Blueberries 1kg",
    "Coles Frozen Broccoli Florets 1kg",
    "Coles Frozen Cauliflower 1kg",
]:
    left_items.append(Paragraph(f"&#9744;&nbsp;&nbsp;{it}", ITEM_BIG))

right_items = []
right_items.append(section_header_col(
    "PANTRY  (every 4&ndash;8 weeks)", TEAL, COL_W))
right_items.append(Spacer(1, 4))
for it in [
    "Macro Black Beluga Lentils 500g",
    "Macro Whole Rolled Oats 1.5kg",
    "SunRice Brown Rice 1kg",
    "San Remo Wholemeal Penne 500g",
    "Walnut halves 250g",
    "Macadamia nuts 250g",
    "Lucky Brazil Nuts 200g",
    "Macro Chia Seeds 500g",
    "Macro Hulled Hemp Seeds 250g",
    "Ground flaxseed / linseed meal 250g",
    "Cobram Estate Robust EVOO 750ml",
    "Bragg Apple Cider Vinegar 473ml",
    "Nature's Way Raw Organic Cacao Powder 125g",
    "Ceylon cinnamon (G Fresh)",
    "Ground cumin",
    "Macro Psyllium Husk 200g",
]:
    right_items.append(Paragraph(f"&#9744;&nbsp;&nbsp;{it}", ITEM_BIG))

shop_table = Table(
    [[left_items, right_items]],
    colWidths=[COL_W, COL_W],
)
shop_table.setStyle(TableStyle([
    ('VALIGN', (0, 0), (-1, -1), 'TOP'),
    ('LEFTPADDING', (0, 0), (-1, -1), 0),
    ('RIGHTPADDING', (0, 0), (0, 0), 0.4 * cm),
    ('RIGHTPADDING', (1, 0), (1, 0), 0),
    ('TOPPADDING', (0, 0), (-1, -1), 0),
    ('BOTTOMPADDING', (0, 0), (-1, -1), 0),
]))
story.append(shop_table)

# Footer: stats card
story.append(Spacer(1, 14))
stats = Table([[
    Paragraph("<b>Weekly target</b><br/>~$95", BODY),
    Paragraph("<b>First pantry shop</b><br/>+~$140", BODY),
    Paragraph("<b>Yearly saving vs old plan</b><br/>~$2,600", BODY),
    Paragraph("<b>Eating window</b><br/>10am &ndash; 7pm", BODY),
]], colWidths=[PAGE_W / 4] * 4)
stats.setStyle(TableStyle([
    ('BACKGROUND', (0, 0), (-1, -1), TINT_BLUE),
    ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
    ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
    ('TOPPADDING', (0, 0), (-1, -1), 10),
    ('BOTTOMPADDING', (0, 0), (-1, -1), 10),
    ('LINEAFTER', (0, 0), (-2, -1), 0.4, GREY_200),
]))
story.append(stats)

story.append(PageBreak())

# =====================================================
# PAGE 2: SUNDAY PREP WORKFLOW
# =====================================================
story.append(Paragraph("Sunday Meal Prep", TITLE))
story.append(Paragraph(
    "45 minutes &nbsp;&middot;&nbsp; Yields 3&times; Super Veggie + "
    "2&times; Nutty Pudding + leftover roast veg tray",
    SUBTITLE))
story.append(HRFlowable(
    width="100%", thickness=0.6, color=GREY_200, spaceBefore=0, spaceAfter=10))


def step_card(timestamp, title, body_items, accent=ORANGE, tint=TINT_ORANGE):
    """One step card: timestamp on left, title + bullets on right, tint bg."""
    time_cell = Table(
        [[Paragraph(timestamp, STEP_TIME)]],
        colWidths=[2.6 * cm], rowHeights=[1.0 * cm],
    )
    time_cell.setStyle(TableStyle([
        ('BACKGROUND', (0, 0), (-1, -1), accent),
        ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
        ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
    ]))

    body_paragraphs = [Paragraph(title, STEP_TITLE)]
    for it in body_items:
        body_paragraphs.append(Paragraph(f"&bull;&nbsp;&nbsp;{it}", ITEM))

    body_cell = Table(
        [[body_paragraphs]],
        colWidths=[PAGE_W - 2.6 * cm],
    )
    body_cell.setStyle(TableStyle([
        ('VALIGN', (0, 0), (-1, -1), 'TOP'),
        ('LEFTPADDING', (0, 0), (-1, -1), 12),
        ('RIGHTPADDING', (0, 0), (-1, -1), 8),
        ('TOPPADDING', (0, 0), (-1, -1), 6),
        ('BOTTOMPADDING', (0, 0), (-1, -1), 8),
        ('BACKGROUND', (0, 0), (-1, -1), tint),
    ]))

    card = Table(
        [[time_cell, body_cell]],
        colWidths=[2.6 * cm, PAGE_W - 2.6 * cm],
    )
    card.setStyle(TableStyle([
        ('VALIGN', (0, 0), (-1, -1), 'TOP'),
        ('LEFTPADDING', (0, 0), (-1, -1), 0),
        ('RIGHTPADDING', (0, 0), (-1, -1), 0),
        ('TOPPADDING', (0, 0), (-1, -1), 0),
        ('BOTTOMPADDING', (0, 0), (-1, -1), 0),
    ]))
    return card


steps = [
    ("0:00", "START LENTILS  (15 min hands-off)", [
        "200g black/beluga lentils + 600ml water",
        "Boil, reduce to simmer, cook 18 min uncovered",
        "Drain, rinse cold, set aside",
    ], ORANGE, TINT_ORANGE),
    ("0:00", "PREHEAT OVEN to 200&deg;C", [
        "Run while lentils simmer &mdash; no separate time slot",
    ], BLUE, TINT_BLUE),
    ("0:05", "PREP ROAST TRAY  (5 min prep + 25 min oven)", [
        "1.5 head broccoli (florets + chopped stalk)",
        "1 head cauliflower (florets)",
        "200g mushrooms",
        "4 cloves garlic (whole, peeled)",
        "Thumb of ginger (sliced)",
        "Drizzle EVOO + salt + pepper &middot; roast 25 min at 200&deg;C",
    ], ORANGE, TINT_ORANGE),
    ("0:10", "MIX NUTTY PUDDING JARS  (&times; 2)", [
        "<b>Per jar &mdash; ~790 kcal &middot; 38g protein &middot; 17g fibre</b>",
        "2 scoops (73g) Blueprint Metabolic Protein",
        "30g ground macadamia (~3 Tbsp)",
        "20g chia seeds (~2 Tbsp) &middot; 10g ground walnut (~1 Tbsp)",
        "&frac14; Brazil nut (grated) &middot; 1 Tbsp raw cacao",
        "&frac12; tsp Ceylon cinnamon &middot; &frac14; tsp vanilla extract",
        "250ml macadamia milk",
        "Stir well, lid on, fridge (chia thickens overnight)",
        "<b>When serving:</b> top with 75g fresh berries",
    ], TEAL, TINT_TEAL),
    ("0:30", "ASSEMBLE SUPER VEGGIE  (&times; 3)", [
        "<b>Per serving:</b> &#8531; lentils + &#8531; roast veg",
        "Juice of 1 lime + 1 Tbsp ACV + 1 Tbsp ground cumin",
        "Blend chunky &middot; portion into 3 containers",
        "<b>When serving:</b> top with hemp seeds + EVOO drizzle "
        "(do NOT add now &mdash; oxidises in fridge)",
    ], TEAL, TINT_TEAL),
    ("0:45", "DONE", [
        "<b>Fridge inventory:</b> 3&times; Super Veggie &middot; "
        "2&times; Nutty Pudding &middot; leftover roast veg tray",
        "Sat &amp; Sun lunches: free choice",
    ], BLUE, TINT_BLUE),
]

for timestamp, title, body_items, accent, tint in steps:
    story.append(step_card(timestamp, title, body_items, accent, tint))
    story.append(Spacer(1, 7))

story.append(PageBreak())

# =====================================================
# PAGE 3: WEEK CHEATSHEET
# =====================================================
story.append(Paragraph("This Week's Meals", TITLE))
story.append(Paragraph(
    "Eating window 10am &ndash; 7pm &nbsp;&middot;&nbsp; "
    "~2,200 kcal &nbsp;&middot;&nbsp; 130g protein &nbsp;&middot;&nbsp; "
    "45g fibre &nbsp;&middot;&nbsp; ApoB target &lt;0.85",
    SUBTITLE))
story.append(HRFlowable(
    width="100%", thickness=0.6, color=GREY_200, spaceBefore=0, spaceAfter=10))

# === Two-column meal layout ===
LEFT_W = PAGE_W * 0.56
RIGHT_W = PAGE_W * 0.44 - 0.4 * cm

# LEFT COLUMN: 10AM breakfast trio
left = []

left.append(section_header_col(
    "10AM &middot; SMOOTHIE   (every day)", BLUE, LEFT_W))
left.append(Spacer(1, 5))
for line in [
    "200g Chobani 0% Greek yoghurt",
    "150g frozen blueberries",
    "200ml macadamia milk",
    "1 egg",
    "5g psyllium husk  (1 tsp)",
    "20g Blueprint Collagen  (1 scoop)",
    "20g hemp seed protein powder  (~2 Tbsp)",
    "10g black chia seeds  (1 Tbsp)",
    "10g ground flaxseed meal  (1 Tbsp)",
    "30g walnuts (ground)",
    "5g raw cacao  (1 Tbsp)",
    "&frac14; Brazil nut",
    "&frac12; tsp Ceylon cinnamon",
]:
    left.append(Paragraph(f"&bull;&nbsp;&nbsp;{line}", ITEM))
left.append(Spacer(1, 5))
left.append(Paragraph(
    "<b>Take with:</b> Blueprint Essentials &middot; Omega-3 &middot; "
    "B-complex &middot; Creatine 2.5g", NOTE))
left.append(Paragraph(
    "<b>Skip:</b> honey (HbA1c) &middot; multivitamin "
    "(Essentials covers it)", NOTE))
left.append(Paragraph(
    "<b>Tip:</b> drink ~1h pre-strength training to boost tendon "
    "collagen synthesis (Shaw, AJCN 2017)", NOTE))

left.append(Spacer(1, 10))
left.append(section_header_col(
    "10AM &middot; OAT BOWL   (daily, separate)", TEAL, LEFT_W))
left.append(Spacer(1, 5))
for line in [
    "40g rolled oats  (~3g beta-glucan, ApoB dose)",
    "200ml Vitasoy unsweetened soy milk  (creamier + 7g protein)",
    "Simmer 5 min until thick",
    "<b>Top:</b> pinch Ceylon cinnamon + 1 tsp EVOO drizzle",
]:
    left.append(Paragraph(f"&bull;&nbsp;&nbsp;{line}", ITEM))

left.append(Spacer(1, 10))
left.append(section_header_col(
    "10AM &middot; AVOCADO SIDE   (3&ndash;5&times;/week)",
    ORANGE, LEFT_W))
left.append(Spacer(1, 5))
for line in [
    "&frac12; avocado  (whole occasionally)",
    "Pinch Himalayan salt",
    "1 tsp Cobram Robust EVOO",
    "Splash apple cider vinegar",
    "<b>Cap:</b> ~2 Tbsp EVOO daily &mdash; skip drizzle on oats today",
]:
    left.append(Paragraph(f"&bull;&nbsp;&nbsp;{line}", ITEM))

# RIGHT COLUMN: lunch + dinner + evening
right = []

right.append(section_header_col("1PM &middot; LUNCH", BLUE, RIGHT_W))
right.append(Spacer(1, 5))
lunch_table = Table([
    ["Mon / Wed / Fri", "Super Veggie\n+ hemp seeds, EVOO drizzle"],
    ["Tue / Thu", "Nutty Pudding\n+ 75g fresh berries"],
    ["Sat / Sun", "Free choice"],
], colWidths=[2.9 * cm, RIGHT_W - 2.9 * cm])
lunch_table.setStyle(TableStyle([
    ('FONT', (0, 0), (-1, -1), 'Helvetica', 9.5),
    ('FONT', (0, 0), (0, -1), 'Helvetica-Bold', 9.5),
    ('TEXTCOLOR', (0, 0), (0, -1), BLUE),
    ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
    ('ROWBACKGROUNDS', (0, 0), (-1, -1), [TINT_BLUE, colors.white]),
    ('LEFTPADDING', (0, 0), (-1, -1), 8),
    ('RIGHTPADDING', (0, 0), (-1, -1), 8),
    ('TOPPADDING', (0, 0), (-1, -1), 8),
    ('BOTTOMPADDING', (0, 0), (-1, -1), 8),
]))
right.append(lunch_table)

right.append(Spacer(1, 10))
right.append(section_header_col(
    "6:30PM &middot; DINNER   (finish by 7pm)", ORANGE, RIGHT_W))
right.append(Spacer(1, 5))
right.append(Paragraph(
    "<b>Plate:</b> &frac12; veg + &frac14; protein + &frac14; complex carb",
    ITEM))
right.append(Paragraph(
    "<b>Daily side:</b> tomato + red onion + EVOO + ACV", ITEM))
right.append(Spacer(1, 5))
dinner_table = Table([
    ["MON", "Salmon + brown rice + roast veg"],
    ["TUE", "Chicken thigh + sweet potato + kale"],
    ["WED", "Salmon + wholewheat penne + zucchini"],
    ["THU", "Barramundi + brown rice + broccoli"],
    ["FRI", "Salmon + sweet potato + cauliflower"],
    ["SAT", "Chicken thigh + brown rice + veg"],
    ["SUN", "Salmon + potato + kale"],
], colWidths=[1.4 * cm, RIGHT_W - 1.4 * cm])
dinner_table.setStyle(TableStyle([
    ('FONT', (0, 0), (-1, -1), 'Helvetica', 9.5),
    ('FONT', (0, 0), (0, -1), 'Helvetica-Bold', 9),
    ('TEXTCOLOR', (0, 0), (0, -1), ORANGE),
    ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
    ('ALIGN', (0, 0), (0, -1), 'CENTER'),
    ('ROWBACKGROUNDS', (0, 0), (-1, -1), [TINT_ORANGE, colors.white]),
    ('LEFTPADDING', (0, 0), (-1, -1), 8),
    ('RIGHTPADDING', (0, 0), (-1, -1), 8),
    ('TOPPADDING', (0, 0), (-1, -1), 7),
    ('BOTTOMPADDING', (0, 0), (-1, -1), 7),
]))
right.append(dinner_table)

right.append(Spacer(1, 10))
right.append(section_header_col(
    "9PM &middot; EVENING", TEAL, RIGHT_W))
right.append(Spacer(1, 5))
right.append(Paragraph(
    "&bull;&nbsp;&nbsp;Herbal tea", ITEM))
right.append(Paragraph(
    "&bull;&nbsp;&nbsp;Magnesium glycinate 400mg", ITEM))
right.append(Paragraph(
    "&bull;&nbsp;&nbsp;Stop fluids by 4pm to minimise night wakings", ITEM))

# Combine columns
meals_table = Table(
    [[left, right]],
    colWidths=[LEFT_W, RIGHT_W + 0.4 * cm],
)
meals_table.setStyle(TableStyle([
    ('VALIGN', (0, 0), (-1, -1), 'TOP'),
    ('LEFTPADDING', (0, 0), (-1, -1), 0),
    ('RIGHTPADDING', (0, 0), (0, 0), 0.4 * cm),
    ('RIGHTPADDING', (1, 0), (1, 0), 0),
    ('TOPPADDING', (0, 0), (-1, -1), 0),
    ('BOTTOMPADDING', (0, 0), (-1, -1), 0),
]))
story.append(meals_table)

doc.build(story)
print(f"Generated: {OUTPUT}")
