"""
AnkhDB Python SDK v2.0.0
https://github.com/your-org/ankhdb
"""
import requests

ANKHDB_SERVER_URL = "https://ankhdb-server.vercel.app"


class AnkhDB:
    """
    Client for the AnkhDB Backend-as-a-Service platform.

    Args:
        project_id (str): Your Project ID (proj_...).
        api_key    (str): Your Project API Key (ankh_sec_...).
        server_url (str): Override the server URL. Defaults to production.
        token      (str): Optional bearer token for an authenticated end-user.
    """

    def __init__(self, project_id: str, api_key: str, server_url: str = None, token: str = None):
        self.project_id = project_id
        self.api_key    = api_key
        self.base_url   = (server_url or ANKHDB_SERVER_URL).rstrip("/")
        self.token      = token

    @property
    def _headers(self) -> dict:
        h = {
            "Content-Type": "application/json",
            "x-api-key":    self.api_key,
        }
        if self.token:
            h["Authorization"] = f"Bearer {self.token}"
        return h

    def _request(self, path: str, method: str = "GET", body: dict = None):
        url = f"{self.base_url}{path}"
        response = requests.request(method, url, headers=self._headers, json=body)
        if response.ok:
            return response.json()
        raise Exception(f"AnkhDB Error {response.status_code}: {response.text}")

    # ─── Auth ────────────────────────────────────────────────────────────────

    def register(self, email: str, password: str) -> dict:
        """Register a new end-user. Auto-sets token if email verification is not required."""
        data = self._request("/api/auth/register", method="POST", body={"email": email, "password": password})
        if "token" in data:
            self.token = data["token"]
        return data

    def login(self, email: str, password: str) -> dict:
        """Log in an end-user. Auto-sets the instance token."""
        data = self._request("/api/auth/login", method="POST", body={"email": email, "password": password})
        if "token" in data:
            self.token = data["token"]
        return data

    def logout(self) -> dict:
        """Log out the current end-user. Clears the stored token."""
        self.token = None
        return {"message": "Logged out"}

    def get_session(self) -> dict:
        """Verify the current token and return session user info."""
        return self._request("/api/auth/session")

    # ─── Database ────────────────────────────────────────────────────────────

    def get_collections(self) -> list:
        """List all collections in this project."""
        res = self._request("/db/")
        return res.get("collections", res)

    def from_collection(self, collection: str) -> "AnkhQuery":
        """Target a collection for database operations."""
        return AnkhQuery(self, collection)

    # ─── Storage ─────────────────────────────────────────────────────────────

    def storage_upload(self, filepath: str, filename: str = None) -> dict:
        """Upload a file from a local path."""
        import os
        fname = filename or os.path.basename(filepath)
        headers = {"x-api-key": self.api_key}
        if self.token:
            headers["Authorization"] = f"Bearer {self.token}"
        with open(filepath, "rb") as f:
            response = requests.post(
                f"{self.base_url}/storage/upload",
                headers=headers,
                files={"file": (fname, f)},
            )
        if response.ok:
            return response.json()
        raise Exception(f"AnkhDB Storage Error {response.status_code}: {response.text}")

    def storage_list(self) -> list:
        """List all uploaded files for this project."""
        return self._request("/storage/files")

    def storage_get(self, file_id: str) -> dict:
        """Get metadata + URL for a single file."""
        return self._request(f"/storage/files/{file_id}")

    def storage_delete(self, file_id: str) -> dict:
        """Delete a file by ID."""
        return self._request(f"/storage/files/{file_id}", method="DELETE")

    # ─── Edge Functions ───────────────────────────────────────────────────────

    def invoke_function(self, name: str, payload: dict = None) -> dict:
        """
        Invoke an edge function by name.

        Args:
            name    (str):  Function name.
            payload (dict): Data available to the function as `payload`.
        """
        return self._request(f"/edge/invoke/{name}", method="POST", body=payload or {})


class AnkhQuery:
    """
    A query builder for a specific collection.
    Obtained via ``client.from_collection("my_collection")``.
    """

    def __init__(self, client: AnkhDB, collection: str):
        self._client     = client
        self._collection = collection

    def select(self) -> list:
        """Fetch all documents (filtered by your RLS policies)."""
        return self._client._request(f"/db/{self._collection}")

    def get(self, doc_id: str) -> dict:
        """Fetch a single document by ID."""
        return self._client._request(f"/db/{self._collection}/{doc_id}")

    def insert(self, data: dict) -> dict:
        """Insert a new document."""
        return self._client._request(f"/db/{self._collection}", method="POST", body=data)

    def update(self, doc_id: str, data: dict) -> dict:
        """Update an existing document by ID."""
        return self._client._request(f"/db/{self._collection}/{doc_id}", method="PUT", body=data)

    def delete(self, doc_id: str) -> dict:
        """Delete a document by ID."""
        return self._client._request(f"/db/{self._collection}/{doc_id}", method="DELETE")
