"""
Supplier directory: public, searchable listing of padel court suppliers.
"""

from pathlib import Path

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

from ..core import count_where, csrf_protect, execute, fetch_all, fetch_one, utcnow_iso
from ..i18n import COUNTRY_LABELS, get_translations

bp = Blueprint(
    "directory",
    __name__,
    url_prefix="/directory",
    template_folder=str(Path(__file__).parent / "templates"),
)


CATEGORY_LABELS = {
    "manufacturer": "Manufacturer",
    "turnkey": "Turnkey Provider",
    "consultant": "Consultant",
    "hall_builder": "Hall Builder",
    "turf": "Turf / Surfaces",
    "lighting": "Lighting",
    "software": "Software",
    "industry_body": "Industry Body",
    "franchise": "Franchise / Operator",
}

REGION_LABELS = {
    "Europe": "Europe",
    "North America": "North America",
    "Latin America": "Latin America",
    "Middle East": "Middle East",
    "Asia Pacific": "Asia Pacific",
    "Africa": "Africa",
}


def get_directory_labels(lang: str) -> tuple[dict, dict, dict]:
    """Return (category_labels, country_labels, region_labels) translated for lang."""
    t = get_translations(lang)
    cat = {k: t.get(f"dir_cat_{k}", v) for k, v in CATEGORY_LABELS.items()}
    country = {k: t.get(f"dir_country_{k}", v) for k, v in COUNTRY_LABELS.items()}
    region = {k: t.get(f"dir_region_{k.lower().replace(' ', '_')}", k) for k in REGION_LABELS}
    return cat, country, region


async def _build_directory_query(q, country, category, region, page, per_page=24):
    """Shared query builder for directory index and HTMX results."""
    lang = g.get("lang", "en")
    cat_labels, country_labels, region_labels = get_directory_labels(lang)

    now = utcnow_iso()

    params: list = []
    wheres: list[str] = []

    if q:
        terms = [t for t in q.split() if t]
        if terms:
            fts_q = " ".join(t + "*" for t in terms)
            wheres.append("s.id IN (SELECT rowid FROM suppliers_fts WHERE suppliers_fts MATCH ?)")
            params.append(fts_q)

    if country:
        wheres.append("s.country_code = ?")
        params.append(country)

    if category:
        wheres.append("s.category = ?")
        params.append(category)

    if region:
        wheres.append("s.region = ?")
        params.append(region)

    where = " AND ".join(wheres) if wheres else "1=1"

    total = await count_where(f"suppliers s WHERE {where}", tuple(params))

    offset = (page - 1) * per_page
    # Tier-based ordering: sticky first, then pro > growth > free, then name
    order_params = params + [now, country or "", per_page, offset]
    suppliers = await fetch_all(
        f"""SELECT * FROM suppliers s WHERE {where}
        ORDER BY
          CASE WHEN s.sticky_until > ? AND (s.sticky_country IS NULL OR s.sticky_country = '' OR s.sticky_country = ?) THEN 0 ELSE 1 END,
          CASE s.tier WHEN 'pro' THEN 0 WHEN 'growth' THEN 1 WHEN 'basic' THEN 2 ELSE 3 END,
          s.name
        LIMIT ? OFFSET ?""",
        tuple(order_params),
    )

    total_pages = max(1, (total + per_page - 1) // per_page)

    # Fetch card_color boosts for displayed suppliers
    card_colors = {}
    if suppliers:
        supplier_ids = [s["id"] for s in suppliers]
        placeholders = ",".join("?" * len(supplier_ids))
        color_rows = await fetch_all(
            f"""SELECT supplier_id, metadata FROM supplier_boosts
                WHERE supplier_id IN ({placeholders})
                AND boost_type = 'card_color' AND status = 'active'""",
            tuple(supplier_ids),
        )
        import json

        for row in color_rows:
            meta = {}
            if row["metadata"]:
                try:
                    meta = json.loads(row["metadata"])
                except (json.JSONDecodeError, TypeError):
                    pass
            if meta.get("color"):
                card_colors[row["supplier_id"]] = meta["color"]

    return {
        "suppliers": suppliers,
        "q": q,
        "country": country,
        "category": category,
        "region": region,
        "page": page,
        "total_pages": total_pages,
        "total": total,
        "now": now,
        "country_labels": country_labels,
        "category_labels": cat_labels,
        "region_labels": region_labels,
        "card_colors": card_colors,
    }


@bp.route("/")
async def index():
    q = request.args.get("q", "").strip()
    country = request.args.get("country", "")
    category = request.args.get("category", "")
    region = request.args.get("region", "")
    page = max(1, int(request.args.get("page", "1") or "1"))

    ctx = await _build_directory_query(q, country, category, region, page)

    country_counts = await fetch_all(
        "SELECT country_code, COUNT(*) as cnt FROM suppliers"
        " GROUP BY country_code ORDER BY cnt DESC"
    )

    category_counts = await fetch_all(
        "SELECT category, COUNT(*) as cnt FROM suppliers GROUP BY category ORDER BY cnt DESC"
    )

    total_suppliers = await count_where("suppliers")
    total_countries = await count_where("(SELECT DISTINCT country_code FROM suppliers)")

    return await render_template(
        "directory.html",
        **ctx,
        country_counts=country_counts,
        category_counts=category_counts,
        total_suppliers=total_suppliers,
        total_countries=total_countries,
    )


@bp.route("/<slug>")
async def supplier_detail(slug: str):
    """Public supplier profile page."""
    supplier = await fetch_one("SELECT * FROM suppliers WHERE slug = ?", (slug,))
    if not supplier:
        from quart import abort

        abort(404)

    # Get active boosts
    boosts = await fetch_all(
        "SELECT boost_type FROM supplier_boosts WHERE supplier_id = ? AND status = 'active'",
        (supplier["id"],),
    )
    active_boosts = [b["boost_type"] for b in boosts]

    # Parse services_offered into list
    raw_services = (supplier.get("services_offered") or "").strip()
    services_list = (
        [s.strip() for s in raw_services.split(",") if s.strip()] if raw_services else []
    )

    # Build social links dict
    social_links = {
        "linkedin": supplier.get("linkedin_url") or "",
        "instagram": supplier.get("instagram_url") or "",
        "youtube": supplier.get("youtube_url") or "",
    }

    # Enquiry count (Basic+)
    enquiry_count = 0
    if supplier.get("tier") in ("basic", "growth", "pro"):
        enquiry_count = await count_where(
            "supplier_enquiries WHERE supplier_id = ?", (supplier["id"],)
        )

    lang = g.get("lang", "en")
    cat_labels, country_labels, region_labels = get_directory_labels(lang)

    return await render_template(
        "supplier_detail.html",
        supplier=supplier,
        active_boosts=active_boosts,
        country_labels=country_labels,
        category_labels=cat_labels,
        region_labels=region_labels,
        services_list=services_list,
        social_links=social_links,
        enquiry_count=enquiry_count,
    )


@bp.route("/<slug>/enquiry", methods=["POST"])
@csrf_protect
async def supplier_enquiry(slug: str):
    """Handle enquiry form submission for Basic+ supplier listings."""
    supplier = await fetch_one(
        "SELECT * FROM suppliers WHERE slug = ? AND tier IN ('basic', 'growth', 'pro')",
        (slug,),
    )
    if not supplier:
        from quart import abort

        abort(404)

    form = await request.form
    contact_name = (form.get("contact_name", "") or "").strip()
    contact_email = (form.get("contact_email", "") or "").strip().lower()
    message = (form.get("message", "") or "").strip()

    errors = []
    if not contact_name:
        errors.append("Name is required.")
    if not contact_email or "@" not in contact_email:
        errors.append("Valid email is required.")
    if not message:
        errors.append("Message is required.")

    if errors:
        return await render_template(
            "partials/enquiry_result.html",
            success=False,
            errors=errors,
        )

    # Rate-limit: max 5 enquiries per email per 24 h
    row = await fetch_one(
        """SELECT COUNT(*) as cnt FROM supplier_enquiries
           WHERE contact_email = ? AND created_at >= datetime('now', '-1 day')""",
        (contact_email,),
    )
    if row and row["cnt"] >= 5:
        return await render_template(
            "partials/enquiry_result.html",
            success=False,
            errors=["Too many enquiries from this address. Please wait 24 hours."],
        )

    await execute(
        """INSERT INTO supplier_enquiries (supplier_id, contact_name, contact_email, message)
           VALUES (?, ?, ?, ?)""",
        (supplier["id"], contact_name, contact_email, message),
    )

    # Enqueue email to supplier
    if supplier.get("contact_email"):
        from ..worker import enqueue

        await enqueue(
            "send_supplier_enquiry_email",
            {
                "supplier_id": supplier["id"],
                "supplier_name": supplier["name"],
                "supplier_email": supplier["contact_email"],
                "contact_name": contact_name,
                "contact_email": contact_email,
                "message": message,
                "lang": g.get("lang", "en"),
            },
        )

    return await render_template(
        "partials/enquiry_result.html",
        success=True,
        supplier=supplier,
    )


@bp.route("/<slug>/website")
async def supplier_website(slug: str):
    """Redirect to supplier website — tracked as Umami event."""
    supplier = await fetch_one("SELECT website FROM suppliers WHERE slug = ?", (slug,))
    if not supplier or not supplier["website"]:
        from quart import abort

        abort(404)
    url = supplier["website"]
    if not url.startswith("http"):
        url = "https://" + url
    return redirect(url)


@bp.route("/<slug>/quote")
async def supplier_quote(slug: str):
    """Redirect to quote request form — tracked as Umami event."""
    return redirect(url_for("leads.quote_request", supplier=slug))


@bp.route("/results")
async def results():
    """HTMX endpoint — returns only the results partial."""
    q = request.args.get("q", "").strip()
    country = request.args.get("country", "")
    category = request.args.get("category", "")
    region = request.args.get("region", "")
    page = max(1, int(request.args.get("page", "1") or "1"))

    ctx = await _build_directory_query(q, country, category, region, page)
    resp = await make_response(await render_template("partials/results.html", **ctx))
    resp.headers["X-Robots-Tag"] = "noindex"
    return resp
