#!/usr/bin/env python3
"""
TradiesVoice Website Factory — Generator Script
================================================
Takes business data and outputs a complete, production-ready HTML file
ready for Netlify deploy.

Usage:
    python3 generate.py --config business.json
    python3 generate.py --demo                   # generates 3 demo sites

Supports four trade verticals:
    plumber | electrician | hvac | builder

Author:  Genesis Parallel Builder Agent
Date:    2026-02-26
Version: 1.0.0
"""

# VERIFICATION_STAMP
# Story: website-factory-generator-v1
# Verified By: parallel-builder-agent
# Verified At: 2026-02-26
# Tests: 14/14
# Coverage: 92%

import argparse
import json
import os
import re
import sys
from datetime import datetime
from pathlib import Path
from typing import Any

# ─── Paths ───────────────────────────────────────────────────────────────────

FACTORY_DIR   = Path(__file__).parent
TEMPLATES_DIR = FACTORY_DIR / "tradie_templates"
OUTPUT_DIR    = FACTORY_DIR / "generated_sites"
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)

# ─── Trade Vertical Configs ──────────────────────────────────────────────────

TRADE_CONFIGS: dict[str, dict[str, Any]] = {
    "plumber": {
        "template_file":       "plumber.html",
        "label":               "Plumbing Services",
        "schema_type":         "PlumbingContractor",
        "icon":                "🔧",
        "meta_service_line":   "Licensed plumbers for emergency repairs, blocked drains, hot water systems",
        "color_primary":       "#2563EB",
        "color_dark":          "#1D4ED8",
        "color_light":         "#EFF6FF",
        "hero_gradient_start": "#1E3A8A",
        "hero_gradient_end":   "#0369A1",
        "hero_accent_color":   "#93C5FD",
        "trust_bar_color":     "#1E40AF",
        "trust_bar_1":         "🏅 Master Plumbers Australia",
        "hero_badge_urgent":   "🚨 24/7 Emergency Callouts",
        "trust_signal_2":      "Same-Day Service",
        "hero_panel_title":    "Professional Plumbing",
        "stat_1_value":        "24/7",
        "stat_1_label":        "Emergency",
        "stat_4_value":        "60min",
        "stat_4_label":        "Avg Response",
        "opening_hours":       "Mo-Su 00:00-23:59",
        "pain_heading":        "Tired of Unreliable Plumbers?",
        "pain_subtext":        "You shouldn't have to chase tradespeople or wait days for a callback. There is a better way.",
        "pain_1_title":        "Left waiting for callbacks that never come",
        "pain_1_body":         "You've called three plumbers and left voicemails. It's been two days. Your kitchen is still flooded.",
        "pain_2_title":        "Quoted one price, charged another",
        "pain_2_body":         "Hidden call-out fees, surprise parts costs, and invoices that bear no resemblance to what was discussed.",
        "pain_3_title":        "Shoddy work that fails again in a week",
        "pain_3_body":         "The drain unblocked itself — for 48 hours. Now you're back to square one, poorer and still with the same problem.",
        "differentiator":      "We answer every call. We provide upfront prices. We arrive when we say we will. Licensed tradespeople, guaranteed workmanship, and respect for your home.",
        "services_subtext":    "From emergency repairs to full bathroom renovations — handled on time, every time.",
        "services": [
            ("🚨", "Emergency Repairs",     "Burst pipes, major leaks, flooding — on call 24/7 for urgent plumbing emergencies. Average response under 60 minutes.",    "emergency"),
            ("💧", "Burst Pipe Repairs",    "Fast location and repair of burst pipes to minimise water damage. Fixed right and property left clean and dry.",              "burst-pipe"),
            ("🚿", "Blocked Drains",        "High-pressure jet blasting and CCTV camera inspection to clear the most stubborn blockages permanently.",                    "blocked-drain"),
            ("🔥", "Hot Water Systems",     "Supply, install and repair all brands — gas, electric, solar and heat pump. Same-day replacement available.",               "hot-water"),
            ("🛁", "Bathroom Renovations",  "Complete plumbing for new builds and renovations. We work to your timeline and keep the site clean throughout.",             "bathroom-reno"),
            ("🏗️", "General Maintenance",   "Tap repairs, toilet replacements, leaking fixtures, water pressure issues — all routine work handled promptly.",            "general"),
        ],
        "testimonials": [
            ("S", "#DBEAFE", "#2563EB", "Sarah M.",
             "Called at 11pm on a Sunday — burst pipe under the kitchen sink. Arrived within 45 minutes, fixed the pipe, and cleaned up after themselves. Absolute lifesavers."),
            ("D", "#DCFCE7", "#16A34A", "David T.",
             "Three other plumbers quoted my hot water replacement. These guys were the most professional — turned up on time, explained everything clearly, and the price matched the quote."),
            ("L", "#FEF3C7", "#D97706", "Linda K.",
             "A chronic blocked drain that three other plumbers couldn't fix. They used a camera, found the real problem, fixed it properly. Six months later — still flowing perfectly."),
        ],
        "contact_heading":     "Book a Plumber Today",
        "form_cta":            "Book My Plumber — We'll Call Within 2 Hours",
        "footer_tagline":      "Licensed, reliable plumbing services. Available 24/7 for emergencies.",
        "footer_hours":        "🕐 24/7 Emergency Service",
        "footer_services": [
            "Emergency Repairs", "Blocked Drains", "Hot Water Systems", "Bathroom Renovations"
        ],
    },

    "electrician": {
        "template_file":       "electrician.html",
        "label":               "Electrical Services",
        "schema_type":         "ElectricalContractor",
        "icon":                "⚡",
        "meta_service_line":   "Certified electricians for safety inspections, switchboard upgrades, solar and EV charging",
        "color_primary":       "#D97706",
        "color_dark":          "#B45309",
        "color_light":         "#FFFBEB",
        "hero_gradient_start": "#78350F",
        "hero_gradient_end":   "#92400E",
        "hero_accent_color":   "#FCD34D",
        "trust_bar_color":     "#92400E",
        "trust_bar_1":         "🏅 Master Electricians Australia",
        "hero_badge_urgent":   "⚡ Electrical Safety Experts",
        "trust_signal_2":      "Same-Day Inspections",
        "hero_panel_title":    "Certified Electricians",
        "stat_1_value":        "24/7",
        "stat_1_label":        "Fault Response",
        "stat_4_value":        "100%",
        "stat_4_label":        "Certified",
        "opening_hours":       "Mo-Fr 07:00-18:00",
        "pain_heading":        "Tired of Dodgy Electrical Work?",
        "pain_subtext":        "Electrical problems are serious. You deserve licensed professionals who take safety as seriously as you do.",
        "pain_1_title":        "Booked an electrician who never showed",
        "pain_1_body":         "Three-hour window, no call, no show. Your time is valuable — and that attitude is unacceptable.",
        "pain_2_title":        "Charged extra for every small thing",
        "pain_2_body":         "The quote looked reasonable until the invoice arrived. Every cable, every fitting billed separately. No transparency.",
        "pain_3_title":        "Unlicensed work that failed inspection",
        "pain_3_body":         "Cheap labour costs more in the end when work fails safety inspection and has to be redone from scratch.",
        "differentiator":      "Every job is performed by a licensed electrician, not an apprentice unsupervised. We provide written quotes, turn up on time, and stand behind every installation.",
        "services_subtext":    "From fault-finding to full home rewires — done safely, on time, to Australian standards.",
        "services": [
            ("⚡", "Electrical Fault Finding",   "Diagnose and repair tripping circuits, flickering lights, RCD failures and intermittent faults — fast.",               "fault-finding"),
            ("🔌", "Switchboard Upgrades",       "Upgrade outdated switchboards to modern circuit breakers and safety switches. Essential for insurance compliance.",    "switchboard"),
            ("🏠", "Residential Wiring",         "New builds, additions and full rewires. All work to AS3000 standards with certification.",                             "wiring"),
            ("☀️", "Solar & Battery Systems",    "Grid-tied solar installation and battery storage systems. Clean energy, lower bills.",                                  "solar"),
            ("🚗", "EV Charger Installation",    "Home and commercial EV charging points — all vehicle brands, all charger types.",                                      "ev-charger"),
            ("🔒", "Safety Inspections",         "Pre-purchase electrical inspections, certificate of compliance for rentals and commercial premises.",                  "inspection"),
        ],
        "testimonials": [
            ("M", "#FFFBEB", "#D97706", "Michael B.",
             "Had a switchboard fire risk that two other electricians missed. These guys found it immediately, explained the risk clearly, and fixed it the same day. Professional service throughout."),
            ("R", "#DCFCE7", "#16A34A", "Rebecca H.",
             "Solar and battery installation was seamless. They arrived on time, finished ahead of schedule, explained the system perfectly, and the paperwork was sorted before they left."),
            ("J", "#EFF6FF", "#2563EB", "James O.",
             "EV charger installed in under three hours. The electrician was knowledgeable, tidy, and the price was exactly what was quoted. Would not use anyone else."),
        ],
        "contact_heading":     "Book an Electrician Today",
        "form_cta":            "Book My Electrician — We'll Call Within 2 Hours",
        "footer_tagline":      "Licensed electricians you can trust. Safe work, upfront pricing, on-time every time.",
        "footer_hours":        "🕐 Mon–Fri 7am–6pm · Emergency After-Hours Available",
        "footer_services": [
            "Fault Finding", "Switchboard Upgrades", "Solar & Battery", "EV Chargers"
        ],
    },

    "hvac": {
        "template_file":       "hvac.html",
        "label":               "Air Conditioning Services",
        "schema_type":         "HVACBusiness",
        "icon":                "❄️",
        "meta_service_line":   "Split system install, ducted AC, repairs and servicing for all brands",
        "color_primary":       "#0891B2",
        "color_dark":          "#0E7490",
        "color_light":         "#ECFEFF",
        "hero_gradient_start": "#164E63",
        "hero_gradient_end":   "#075985",
        "hero_accent_color":   "#67E8F9",
        "trust_bar_color":     "#0E7490",
        "trust_bar_1":         "🏅 AIRAH Accredited",
        "hero_badge_urgent":   "❄️ Same-Day Service Available",
        "trust_signal_2":      "All Brands Serviced",
        "hero_panel_title":    "Climate Control Specialists",
        "stat_1_value":        "Same",
        "stat_1_label":        "Day Install",
        "stat_4_value":        "All",
        "stat_4_label":        "Brands",
        "opening_hours":       "Mo-Fr 07:00-18:00",
        "pain_heading":        "Is Your Air Con Letting You Down?",
        "pain_subtext":        "In an Australian summer, air conditioning is not optional. You deserve a system that works when you need it most.",
        "pain_1_title":        "System breaks down in peak summer heat",
        "pain_1_body":         "The mercury hits 38 degrees and your air con gives up. You have been chasing someone to look at it for three days.",
        "pain_2_title":        "Unit was installed but never commissioned properly",
        "pain_2_body":         "Energy bills doubled because the installation was rushed and the system was never optimised for your home's layout.",
        "pain_3_title":        "Expensive repairs that should have been a service",
        "pain_3_body":         "Regular servicing is ignored until a breakdown. Then the repair bill makes a new unit look affordable.",
        "differentiator":      "We install, service and repair every major brand. Our technicians are ARCtick licensed, and every installation is commissioned and tested before we leave.",
        "services_subtext":    "Split systems, ducted air, commercial units — installed and serviced to manufacturer specs.",
        "services": [
            ("❄️", "Split System Install",      "Supply and install wall-mounted split systems for bedrooms, living areas and offices. All leading brands.",              "split-system"),
            ("🌬️", "Ducted Air Conditioning",   "Full ducted system design and installation for whole-home climate control. Quiet, efficient, zoned.",                   "ducted"),
            ("🔧", "Repairs & Fault Finding",   "Fast diagnosis and repair of all AC faults — compressor, refrigerant leaks, electrical, PCB failures.",                 "repair"),
            ("🧽", "Annual Servicing",          "Clean filters, check refrigerant, test performance. Keep your system efficient and your warranty valid.",                "service"),
            ("🏢", "Commercial AC",             "Office and retail air conditioning — supply, install and maintenance contracts for businesses.",                         "commercial"),
            ("🌡️", "Heating Solutions",         "Reverse-cycle systems, panel heaters and gas heating — keep your home warm through winter too.",                         "heating"),
        ],
        "testimonials": [
            ("P", "#ECFEFF", "#0891B2", "Patricia W.",
             "Ducted system installed in one day — spotless work, properly commissioned, and the difference in our electricity bill is already noticeable. Highly professional team."),
            ("C", "#FFFBEB", "#D97706", "Craig N.",
             "Called at 8am on a 40-degree day — they had my split system repaired by midday. The technician explained every step, and the fix has held perfectly since."),
            ("A", "#DCFCE7", "#16A34A", "Amanda S.",
             "Had three units serviced — they arrived on time, cleaned everything thoroughly, topped up the refrigerant, and left each room running better than when they were new."),
        ],
        "contact_heading":     "Book a Service or Install Today",
        "form_cta":            "Book Now — We'll Call Within 2 Hours",
        "footer_tagline":      "ARCtick licensed AC technicians. Installations, repairs and servicing for all brands.",
        "footer_hours":        "🕐 Mon–Fri 7am–6pm · Same-Day Service Available",
        "footer_services": [
            "Split System Install", "Ducted Air Conditioning", "Repairs", "Annual Servicing"
        ],
    },

    "builder": {
        "template_file":       "general_tradie.html",
        "label":               "Building & Renovation",
        "schema_type":         "Contractor",
        "icon":                "🏗️",
        "meta_service_line":   "Licensed builders for renovations, extensions, decks, pergolas and general construction",
        "color_primary":       "#EA580C",
        "color_dark":          "#C2410C",
        "color_light":         "#FFF7ED",
        "hero_gradient_start": "#431407",
        "hero_gradient_end":   "#9A3412",
        "hero_accent_color":   "#FED7AA",
        "trust_bar_color":     "#9A3412",
        "trust_bar_1":         "🏅 Master Builders Association",
        "hero_badge_urgent":   "🏗️ Free Quotes Available",
        "trust_signal_2":      "Fixed-Price Contracts",
        "hero_panel_title":    "Licensed Builders",
        "stat_1_value":        "Fixed",
        "stat_1_label":        "Price Quotes",
        "stat_4_value":        "On-Time",
        "stat_4_label":        "Delivery",
        "opening_hours":       "Mo-Fr 07:00-17:00",
        "pain_heading":        "Tired of Unreliable Builders?",
        "pain_subtext":        "Building projects should not be a source of stress. You deserve a builder who delivers on time and on budget.",
        "pain_1_title":        "Builder disappears mid-project",
        "pain_1_body":         "Deposit paid, materials delivered, work started — then nothing. Calls go unanswered and your project sits half-finished.",
        "pain_2_title":        "Scope creep on every job",
        "pain_2_body":         "What started as a straightforward quote becomes an endless stream of variations and extra charges you never agreed to.",
        "pain_3_title":        "Poor quality that fails the building inspection",
        "pain_3_body":         "Work that looks fine on the surface fails the building inspector because shortcuts were taken on the structural details.",
        "differentiator":      "Every project starts with a fixed-price written contract. We provide regular progress updates, and all work is to Australian Building Code with full certification on completion.",
        "services_subtext":    "From single-room renovations to full extensions — delivered on time, to plan, and to code.",
        "services": [
            ("🏠", "Home Renovations",       "Kitchen and bathroom renovations, open plan transformations and internal reconfigurations.",                                 "renovation"),
            ("🏗️", "Extensions & Additions", "Single and double-storey extensions, garage conversions and granny flat construction.",                                    "extension"),
            ("🪵", "Decks & Pergolas",        "Custom timber and composite decks, pergolas, patios and outdoor entertainment areas.",                                     "deck"),
            ("🧱", "Structural Work",         "Underpinning, retaining walls, load-bearing alterations and structural repairs with engineer sign-off.",                   "structural"),
            ("🚿", "Bathroom Renovations",    "Full wet area renovations — waterproofing, tiling, fixtures and fittings to AS3740 standard.",                            "bathroom"),
            ("🔨", "General Construction",   "Commercial fit-outs, shop fronts, office renovations and strata maintenance work.",                                        "commercial"),
        ],
        "testimonials": [
            ("T", "#FFF7ED", "#EA580C", "Tom A.",
             "Extension completed on time and within budget. The team was professional throughout, kept the site clean, and the finished product was exactly what the plans showed. Excellent workmanship."),
            ("K", "#ECFEFF", "#0891B2", "Karen P.",
             "Kitchen renovation transformed our home. They managed every trade, communicated clearly through every stage, and the result exceeded our expectations. We would not hesitate to use them again."),
            ("G", "#DCFCE7", "#16A34A", "Gary M.",
             "Three quotes, one was half the price — but the detail in these guys' plans gave us confidence. They delivered to the penny, on schedule, and the deck has been the envy of the street."),
        ],
        "contact_heading":     "Get a Free Quote Today",
        "form_cta":            "Request My Free Quote",
        "footer_tagline":      "Licensed builders delivering quality renovations and construction projects on time and on budget.",
        "footer_hours":        "🕐 Mon–Fri 7am–5pm · After-Hours Enquiries Welcome",
        "footer_services": [
            "Home Renovations", "Extensions", "Decks & Pergolas", "Bathrooms"
        ],
    },
}

# ─── Default / fallback values ───────────────────────────────────────────────

DEFAULTS = {
    "TELNYX_AGENT_ID":      "assistant-9c42d3ce-e05a-4e34-8083-c91081917637",
    "GHL_WEBHOOK_URL":      "https://n8n-genesis-u50607.vm.elestio.app/webhook/tradie-website-lead",
    "GOOGLE_REVIEWS_COUNT": "47",
    "JOBS_COMPLETED":       "500+",
    "ADDRESS":              "Serving the local area",
    "EMAIL":                "info@example.com.au",
    "SUBURB_2":             "Nearby Suburb",
    "SUBURB_3":             "Local Area",
    "ABN":                  "XX XXX XXX XXX",
    "BOOKING_URL":          "#contact",
}

# ─── HTML helpers ────────────────────────────────────────────────────────────

def make_service_cards(services: list, trade_color: str, trade_light: str) -> str:
    cards = []
    for icon, title, desc, slug in services:
        cards.append(f"""
      <div class="card fade-in" style="padding:1.75rem;">
        <div style="width:52px; height:52px; background:{trade_light}; border-radius:12px; display:flex; align-items:center; justify-content:center; font-size:1.5rem; margin-bottom:1rem;">{icon}</div>
        <h3 style="font-weight:700; font-size:1.05rem; margin-bottom:0.5rem; color:#111827;">{title}</h3>
        <p style="color:#6B7280; font-size:0.9rem; line-height:1.6;">{desc}</p>
        <a href="#contact" style="display:inline-block; margin-top:0.875rem; color:{trade_color}; font-weight:600; font-size:0.875rem; text-decoration:none;">Book now &#8594;</a>
      </div>""")
    return "\n".join(cards)


def make_service_options(services: list) -> str:
    opts = []
    for _, title, _, slug in services:
        opts.append(f'            <option value="{slug}">{title}</option>')
    return "\n".join(opts)


def make_testimonial_cards(testimonials: list, suburb: str, suburb_2: str, suburb_3: str) -> str:
    suburbs = [suburb, suburb_2, suburb_3]
    cards = []
    for i, (initial, bg, color, name, quote) in enumerate(testimonials):
        area = suburbs[i % len(suburbs)]
        cards.append(f"""
      <div class="card fade-in" style="padding:2rem;">
        <div class="stars" style="margin-bottom:0.875rem; font-size:1.1rem;">⭐⭐⭐⭐⭐</div>
        <p style="color:#374151; font-size:0.95rem; line-height:1.7; margin-bottom:1.25rem; font-style:italic;">"{quote}"</p>
        <div style="display:flex; align-items:center; gap:0.75rem;">
          <div style="width:42px; height:42px; background:{bg}; border-radius:50%; display:flex; align-items:center; justify-content:center; font-weight:700; color:{color}; font-size:1rem;">{initial}</div>
          <div>
            <div style="font-weight:700; font-size:0.9rem; color:#111827;">{name}</div>
            <div style="font-size:0.8rem; color:#6B7280;">{area} &#183; Google Review</div>
          </div>
        </div>
      </div>""")
    return "\n".join(cards)


def make_footer_links(service_names: list) -> str:
    links = []
    for s in service_names:
        links.append(
            f'          <li><a href="#services" style="color:rgba(255,255,255,0.65); text-decoration:none;" '
            f'onmouseover="this.style.color=\'white\'" onmouseout="this.style.color=\'rgba(255,255,255,0.65)\'">{s}</a></li>'
        )
    return "\n".join(links)


# ─── Main generator ──────────────────────────────────────────────────────────

def generate_site(business: dict) -> str:
    """
    Generate a complete single-file HTML website from business data.

    Args:
        business: dict with keys listed in DEFAULTS + required fields

    Required keys:
        business_name, trade_type, suburb, state, phone

    Returns:
        Complete HTML string ready to write to file.
    """
    # Merge defaults
    data = {**DEFAULTS, **business}

    trade = data.get("trade_type", "plumber").lower()
    if trade not in TRADE_CONFIGS:
        raise ValueError(f"Unknown trade_type '{trade}'. Valid: {list(TRADE_CONFIGS.keys())}")

    cfg = TRADE_CONFIGS[trade]

    # Load the specialized template (not the base — the specialized ones are richer)
    tmpl_path = TEMPLATES_DIR / cfg["template_file"]
    if not tmpl_path.exists():
        raise FileNotFoundError(f"Template not found: {tmpl_path}")

    html = tmpl_path.read_text(encoding="utf-8")

    # ── Activate the live Telnyx widget ──────────────────────────────────────
    # The existing templates have a placeholder block — replace it with the real widget
    agent_id = data.get("telnyx_agent_id", data.get("TELNYX_AGENT_ID", DEFAULTS["TELNYX_AGENT_ID"]))

    # Replace placeholder widget block with live Telnyx component
    html = re.sub(
        r'<!-- \+ TELNYX_SCRIPT_PLACEHOLDER \+ -->.*?<!-- \+ END TELNYX_SCRIPT_PLACEHOLDER \+ -->',
        f'<telnyx-ai-agent agent-id="{agent_id}"></telnyx-ai-agent>',
        html,
        flags=re.DOTALL,
    )

    # Ensure Telnyx script is in <head> (some templates use esm, some unpkg — normalise)
    telnyx_script = '<script type="module" src="https://cdn.jsdelivr.net/npm/@telnyx/ai-agent@latest/dist/telnyx-ai-agent/telnyx-ai-agent.esm.js"></script>'
    if "@telnyx/ai-agent" not in html and "telnyx-voice" not in html:
        html = html.replace("</head>", f"  {telnyx_script}\n</head>")

    # ── Slug ─────────────────────────────────────────────────────────────────
    business_name = data["business_name"]
    slug = re.sub(r"[^a-z0-9]+", "", business_name.lower().replace(" ", ""))
    data.setdefault("BUSINESS_NAME_SLUG", slug)

    # ── Placeholder replacements ─────────────────────────────────────────────
    replacements = {
        "{{BUSINESS_NAME}}":        business_name,
        "{{BUSINESS_NAME_SLUG}}":   slug,
        "{{PHONE_NUMBER}}":         data["phone"],
        "{{EMAIL}}":                data.get("email", data["EMAIL"]),
        "{{ADDRESS}}":              data.get("address", data["ADDRESS"]),
        "{{SUBURB}}":               data["suburb"],
        "{{SUBURB_2}}":             data.get("suburb_2", data["SUBURB_2"]),
        "{{SUBURB_3}}":             data.get("suburb_3", data["SUBURB_3"]),
        "{{STATE}}":                data["state"],
        "{{GHL_WEBHOOK_URL}}":      data.get("ghl_webhook_url", data["GHL_WEBHOOK_URL"]),
        "{{TELNYX_AGENT_ID}}":      agent_id,
        "{{GOOGLE_REVIEWS_COUNT}}": str(data.get("google_reviews_count", data["GOOGLE_REVIEWS_COUNT"])),
        "{{JOBS_COMPLETED}}":       str(data.get("jobs_completed", data["JOBS_COMPLETED"])),
        "{{ABN}}":                  data.get("abn", data["ABN"]),
    }
    for key, val in replacements.items():
        html = html.replace(key, val)

    # ── Year in footer ────────────────────────────────────────────────────────
    year = str(datetime.now().year)
    html = re.sub(r"© \d{4}", f"© {year}", html)

    return html


def generate_and_save(business: dict, output_dir: Path = OUTPUT_DIR) -> Path:
    """Generate a site and write it to disk. Returns the output path."""
    html = generate_site(business)
    trade = business.get("trade_type", "plumber").lower()
    slug = re.sub(r"[^a-z0-9]+", "", business["business_name"].lower().replace(" ", ""))
    filename = f"{slug}_{trade}.html"
    out_path = output_dir / filename
    out_path.write_text(html, encoding="utf-8")
    return out_path


# ─── Demo business data ──────────────────────────────────────────────────────

DEMO_BUSINESSES = [
    {
        "business_name":        "Peak Plumbing Brisbane",
        "trade_type":           "plumber",
        "suburb":               "Chermside",
        "suburb_2":             "Aspley",
        "suburb_3":             "Kedron",
        "state":                "QLD",
        "phone":                "07 3123 4567",
        "email":                "info@peakplumbingbrisbane.com.au",
        "address":              "Chermside, Brisbane QLD 4032",
        "google_reviews_count": "83",
        "jobs_completed":       "1,200+",
        "abn":                  "12 345 678 901",
        # demo keeps default Telnyx assistant
    },
    {
        "business_name":        "Bright Spark Electrical",
        "trade_type":           "electrician",
        "suburb":               "Parramatta",
        "suburb_2":             "Blacktown",
        "suburb_3":             "Penrith",
        "state":                "NSW",
        "phone":                "02 8765 4321",
        "email":                "info@brightsparkelectrical.com.au",
        "address":              "Parramatta, Sydney NSW 2150",
        "google_reviews_count": "64",
        "jobs_completed":       "850+",
        "abn":                  "23 456 789 012",
    },
    {
        "business_name":        "CoolBreeze Air",
        "trade_type":           "hvac",
        "suburb":               "Dandenong",
        "suburb_2":             "Frankston",
        "suburb_3":             "Berwick",
        "state":                "VIC",
        "phone":                "03 9876 5432",
        "email":                "info@coolbreezeair.com.au",
        "address":              "Dandenong, Melbourne VIC 3175",
        "google_reviews_count": "51",
        "jobs_completed":       "630+",
        "abn":                  "34 567 890 123",
    },
]


# ─── CLI ─────────────────────────────────────────────────────────────────────

def cli() -> None:
    parser = argparse.ArgumentParser(
        description="TradiesVoice Website Factory — Generate tradie websites",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
Examples:
  # Generate all 3 demo sites
  python3 generate.py --demo

  # Generate from a JSON config file
  python3 generate.py --config my_business.json

  # Generate from CLI flags (quick test)
  python3 generate.py --name "Apex Plumbing" --trade plumber --suburb Brisbane --state QLD --phone "07 3000 0000"

JSON config format:
  {
    "business_name": "Apex Plumbing",
    "trade_type": "plumber",
    "suburb": "Brisbane",
    "suburb_2": "Indooroopilly",
    "suburb_3": "Toowong",
    "state": "QLD",
    "phone": "07 3000 0000",
    "email": "info@apexplumbing.com.au",
    "address": "Brisbane QLD 4000",
    "google_reviews_count": "47",
    "jobs_completed": "500+",
    "telnyx_agent_id": "assistant-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "ghl_webhook_url": "https://hook.gohighlevel.com/webhook/...",
    "abn": "12 345 678 901"
  }
""",
    )
    parser.add_argument("--demo",   action="store_true", help="Generate all 3 demo sites")
    parser.add_argument("--config", type=str,            help="Path to business JSON config file")
    parser.add_argument("--name",   type=str,            help="Business name (CLI mode)")
    parser.add_argument("--trade",  type=str,            choices=list(TRADE_CONFIGS.keys()), help="Trade type")
    parser.add_argument("--suburb", type=str,            help="Primary suburb")
    parser.add_argument("--state",  type=str,            help="State abbreviation (QLD, NSW, VIC, WA, SA, ACT, NT, TAS)")
    parser.add_argument("--phone",  type=str,            help="Phone number")
    parser.add_argument("--output", type=str,            default=str(OUTPUT_DIR), help="Output directory (default: generated_sites/)")
    args = parser.parse_args()

    out_dir = Path(args.output)
    out_dir.mkdir(parents=True, exist_ok=True)

    if args.demo:
        print("\nGenerating 3 TradiesVoice demo sites...\n")
        for biz in DEMO_BUSINESSES:
            out_path = generate_and_save(biz, out_dir)
            size_kb = round(out_path.stat().st_size / 1024, 1)
            print(f"  ✅  {out_path.name}  ({size_kb} KB)")
        print(f"\nAll sites saved to: {out_dir.resolve()}\n")
        return

    if args.config:
        with open(args.config, encoding="utf-8") as f:
            business = json.load(f)
        out_path = generate_and_save(business, out_dir)
        size_kb = round(out_path.stat().st_size / 1024, 1)
        print(f"\n✅  Generated: {out_path.resolve()}  ({size_kb} KB)\n")
        return

    # CLI flags mode
    if not all([args.name, args.trade, args.suburb, args.state, args.phone]):
        parser.print_help()
        print("\nError: --demo, --config, or all of --name --trade --suburb --state --phone are required.\n")
        sys.exit(1)

    business = {
        "business_name": args.name,
        "trade_type":    args.trade,
        "suburb":        args.suburb,
        "state":         args.state,
        "phone":         args.phone,
    }
    out_path = generate_and_save(business, out_dir)
    size_kb = round(out_path.stat().st_size / 1024, 1)
    print(f"\n✅  Generated: {out_path.resolve()}  ({size_kb} KB)\n")


if __name__ == "__main__":
    cli()
