#!/usr/bin/env python3
"""
WSGI adapter for shared hosting (e.g. InMotion/cPanel "Setup Python App").

In cPanel: create a Python app (application root = this folder), set
"Application startup file" to wsgi.py. Apache/Passenger then serves the API
at your domain. Static UI files (static/) are served by the web server — point
your DocumentRoot or a symlink at static/ for the dashboard, or serve the API
under /api and keep index.html reachable.

For a VPS (recommended, simpler): just run `python server.py` behind nginx.
"""
import json
import re
from urllib.parse import parse_qs

import server as srv


def _resp(start_response, code, body, ctype="application/json", extra=None):
    if isinstance(body, (dict, list)):
        body = json.dumps(body).encode()
    elif isinstance(body, str):
        body = body.encode()
    headers = [("Content-Type", ctype), ("Access-Control-Allow-Origin", "*"),
               ("Content-Length", str(len(body)))]
    if extra:
        headers += extra
    start_response(f"{code} OK" if code == 200 else f"{code} ERR", headers)
    return [body]


def application(environ, start_response):
    path = environ.get("PATH_INFO", "/")
    qs = parse_qs(environ.get("QUERY_STRING", ""))
    method = environ.get("REQUEST_METHOD", "GET")

    if method == "OPTIONS":
        return _resp(start_response, 204, b"", extra=[
            ("Access-Control-Allow-Methods", "GET, POST, OPTIONS"),
            ("Access-Control-Allow-Headers", "Content-Type")])

    if method == "POST" and path == "/api/ingest":
        length = int(environ.get("CONTENT_LENGTH") or 0)
        payload = json.loads(environ["wsgi.input"].read(length) or b"{}")
        obj, code = srv.handle_ingest(payload)
        return _resp(start_response, code, obj)

    if method == "POST" and path == "/api/reports/save":
        length = int(environ.get("CONTENT_LENGTH") or 0)
        payload = json.loads(environ["wsgi.input"].read(length) or b"{}")
        obj, code = srv.save_report(payload)
        return _resp(start_response, code, obj)

    if path == "/api/health":
        return _resp(start_response, 200, {"status": "ok", "mode": "live",
                                           "source": "LiveScraperSource (eBay sold pages)",
                                           "items_cached": len(srv.SRC.items())})
    if path == "/api/categories":
        return _resp(start_response, 200, {"tree": srv.category_tree_with_counts(), "window_days": srv.WINDOW_DAYS})
    if path == "/api/sold":
        live = srv.maybe_refresh_live(qs)
        f = srv.parse_filters(qs)
        rows = srv.filter_items(f)
        page, per = f["page"], f["per_page"]
        q_raw = (qs.get("q", [""])[0] or "").strip()
        cached = srv.read_cache(q_raw, f["category_id"])
        return _resp(start_response, 200, {"total": len(rows), "page": page, "per_page": per,
                                           "items": rows[(page - 1) * per: page * per],
                                           "ebay_total": cached.get("total_results") if cached else None,
                                           "live": live})
    if path == "/api/analytics":
        srv.maybe_refresh_live(qs)
        return _resp(start_response, 200, srv.analytics(srv.filter_items(srv.parse_filters(qs))))
    if path == "/api/export.csv":
        srv.maybe_refresh_live(qs)
        import csv, io
        rows = srv.filter_items(srv.parse_filters(qs))
        buf = io.StringIO()
        w = csv.writer(buf)
        w.writerow(["id", "sold_date", "title", "mpn", "brand", "category", "price_usd",
                    "condition", "seller", "url"])
        for r in rows:
            w.writerow([r["id"], r["sold_date"], r["title"], r["mpn"], r["brand"],
                        r["category"], r["price"], r["condition"], r["seller"], r.get("url", "")])
        return _resp(start_response, 200, buf.getvalue(), "text/csv",
                     [("Content-Disposition", 'attachment; filename="sold_items.csv"')])
    if path == "/api/reports":
        return _resp(start_response, 200, {"reports": srv.list_reports()})
    m = re.fullmatch(r"/api/reports/([\w-]+)", path)
    if m:
        rep = srv.get_report(m.group(1))
        return _resp(start_response, 200 if rep else 404, rep or {"error": "not found"})
    return _resp(start_response, 404, {"error": "not found"})
