"""جسر WSGI — بيشغّل نفس DashboardHandler بتاع app.py تحت Passenger/cPanel
بدون ما نغيّر منطق التطبيق.
"""

import base64
import io
import os
import sys
from types import SimpleNamespace
from urllib.parse import quote

BASE_DIR = os.path.dirname(os.path.abspath(__file__))
if BASE_DIR not in sys.path:
    sys.path.insert(0, BASE_DIR)

import app as dashboard  # noqa: E402

WEB_DIR = os.path.join(BASE_DIR, "web")


def _raw_request(environ):
    method = environ.get("REQUEST_METHOD", "GET").upper()
    path = environ.get("PATH_INFO", "/") or "/"
    query = environ.get("QUERY_STRING", "")
    if query:
        path = f"{path}?{query}"
    path = quote(path, safe="/?=&%:@!$'()*+,;~-._[]")

    lines = [f"{method} {path} HTTP/1.1"]
    host = environ.get("HTTP_HOST") or "localhost"
    lines.append(f"Host: {host}")
    lines.append("Connection: close")

    length = environ.get("CONTENT_LENGTH") or "0"
    try:
        length = int(length)
    except ValueError:
        length = 0
    if length:
        lines.append(f"Content-Length: {length}")
    ctype = environ.get("CONTENT_TYPE")
    if ctype:
        lines.append(f"Content-Type: {ctype}")

    for key, value in environ.items():
        if key.startswith("HTTP_"):
            header = key[5:].replace("_", "-").title()
            if header.lower().startswith("content-"):
                continue
            lines.append(f"{header}: {value}")
    lines.append("")
    lines.append("")

    head = "\r\n".join(lines).encode("latin-1", "replace")
    body = b""
    if length:
        body = environ["wsgi.input"].read(length)
    return head + body


def _parse_response(raw):
    head, _, body = raw.partition(b"\r\n\r\n")
    parts = head.split(b"\r\n")
    if not parts:
        return 500, [("Content-Type", "text/plain")], b"empty response"
    status_line = parts[0].split()
    try:
        code = int(status_line[1])
    except (IndexError, ValueError):
        code = 500
    headers = []
    for line in parts[1:]:
        name, _, value = line.partition(b": ")
        if name:
            headers.append((name.decode("latin-1"), value.decode("latin-1")))
    return code, headers, body


def _authorized(environ):
    """باسورد اختياري للوحة — الويبهوك مستثنى."""
    try:
        cfg = dashboard.load_config()
    except Exception:  # noqa: BLE001
        return True
    password = str(cfg.get("web_pass") or "")
    if not password:
        return True
    if environ.get("PATH_INFO") == "/easy/webhook":
        return True
    header = environ.get("HTTP_AUTHORIZATION") or ""
    if not header.startswith("Basic "):
        return False
    try:
        decoded = base64.b64decode(header[6:]).decode("utf-8")
    except Exception:  # noqa: BLE001
        return False
    user = str(cfg.get("web_user") or "admin")
    return decoded == f"{user}:{password}"


def call(environ, start_response):
    if not _authorized(environ):
        start_response("401 Unauthorized", [
            ("Content-Type", "text/plain; charset=utf-8"),
            ("WWW-Authenticate", 'Basic realm="Dashboard"'),
        ])
        return [b"Login required"]

    raw = _raw_request(environ)
    handler = dashboard.DashboardHandler.__new__(dashboard.DashboardHandler)
    handler.rfile = io.BytesIO(raw)
    handler.wfile = io.BytesIO()
    handler.client_address = (environ.get("REMOTE_ADDR") or "127.0.0.1", 0)
    handler.server = SimpleNamespace(server_name="localhost", server_port=443)
    handler.directory = WEB_DIR
    handler.close_connection = True
    handler.raw_requestline = handler.rfile.readline(65537)
    handler.request_version = "HTTP/1.1"
    handler.command = None

    try:
        if not handler.parse_request():
            code, headers, body = _parse_response(handler.wfile.getvalue())
        else:
            method = "do_" + handler.command
            if hasattr(handler, method):
                getattr(handler, method)()
            else:
                handler.send_error(405, "Method Not Allowed")
            code, headers, body = _parse_response(handler.wfile.getvalue())
    except Exception as exc:  # noqa: BLE001
        import traceback
        traceback.print_exc()
        code, headers, body = 500, [("Content-Type", "text/plain; charset=utf-8")], \
            f"WSGI error: {exc}".encode("utf-8")

    start_response(f"{code} {_reason(code)}", headers)
    return [body]


def _reason(code):
    return {200: "OK", 201: "Created", 400: "Bad Request", 401: "Unauthorized",
            403: "Forbidden", 404: "Not Found", 405: "Method Not Allowed",
            500: "Internal Server Error"}.get(code, "OK")
