"""
Public domain: landing page, marketing pages, legal pages, feedback, sitemap.
"""
from datetime import datetime
from pathlib import Path

from quart import Blueprint, g, make_response, render_template, request

from ..core import check_rate_limit, config, csrf_protect, execute, fetch_all

# Blueprint with its own template folder
bp = Blueprint(
    "public",
    __name__,
    template_folder=str(Path(__file__).parent / "templates"),
)


@bp.route("/")
async def landing():
    """Landing page."""
    return await render_template("landing.html")


@bp.route("/features")
async def features():
    """Features page."""
    return await render_template("features.html")


@bp.route("/terms")
async def terms():
    """Terms of service."""
    return await render_template("terms.html")


@bp.route("/privacy")
async def privacy():
    """Privacy policy."""
    return await render_template("privacy.html")


@bp.route("/about")
async def about():
    """About page."""
    return await render_template("about.html")


@bp.route("/imprint")
async def imprint():
    """Legal imprint (Impressum) — required by §5 DDG."""
    return await render_template("imprint.html")


@bp.route("/methodology")
async def methodology():
    """Data methodology page — explains all data sources."""
    return await render_template("methodology.html")


@bp.route("/feedback", methods=["POST"])
@csrf_protect
async def feedback():
    """Submit feedback. Rate-limited to 5/hour per IP. Returns HTMX snippet."""
    ip = request.remote_addr or "unknown"
    allowed, _ = await check_rate_limit(f"feedback:{ip}", limit=5, window=3600)
    if not allowed:
        return '<p style="color:#EF4444;font-size:13px;">Too many submissions. Try again later.</p>', 429

    form = await request.form
    message = (form.get("message") or "").strip()
    page_url = (form.get("page_url") or "").strip()[:500]

    if not message:
        return '<p style="color:#EF4444;font-size:13px;">Message cannot be empty.</p>', 400
    if len(message) > 2000:
        return '<p style="color:#EF4444;font-size:13px;">Message too long (max 2000 characters).</p>', 400

    user_id = g.user["id"] if g.get("user") else None

    await execute(
        """
        INSERT INTO feedback (user_id, page_url, message, created_at)
        VALUES (?, ?, ?, ?)
        """,
        (user_id, page_url, message, datetime.utcnow().isoformat()),
    )

    return '<p style="color:#15803D;font-size:13px;font-weight:500;">Thanks for your feedback!</p>'


@bp.route("/robots.txt")
async def robots_txt():
    """robots.txt for search engines."""
    body = "User-agent: *\n"
    body += "Disallow: /admin/\n"
    body += "Disallow: /auth/\n"
    body += "Disallow: /dashboard/\n"
    body += "Disallow: /billing/\n"
    body += f"Sitemap: {config.BASE_URL.rstrip('/')}/sitemap.xml\n"
    response = await make_response(body)
    response.headers["Content-Type"] = "text/plain"
    return response


@bp.route("/sitemap.xml")
async def sitemap_xml():
    """XML sitemap for search engines."""
    base = config.BASE_URL.rstrip("/")

    def url_entry(loc: str, priority: str = "0.5", changefreq: str = "weekly") -> str:
        return (
            f"  <url>\n"
            f"    <loc>{loc}</loc>\n"
            f"    <changefreq>{changefreq}</changefreq>\n"
            f"    <priority>{priority}</priority>\n"
            f"  </url>\n"
        )

    today = datetime.utcnow().date().isoformat()
    xml = '<?xml version="1.0" encoding="UTF-8"?>\n'
    xml += '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n'
    xml += url_entry(f"{base}/", priority="1.0", changefreq="daily")
    xml += url_entry(f"{base}/features", priority="0.8")
    xml += url_entry(f"{base}/about", priority="0.6")
    xml += url_entry(f"{base}/pricing", priority="0.8")
    xml += url_entry(f"{base}/terms", priority="0.3", changefreq="yearly")
    xml += url_entry(f"{base}/privacy", priority="0.3", changefreq="yearly")
    xml += url_entry(f"{base}/imprint", priority="0.2", changefreq="yearly")

    # CMS articles
    try:
        articles = await fetch_all(
            "SELECT url_path, updated_at, published_at FROM articles WHERE status = 'published' ORDER BY published_at DESC LIMIT 500"
        )
    except Exception:
        articles = []

    for article in articles:
        lastmod = (article.get("updated_at") or article.get("published_at") or today)[:10]
        loc = f"{base}{article['url_path']}"
        xml += (
            f"  <url>\n"
            f"    <loc>{loc}</loc>\n"
            f"    <lastmod>{lastmod}</lastmod>\n"
            f"    <changefreq>monthly</changefreq>\n"
            f"    <priority>0.6</priority>\n"
            f"  </url>\n"
        )

    xml += "</urlset>"

    response = await make_response(xml)
    response.headers["Content-Type"] = "application/xml"
    return response
