import os
import base64
from jinja2 import Environment, FileSystemLoader
from app.services.theme import derive_color_harmonics

_TEMPLATE_DIR = os.path.join(os.path.dirname(os.path.dirname(__file__)), "templates")
_standalone_env = Environment(loader=FileSystemLoader(_TEMPLATE_DIR), autoescape=False)

VALID_TIERS = ("nano", "banana", "premium")
DEFAULT_TIER = "premium"

PREMIUM_TEMPLATE_VARIANTS = {
    "hero": "site_premium.html",
    "sidebar": "site_sidebar.html",
    "magazine": "site_magazine.html",
    "cinematic": "site_cinematic.html",
    "command": "site_command.html",
    "split": "site_split.html",
    "data-dense": "site_premium.html",
    "comparison": "site_premium.html",
    "gallery": "site_premium.html",
}

ICON_SVG_MAP = {
    "shield":       '<svg width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>',
    "chart":        '<svg width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"><polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/></svg>',
    "globe":        '<svg width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>',
    "zap":          '<svg width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/></svg>',
    "users":        '<svg width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>',
    "star":         '<svg width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>',
    "target":       '<svg width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><circle cx="12" cy="12" r="6"/><circle cx="12" cy="12" r="2"/></svg>',
    "clock":        '<svg width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>',
    "heart":        '<svg width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/></svg>',
    "check":        '<svg width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"><polyline points="20 6 9 17 4 12"/></svg>',
    "book":         '<svg width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg>',
    "rocket":       '<svg width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"><path d="M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09z"/><path d="M12 15l-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 0 1-4 2z"/><path d="M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0"/><path d="M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5"/></svg>',
    "lock":         '<svg width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>',
    "gear":         '<svg width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg>',
    "lightning":    '<svg width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/></svg>',
    "shield-check": '<svg width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/><polyline points="9 12 11 14 15 10"/></svg>',
    "cpu":          '<svg width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"><rect x="4" y="4" width="16" height="16" rx="2"/><rect x="9" y="9" width="6" height="6"/><line x1="9" y1="1" x2="9" y2="4"/><line x1="15" y1="1" x2="15" y2="4"/><line x1="9" y1="20" x2="9" y2="23"/><line x1="15" y1="20" x2="15" y2="23"/><line x1="20" y1="9" x2="23" y2="9"/><line x1="20" y1="14" x2="23" y2="14"/><line x1="1" y1="9" x2="4" y2="9"/><line x1="1" y1="14" x2="4" y2="14"/></svg>',
    "database":     '<svg width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"><ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M21 12c0 1.66-4 3-9 3s-9-1.34-9-3"/><path d="M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5"/></svg>',
}
ICON_MAP = {k: v for k, v in ICON_SVG_MAP.items()}


def _hex_to_rgb(hex_color):
    hex_color = hex_color.lstrip("#")
    if len(hex_color) == 3:
        hex_color = "".join(c * 2 for c in hex_color)
    try:
        return ",".join(str(int(hex_color[i:i+2], 16)) for i in (0, 2, 4))
    except (ValueError, IndexError):
        return "79,70,229"


def _resolve_tier(tier):
    if tier and tier.lower() in VALID_TIERS:
        return tier.lower()
    return DEFAULT_TIER


def _base_context(domain, brand, brand_data, tier="premium"):
    tier = _resolve_tier(tier)
    primary = brand_data.get("color_primary", "#4F46E5")
    secondary = brand_data.get("color_secondary", "#7C3AED")
    accent = brand_data.get("color_accent", "#06B6D4")
    brand_name = brand.get("name", domain)
    tagline = brand.get("tagline", "")

    harmonics = derive_color_harmonics(primary, secondary, accent)

    return {
        "tier": tier,
        "domain": domain,
        "brand_name": brand_name,
        "tagline": tagline,
        "primary": primary,
        "secondary": secondary,
        "accent": accent,
        "primary_rgb": _hex_to_rgb(primary),
        "secondary_rgb": _hex_to_rgb(secondary),
        "accent_rgb": _hex_to_rgb(accent),
        **harmonics,
    }


def _resolve_image_to_b64(image_url):
    if not image_url:
        return None
    try:
        img_disk_path = image_url.lstrip("/")
        if os.path.exists(img_disk_path):
            with open(img_disk_path, "rb") as img_f:
                b64 = base64.b64encode(img_f.read()).decode("utf-8")
            ext = img_disk_path.rsplit(".", 1)[-1].lower() if "." in img_disk_path else "png"
            mime = {"jpg": "jpeg", "jpeg": "jpeg", "svg": "svg+xml", "webp": "webp"}.get(ext, "png")
            return f"data:image/{mime};base64,{b64}"
        return image_url
    except Exception:
        return None


def render_standalone_site(domain, brand, brand_data, site_copy, hero_image_url=None, augments=None, tier="premium", designations=None, template_type=None):
    tier = _resolve_tier(tier)
    designations = designations or {}

    if tier == "nano":
        from app.main import generate_standalone_site_html as _nano_gen
        return _nano_gen(domain, brand, brand_data, site_copy, hero_image_url, augments)

    ctx = _base_context(domain, brand, brand_data, tier)

    features_raw = site_copy.get("features", [])
    if isinstance(features_raw, dict) and "features" in features_raw:
        features_raw = features_raw["features"]
    features = []
    for f in (features_raw if isinstance(features_raw, list) else []):
        icon_key = f.get("icon", "star")
        features.append({
            "title": f.get("title", ""),
            "description": f.get("description", ""),
            "icon_svg": ICON_SVG_MAP.get(icon_key, ICON_SVG_MAP["star"]),
        })

    faq_raw = site_copy.get("faq_items", site_copy.get("faq", []))
    if isinstance(faq_raw, dict):
        faq_raw = faq_raw.get("faq_items", faq_raw.get("faq", []))
    faq = faq_raw if isinstance(faq_raw, list) else []

    testimonials_raw = site_copy.get("testimonials", [])
    if isinstance(testimonials_raw, dict):
        testimonials_raw = testimonials_raw.get("testimonials", [])
    testimonials = testimonials_raw if isinstance(testimonials_raw, list) else []

    effective_hero = designations.get("hero") or hero_image_url
    hero_bg_image = _resolve_image_to_b64(effective_hero)

    logo_image = _resolve_image_to_b64(designations.get("logo"))
    favicon_image = _resolve_image_to_b64(designations.get("favicon"))
    og_image = _resolve_image_to_b64(designations.get("og_image"))
    about_image = _resolve_image_to_b64(designations.get("about_image"))

    aug_data = []
    if augments:
        from app.main import _augment_slug
        for aug in augments:
            aug_data.append({
                "title": aug.title,
                "description": aug.description or "",
                "slug": _augment_slug(aug.id, aug.title),
            })

    about = site_copy.get("about", "")
    if isinstance(about, dict):
        about = about.get("about_body", about.get("body", ""))

    pricing_raw = site_copy.get("pricing_tiers", site_copy.get("pricing_plans", []))
    if isinstance(pricing_raw, dict):
        pricing_raw = pricing_raw.get("tiers", pricing_raw.get("plans", []))
    pricing_tiers = pricing_raw if isinstance(pricing_raw, list) else []
    for pt in pricing_tiers:
        if isinstance(pt.get("features"), str):
            pt["features"] = [f.strip() for f in pt["features"].split(",") if f.strip()]
        if "featured" not in pt:
            pt["featured"] = False

    hiw_raw = site_copy.get("how_it_works_steps", site_copy.get("how_steps", []))
    if isinstance(hiw_raw, dict):
        hiw_raw = hiw_raw.get("steps", hiw_raw.get("how_it_works_steps", []))
    how_it_works_steps = hiw_raw if isinstance(hiw_raw, list) else []

    comparison_raw = site_copy.get("comparison_table", {})
    if isinstance(comparison_raw, dict):
        comparison_table = comparison_raw
    else:
        comparison_table = {}

    ctx.update({
        "headline": site_copy.get("headline", brand.get("name", "")),
        "subheadline": site_copy.get("subheadline", brand.get("tagline", "")),
        "hero_body": site_copy.get("hero_body", ""),
        "cta_text": site_copy.get("cta_text", "Get Started"),
        "about_title": site_copy.get("about_title", "About Us"),
        "about": about,
        "offer": site_copy.get("offer", ""),
        "niche": site_copy.get("niche", ""),
        "features": features,
        "faq": faq,
        "testimonials": testimonials,
        "augments": aug_data,
        "hero_bg_image": hero_bg_image,
        "logo_image": logo_image,
        "favicon_image": favicon_image,
        "og_image": og_image,
        "about_image": about_image,
        "pricing_tiers": pricing_tiers,
        "pricing_title": site_copy.get("pricing_title", ""),
        "pricing_subtitle": site_copy.get("pricing_subtitle", ""),
        "how_it_works_steps": how_it_works_steps,
        "how_it_works_title": site_copy.get("how_it_works_title", ""),
        "how_it_works_subtitle": site_copy.get("how_it_works_subtitle", ""),
        "comparison_table": comparison_table,
        "comparison_title": site_copy.get("comparison_title", ""),
    })

    if tier == "premium" and template_type and template_type in PREMIUM_TEMPLATE_VARIANTS:
        variant_file = PREMIUM_TEMPLATE_VARIANTS[template_type]
        template_name = f"standalone/{variant_file}"
    else:
        template_name = f"standalone/site_{tier}.html"
    try:
        tmpl = _standalone_env.get_template(template_name)
    except Exception:
        tmpl = _standalone_env.get_template("standalone/site_premium.html")
    return tmpl.render(**ctx)


def render_standalone_admin(domain, brand, brand_data, site_copy, pkg, augments, brand_kit_assets, business_docs, graphics_assets, deployed_files_manifest, tier="premium"):
    tier = _resolve_tier(tier)

    if tier == "nano":
        from app.main import generate_standalone_admin_html as _nano_gen
        return _nano_gen(domain, brand, brand_data, site_copy, pkg, augments, brand_kit_assets, business_docs, graphics_assets, deployed_files_manifest)

    from app.main import _augment_slug
    ctx = _base_context(domain, brand, brand_data, tier)

    niche = pkg.chosen_niche if pkg else ""
    gen_date = pkg.created_at.strftime("%B %d, %Y") if pkg and pkg.created_at else "N/A"

    total_pages = sum(1 for k in deployed_files_manifest if k.endswith(".html"))
    total_images = sum(1 for k in deployed_files_manifest if any(k.endswith(ext) for ext in (".png", ".jpg", ".jpeg", ".gif", ".svg", ".webp")))
    total_docs = len(business_docs) if business_docs else 0
    total_files = len(deployed_files_manifest)

    page_list = []
    page_list.append(("index.html", "Main Site", "&#127968;"))
    if any(k == "sales.html" for k in deployed_files_manifest):
        page_list.append(("sales.html", "Sales Letter", "&#128176;"))
    page_list.append(("admin.html", "Site Admin (This Page)", "&#9881;"))
    for aug in (augments or []):
        slug = _augment_slug(aug.id, aug.title)
        page_list.append((f"tools/{slug}.html", f"Tool: {aug.title}", "&#9889;"))
    if business_docs:
        for dk, dv in business_docs.items():
            tier_name = dv.get("tier", "general")
            tier_slug = tier_name.lower().replace(" ", "-")
            page_list.append((f"docs/{tier_slug}/{dk}.html", f"Doc: {dv.get('title', dk)}", "&#128196;"))

    img_items = []
    hero_url = pkg.hero_image_url if pkg else None
    if hero_url:
        img_items.append(("Hero Image", os.path.basename(hero_url), f"images/{os.path.basename(hero_url)}"))
    for fi_url in (pkg.feature_images or []) if pkg else []:
        if fi_url:
            img_items.append(("Feature Image", os.path.basename(fi_url), f"images/{os.path.basename(fi_url)}"))
    for ga in (graphics_assets or []):
        fn = ga.get("filename", os.path.basename(ga.get("url", "")))
        img_items.append(("Graphics Pack", fn, f"images/graphics/{fn}"))
    for bka in (brand_kit_assets or []):
        cls = bka.classification or "uncategorized"
        img_items.append((f"Brand Kit: {cls}", bka.filename, f"assets/brand-kit/{cls}/{bka.filename}"))

    docs_by_tier = {}
    if business_docs:
        for dk, dv in business_docs.items():
            tier_name = dv.get("tier", "general")
            tier_slug = tier_name.lower().replace(" ", "-")
            docs_by_tier.setdefault(tier_name, []).append((dk, dv, tier_slug))

    aug_data = []
    if augments:
        for aug in augments:
            aug_data.append({
                "title": aug.title,
                "description": aug.description or "",
                "slug": _augment_slug(aug.id, aug.title),
            })

    manifest_rows = []
    for fpath in sorted(deployed_files_manifest.keys()):
        val = deployed_files_manifest[fpath]
        if fpath.endswith(".html"):
            ftype = "HTML"
        elif any(fpath.endswith(ext) for ext in (".png", ".jpg", ".jpeg", ".gif", ".svg", ".webp")):
            ftype = "Image"
        elif fpath.startswith("docs/"):
            ftype = "Document"
        elif fpath.startswith("assets/"):
            ftype = "Asset"
        else:
            ftype = "Other"
        size_str = f"{val:,} bytes" if isinstance(val, int) else str(val)
        manifest_rows.append((fpath, ftype, size_str))

    ctx.update({
        "niche": niche,
        "gen_date": gen_date,
        "total_pages": total_pages,
        "total_images": total_images,
        "total_docs": total_docs,
        "total_files": total_files,
        "page_list": page_list,
        "img_items": img_items,
        "docs_by_tier": docs_by_tier,
        "augments": aug_data,
        "manifest_rows": manifest_rows,
    })

    template_name = f"standalone/admin_{tier}.html"
    try:
        tmpl = _standalone_env.get_template(template_name)
    except Exception:
        tmpl = _standalone_env.get_template("standalone/admin_premium.html")
    return tmpl.render(**ctx)


def render_standalone_doc(domain, brand_name, primary, secondary, accent, doc_title, doc_tier, rendered_content, tier_nav_links, tier="premium"):
    tier = _resolve_tier(tier)

    if tier == "nano":
        return None

    accent = accent or "#06B6D4"
    harmonics = derive_color_harmonics(primary, secondary, accent)

    ctx = {
        "tier": tier,
        "domain": domain,
        "brand_name": brand_name,
        "primary": primary,
        "secondary": secondary,
        "accent": accent,
        "primary_rgb": _hex_to_rgb(primary),
        "secondary_rgb": _hex_to_rgb(secondary),
        "accent_rgb": _hex_to_rgb(accent),
        "tagline": "",
        "doc_title": doc_title,
        "doc_tier": doc_tier,
        "rendered_content": rendered_content,
        "tier_nav_links": tier_nav_links,
        **harmonics,
    }

    template_name = f"standalone/doc_{tier}.html"
    try:
        tmpl = _standalone_env.get_template(template_name)
    except Exception:
        tmpl = _standalone_env.get_template("standalone/doc_premium.html")
    return tmpl.render(**ctx)


def render_standalone_augment(domain, brand, brand_data, augment, all_augments=None, tier="premium"):
    import html as html_mod
    tier = _resolve_tier(tier)

    if tier == "nano":
        from app.main import generate_standalone_augment_html as _nano_gen
        return _nano_gen(domain, brand, brand_data, augment, all_augments)

    from app.main import _augment_slug
    ctx = _base_context(domain, brand, brand_data, tier)

    aug_title = html_mod.escape(augment.title or f"Tool {augment.id}")
    aug_desc = html_mod.escape(augment.description or "")

    other_augments = []
    for aug in (all_augments or []):
        if aug.id != augment.id:
            other_augments.append({
                "title": html_mod.escape(aug.title or f"Tool {aug.id}"),
                "slug": _augment_slug(aug.id, aug.title or f"tool-{aug.id}"),
            })

    content = augment.html_content or ""
    if not content:
        content = f'''<div style="padding:48px;text-align:center;color:#6b7280">
<p style="font-size:3rem;margin-bottom:16px">&#128338;</p>
<h3 style="font-weight:700;color:#374151;margin-bottom:8px">Content Being Generated</h3>
<p>This tool is still being prepared. Check back shortly.</p>
<a href="../index.html" style="display:inline-block;margin-top:24px;background:{ctx["primary"]};color:#fff;padding:10px 24px;border-radius:8px;font-weight:600;text-decoration:none">Back to Site</a>
</div>'''

    ctx.update({
        "aug_title": aug_title,
        "aug_desc": aug_desc,
        "content": content,
        "other_augments": other_augments,
    })

    template_name = f"standalone/augment_{tier}.html"
    try:
        tmpl = _standalone_env.get_template(template_name)
    except Exception:
        tmpl = _standalone_env.get_template("standalone/augment_premium.html")
    return tmpl.render(**ctx)
