"""Generate docs/Demo_Quick_Notes.docx — short user guide for the demo bundle."""
from pathlib import Path
from docx import Document
from docx.shared import Pt, RGBColor
from docx.enum.text import WD_ALIGN_PARAGRAPH

OUT = Path(__file__).parent / "docs" / "Demo_Quick_Notes.docx"
OUT.parent.mkdir(exist_ok=True)


def h(d, text, level=1):
    p = d.add_heading(text, level=level)
    color = RGBColor(0x1F, 0x3A, 0x5F) if level == 1 else RGBColor(0x2F, 0x54, 0x96)
    for r in p.runs:
        r.font.color.rgb = color


def p(d, text):
    d.add_paragraph(text)


def b(d, text):
    d.add_paragraph(text, style="List Bullet")


def code(d, text):
    para = d.add_paragraph()
    run = para.add_run(text)
    run.font.name = "Consolas"
    run.font.size = Pt(9)


def page_block(d, title, what, try_items, why=None):
    h(d, title, level=2)
    p(d, what)
    pa = d.add_paragraph()
    r = pa.add_run("Try:")
    r.bold = True
    for t in try_items:
        b(d, t)
    if why:
        pa = d.add_paragraph()
        r = pa.add_run("Why it matters: ")
        r.bold = True
        pa.add_run(why)


# ============================================================
d = Document()
style = d.styles["Normal"]
style.font.name = "Calibri"
style.font.size = Pt(11)

# ---- Title ----
t = d.add_paragraph()
t.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = t.add_run("Demand Planning Demo — Quick Notes")
run.bold = True
run.font.size = Pt(22)
run.font.color.rgb = RGBColor(0x1F, 0x3A, 0x5F)
s = d.add_paragraph()
s.alignment = WD_ALIGN_PARAGRAPH.CENTER
r = s.add_run("How to install, what every page does, what to look at first")
r.italic = True
r.font.size = Pt(12)
r.font.color.rgb = RGBColor(0x55, 0x55, 0x55)
d.add_paragraph()

# ============================================================
h(d, "1. What this demo is")
p(d, "A self-contained, fully synthetic version of a demand-forecasting and "
     "S&OP planning tool. 50 fictional SKUs across 8 categories, 26 weeks of "
     "made-up sales history, dummy KAM commitments, dummy stock data. "
     "Nothing here is real-company data — it is safe to share, screenshot, "
     "and explore freely.")
p(d, "The demo runs entirely on your laptop. No cloud, no database, no login. "
     "Streamlit serves the UI in your browser at http://localhost:8501.")

# ============================================================
h(d, "2. Install & launch")
p(d, "Pre-requisite: Python 3.12 (https://www.python.org/downloads/release/python-3120/). "
     "Tick \"Add Python to PATH\" during install. Do NOT use Python 3.14 — scipy "
     "has no wheels for it yet.")

h(d, "Windows", level=2)
b(d, "Unzip the bundle. Double-click Start_Demo.bat.")
b(d, "If Windows blocks it: right-click Start_Demo.bat → Properties → tick \"Unblock\" → OK.")
b(d, "If a corporate policy blocks .bat files: double-click Start_Demo.cmd instead.")
b(d, "First run takes ~3 minutes (pip install, dummy data, baseline forecast). "
     "After that, every launch is instant.")

h(d, "macOS / Linux", level=2)
code(d, "cd Demo\nchmod +x start_demo.sh\n./start_demo.sh")

h(d, "Manual fallback (any OS)", level=2)
code(d, "python -m pip install -r requirements.txt\n"
        "python launcher.py")

# ============================================================
h(d, "3. The sidebar — module switcher")
p(d, "Top-left of the app there is a Demand / Supply switch. The Demand module "
     "covers everything from sales import to S&OP committed plan. The Supply "
     "module covers stock, coverage, ordering. Both share the same data files.")

# ============================================================
h(d, "4. Demand module pages")

page_block(d,
    "Dashboard",
    "Landing page — top KPIs and last-update status across the whole portfolio.",
    ["Scan the headline figures: 50 SKUs, ~1.3M units 26-week run rate, "
     "tier breakdown.",
     "Check the 'Last updated' timestamps so you know whether the data is fresh."],
    why="Quick health-check before each weekly cycle.")

page_block(d,
    "Update sales",
    "Imports a weekly sales export from the ERP, cleans outliers, recalculates "
    "uplift factors. In the demo, the sales file is already there, so this page "
    "is mostly a placeholder.",
    ["Click \"Recalculate uplift\" to see how sku_uplift.csv and cat_uplift.csv "
     "are regenerated from the ERP promo calendar."],
    why="In production this is where every Monday's new data arrives.")

page_block(d,
    "Run forecast",
    "The 13-week forecasting engine. Uses Nixtla StatsForecast with "
    "channel-split (retail vs wholesale) and ABC/XYZ-aware model selection.",
    ["Click Run Forecast — takes ~30-60 seconds. Watch the console log behind the app.",
     "Once done, all downstream pages (Demand Planning, Revenue, Supply) "
     "immediately reflect the new forecast.",
     "Backtest summary appears at the end — Engine FA on dummy data is ~92%."],
    why="The single most important action in the weekly cycle.")

page_block(d,
    "Demand planning",
    "Per-SKU view of baseline forecast vs. last 26 weeks of run rate, plus "
    "VP/MP commitments stacked on top. Planner can override any week with a "
    "Planner Factor (1.10 = +10%, 0.90 = -10%).",
    ["Use the Tier filter (Gold / Silver / Bronze) and Category filter "
     "to zoom in.",
     "Set a planner factor on a few SKUs — saved automatically.",
     "Try the Review column filter — flags SKUs where the next 4 weeks of "
     "forecast diverge by more than 25% from the last 4 weeks of actuals."],
    why="The day-to-day work surface for the demand planner.")

page_block(d,
    "VP input / MP input",
    "Read-only views of the wholesale (VP) and retail (MP) on-top commitments "
    "after they have been combined per SKU. The VP file in the demo has 20 "
    "SKUs across 4 buyers (Konzum, Spar, DM, Kaufland); MP has 15 SKUs.",
    ["Filter by week (CW column) — see who has committed what for next quarter.",
     "Cross-check totals against the source files in data/vp_input.csv."])

page_block(d,
    "Revenue",
    "€ projection by category and channel for the next 13 weeks. Toggle Revenue "
    "vs RUC (margin) view, filter by VP-only or MP-only source.",
    ["Switch to RUC view — see margin contribution, not just turnover.",
     "Toggle 'include non-planned SKUs' — applies a gross-up multiplier so "
     "the chart reflects the full ~€7M RUC instead of just the 50 forecasted SKUs.",
     "The chart line crossing the dotted boundary marks today — past = actuals, "
     "future = forecast."])

page_block(d,
    "SKU management",
    "Master list of all 50 demo SKUs. Edit names, categories, tiers (Oznaka), "
    "or status (active / inactive).",
    ["Change a tier on one SKU and save — see the Demand Planning tier filter "
     "respect the change immediately."])

page_block(d,
    "KAM inputs",
    "Three tabs: Base inputs, Slack cycle, Combined view. In the demo, Slack is "
    "disabled (no token) but template generation and combine still work locally.",
    ["Click Generate templates — produces multi-sheet Excel files. Selma's file "
     "has 7 sheets (one per buyer); Ivan's has 1.",
     "Open the generated Excel, fill some numbers, save, drag it back into "
     "the Base inputs uploader.",
     "Combined view shows what's currently in vp_input.csv / mp_input.csv."])

page_block(d,
    "Download",
    "One-click bundle of every CSV + the master xlsx, zipped.",
    ["Useful for emailing a snapshot to a stakeholder."])

page_block(d,
    "Forecast accuracy",
    "Three tabs: Global FA (model vs actuals), KAM/CM projections FA "
    "(commitment vs actual sell-through), Model-only FA (baseline minus "
    "planner-owned channel).",
    ["Toggle 'Apply Planner Factor' — see how much planner adjustments "
     "improve / worsen FA.",
     "Switch the Weekly tab to Monthly tab — weekly metrics are average of "
     "per-week FAs, monthly metrics are sum-then-divide. The demo loads "
     "8 weeks of synthetic backtest data.",
     "Scroll down to FA TOP 10 Impactors — top 3 categories that week, "
     "top 10 worst-performing SKUs in each."],
    why="Where 'is the forecast actually any good' is answered.")

page_block(d,
    "Top 30 watchlist",
    "The 30 SKUs the planner should look at first this week — biggest "
    "expected jump, biggest miss last week, biggest VP commitment.",
    ["Filter by reason (volatility / commitment / accuracy) to triage."])

page_block(d,
    "Consensus plan",
    "Frozen, S&OP-signed-off version of the demand plan. Re-runs of the "
    "forecast do not overwrite this until you explicitly snapshot.",
    ["Click 'Snapshot current plan as consensus' — saves a JSON snapshot "
     "in data/consensus/."])

page_block(d,
    "S&OP meeting",
    "Executive view designed for the monthly S&OP slot. One screen, big numbers, "
    "tier-level and category-level rollups, alerts.",
    ["Resize the browser — the layout adapts to projector resolution."])

page_block(d,
    "ERP promos",
    "View and lightly edit the ERP-sourced promo calendar that drives uplift.",
    ["Add a fake promo for next week on one SKU — observe how its forecast "
     "moves up after re-running the engine."])

# ============================================================
h(d, "5. Supply module pages")

page_block(d,
    "Supply — Stock projection",
    "Roll-forward stock × forecast × incoming PO over the next 13 weeks. "
    "Includes the long-tail (untiered) SKUs via a trailing 13-week-average "
    "synthetic forecast — so total picture for finance is complete.",
    ["Look for SKUs with closing-stock-units flat but closing-€ dropping — "
     "that's mix shift toward cheaper goods.",
     "Toggle store-stock inclusion (HR / AT / SLO)."])

page_block(d,
    "Supply — Coverage",
    "Weeks-of-cover per SKU = on_hand / avg_weekly_forecast. WH-only stock.",
    ["Sort by ascending coverage — those are stockout candidates.",
     "Click on a SKU to see the underlying calculation."])

page_block(d,
    "Supply — Alerts / Order entry",
    "Suggested order quantities (MOQ-aware, lead-time-aware) for SKUs "
    "below target coverage.",
    ["Default target coverage = 8 weeks. Bump to 12 — see how many SKUs "
     "newly need ordering."])

page_block(d,
    "Supply — Upload",
    "5-block upload page for stock, store stock (HR/AT/SLO), incoming POs, "
    "supply master, cost prices. Smart column detection (Croatian ERP "
    "headers like Šifra, Zaliha, Nabavna are recognised automatically).",
    ["The demo's data is already loaded; this page is here so you can see "
     "how a real client onboards their data."])

# ============================================================
h(d, "6. Where to start — 10-minute tour")
b(d, "1. Dashboard — read the headline KPIs.")
b(d, "2. Run forecast — click it, wait 60s, watch the console.")
b(d, "3. Demand planning — set a planner factor on one Gold SKU.")
b(d, "4. Revenue — switch between Revenue and RUC views.")
b(d, "5. Forecast accuracy — toggle Apply Planner Factor on/off.")
b(d, "6. Supply → Stock projection — see the 13-week roll-forward.")
b(d, "7. KAM inputs → Slack cycle → Generate templates — open one of the "
     "generated Excel files to see the per-buyer sheet split.")

# ============================================================
h(d, "7. Stop, start over, customise")
b(d, "Stop the app: press Ctrl+C in the launcher window, or close it.")
b(d, "Reset the dummy data: delete the `data/` folder, re-run the launcher.")
b(d, "Different SKU count or seed: edit generate_demo_data.py — `random.seed(42)` "
     "and the CATS dict at the top. Then re-run `python generate_demo_data.py`.")
b(d, "Change the colour theme: edit .streamlit/config.toml.")

# ============================================================
h(d, "8. Troubleshooting one-pager")
table = d.add_table(rows=1, cols=2)
table.style = "Light Grid Accent 1"
hdr = table.rows[0].cells
hdr[0].text = "Symptom"
hdr[1].text = "Fix"
for r in hdr:
    for para in r.paragraphs:
        for run in para.runs:
            run.bold = True

troubles = [
    ("Double-click does nothing.",
     "Right-click the .bat → Properties → Unblock → OK. Or use Start_Demo.cmd."),
    ("Window flashes and closes.",
     "Run from CMD: cd into Demo, type `Start_Demo.bat`. CMD stays open and "
     "shows the actual error."),
    ("pip install fails on scipy.",
     "You are on Python 3.13 or 3.14. Install Python 3.12 instead."),
    ("\"Address already in use\" / port 8501 taken.",
     "Run: `python -m streamlit run app.py --server.port 8502`"),
    ("\"No forecast accuracy data yet\".",
     "Click \"Run walk-forward backtest\" on the FA page (or `python run_backtest.py`)."),
    ("Slack tab shows token error.",
     "Expected — the demo has no token. All other tabs work."),
    ("Forecast looks weird after editing data.",
     "Click Run Forecast again. The cache holds for 60 seconds."),
]
for sym, fix in troubles:
    row = table.add_row().cells
    row[0].text = sym
    row[1].text = fix

# ============================================================
h(d, "9. What the demo is NOT")
b(d, "Not connected to any real ERP, Slack workspace, email, or cloud.")
b(d, "Not licensed for production use without explicit permission.")
b(d, "Not optimised for >500 SKUs — the engine handles a few thousand "
     "but the demo is sized for fast first-run experience.")
b(d, "Not a substitute for the three deeper docs in this folder "
     "(01_Kratki_Vodic_Workflow, 02_Arhitektura_Podataka, "
     "03_Logika_Forecast_i_Supply) — those describe the full production "
     "system in Croatian and are the source of truth.")

d.save(OUT)
size_kb = OUT.stat().st_size // 1024
print(f"Generated: {OUT}  ({size_kb} KB)")
