import datetime
from typing import Any, Awaitable

from pyro_mysql.async_ import Opts

# ─── Constants ────────────────────────────────────────────────────────────────

apilevel: str
threadsafety: int
paramstyle: str

# ─── Error ────────────────────────────────────────────────────────────────────

class Warning(Exception): ...
class Error(Exception): ...
class InterfaceError(Error): ...
class DatabaseError(Error): ...
class DataError(DatabaseError): ...
class OperationalError(DatabaseError): ...
class IntegrityError(DatabaseError): ...
class InternalError(DatabaseError): ...
class ProgrammingError(DatabaseError): ...
class NotSupportedError(DatabaseError): ...

# ─── Connection ───────────────────────────────────────────────────────────────

def connect(url_or_opts: str | Opts) -> Awaitable[Connection]:
    """
    Create an async DB-API 2.0 compliant connection to a MySQL server.

    Args:
        url_or_opts: MySQL connection URL (e.g., 'mysql://user:password@host:port/database')
            or Opts object with connection configuration.

    Returns:
        An awaitable that resolves to a DB-API 2.0 compliant Connection object.

    Example:
        >>> import pyro_mysql.dbapi_async as dbapi
        >>> conn = await dbapi.connect('mysql://root:password@localhost:3306/mydb')
        >>> cursor = conn.cursor()
        >>> await cursor.execute('SELECT 1')
        >>> result = await cursor.fetchone()
    """
    ...

class Connection:
    # PEP-249 required methods (async versions)
    def close(self) -> Awaitable[None]: ...
    def commit(self) -> Awaitable[None]: ...
    def rollback(self) -> Awaitable[None]: ...
    def cursor(self) -> "Cursor": ...

    # Helper methods
    def ping(self) -> Awaitable[None]: ...
    def set_autocommit(self, on: bool) -> Awaitable[None]: ...
    def last_insert_id(self) -> Awaitable[int]: ...
    def is_closed(self) -> Awaitable[bool]: ...

class Cursor:
    # PEP-249 required methods (async versions)
    def close(self) -> Awaitable[None]: ...
    def execute(self, query: str, params: Any = ...) -> Awaitable[None]: ...
    def executemany(self, query: str, params: list[Any]) -> Awaitable[None]: ...
    def fetchone(self) -> Awaitable[tuple[Any, ...] | None]: ...
    def fetchmany(
        self, size: int | None = None
    ) -> Awaitable[list[tuple[Any, ...]]]: ...
    def fetchall(self) -> Awaitable[list[tuple[Any, ...]]]: ...

    # PEP-249 optional extensions
    def __aiter__(self) -> "Cursor": ...
    def __anext__(self) -> Awaitable[tuple[Any, ...] | None]: ...
    def setinputsizes(self) -> None: ...
    def setoutputsize(self) -> None: ...

# ─── Type Constructor ─────────────────────────────────────────────────────────

def Date(year: int, month: int, day: int) -> datetime.date: ...
def Time(hour: int, minute: int, second: int) -> datetime.time: ...
def Timestamp(
    year: int, month: int, day: int, hour: int, minute: int, second: int
) -> datetime.datetime: ...
def DateFromTicks(ticks: int) -> datetime.date: ...
def TimeFromTicks(ticks: int) -> datetime.time: ...
def TimestampFromTicks(ticks: int) -> datetime.datetime: ...
def Binary(x: Any) -> bytes: ...
