from _typeshed import Incomplete
from typing import Generic, NamedTuple, TypeVar, overload
from typing_extensions import TypeAlias

from qrcode.image.base import BaseImage

ModulesType: TypeAlias = list[list[bool | None]]
precomputed_qr_blanks: dict[int, ModulesType]

def make(data: Incomplete | None = None, **kwargs): ...
def copy_2d_array(x): ...

class ActiveWithNeighbors(NamedTuple):
    NW: bool
    N: bool
    NE: bool
    W: bool
    me: bool
    E: bool
    SW: bool
    S: bool
    SE: bool
    def __bool__(self) -> bool: ...

GenericImage = TypeVar("GenericImage", bound=BaseImage)  # noqa: Y001
GenericImageLocal = TypeVar("GenericImageLocal", bound=BaseImage)  # noqa: Y001

class QRCode(Generic[GenericImage]):
    modules: ModulesType
    error_correction: Incomplete
    box_size: Incomplete
    border: Incomplete
    image_factory: Incomplete
    def __init__(
        self,
        version: Incomplete | None = None,
        error_correction=0,
        box_size: int = 10,
        border: int = 4,
        image_factory: type[GenericImage] | None = None,
        mask_pattern: Incomplete | None = None,
    ) -> None: ...
    @property
    def version(self) -> int: ...
    @property
    def mask_pattern(self): ...
    modules_count: int
    data_cache: Incomplete
    data_list: Incomplete
    def clear(self) -> None: ...
    def add_data(self, data, optimize: int = 20) -> None: ...
    def make(self, fit: bool = True) -> None: ...
    def makeImpl(self, test, mask_pattern) -> None: ...
    def setup_position_probe_pattern(self, row, col) -> None: ...
    def best_fit(self, start: Incomplete | None = None): ...
    def best_mask_pattern(self): ...
    def print_tty(self, out: Incomplete | None = None) -> None: ...
    def print_ascii(self, out: Incomplete | None = None, tty: bool = False, invert: bool = False): ...
    @overload
    def make_image(self, image_factory: None = None, **kwargs) -> GenericImage: ...
    @overload
    def make_image(self, image_factory: type[GenericImageLocal], **kwargs) -> GenericImageLocal: ...
    def is_constrained(self, row: int, col: int) -> bool: ...
    def setup_timing_pattern(self) -> None: ...
    def setup_position_adjust_pattern(self) -> None: ...
    def setup_type_number(self, test) -> None: ...
    def setup_type_info(self, test, mask_pattern) -> None: ...
    def map_data(self, data, mask_pattern) -> None: ...
    def get_matrix(self): ...
    def active_with_neighbors(self, row: int, col: int) -> ActiveWithNeighbors: ...
