"""
SAYTHON Framework - Response Object
"""
import json
from typing import Any, Optional


class Response:
    """
    Simple HTTP Response wrapper.

    Usage:
        return {"message": "ok"}              # auto-converted to JSON 200
        return Response("Not Found", 404)     # plain text
        return Response({"key": "val"}, 201)  # JSON with custom status
    """

    def __init__(self, body: Any = None, status: int = 200, headers: Optional[dict] = None):
        self.status = status
        self.headers = headers or {}

        if isinstance(body, (dict, list)):
            self._body = json.dumps(body, default=str).encode("utf-8")
            self.headers.setdefault("Content-Type", "application/json")
        elif isinstance(body, str):
            self._body = body.encode("utf-8")
            self.headers.setdefault("Content-Type", "text/plain")
        elif isinstance(body, bytes):
            self._body = body
            self.headers.setdefault("Content-Type", "application/octet-stream")
        elif body is None:
            self._body = b""
            self.headers.setdefault("Content-Type", "application/json")
        else:
            self._body = str(body).encode("utf-8")
            self.headers.setdefault("Content-Type", "text/plain")

        self.headers["Content-Length"] = str(len(self._body))

    # ------------------------------------------------------------------ #
    #  WSGI interface
    # ------------------------------------------------------------------ #
    @property
    def status_line(self) -> str:
        codes = {
            200: "OK", 201: "Created", 204: "No Content",
            400: "Bad Request", 401: "Unauthorized", 403: "Forbidden",
            404: "Not Found", 405: "Method Not Allowed",
            409: "Conflict", 500: "Internal Server Error",
        }
        label = codes.get(self.status, "Unknown")
        return f"{self.status} {label}"

    @property
    def wsgi_headers(self) -> list:
        return list(self.headers.items())

    @property
    def body(self) -> bytes:
        return self._body

    # ------------------------------------------------------------------ #
    #  Convenience constructors
    # ------------------------------------------------------------------ #
    @classmethod
    def json(cls, data: Any, status: int = 200) -> "Response":
        return cls(data, status)

    @classmethod
    def created(cls, data: Any) -> "Response":
        return cls(data, 201)

    @classmethod
    def no_content(cls) -> "Response":
        return cls(None, 204)

    @classmethod
    def error(cls, message: str, status: int = 400) -> "Response":
        return cls({"error": message}, status)

    def __repr__(self):
        return f"<Response {self.status}>"
