from __future__ import annotations

import logging
from concurrent.futures import ThreadPoolExecutor
from pathlib import Path

logger = logging.getLogger(__name__)

def _count_lines_single_file(file_path: Path) -> int:
    """Helper to count lines in a single file safely."""
    try:
        with file_path.open("r", encoding="utf-8", errors="ignore") as f:
            return sum(1 for _ in f)
    except OSError as e:
        logger.warning(f"Could not read file {file_path}: {e}")
        return -1

def count_lines_in_files(
    directory: str | Path, 
    extension: str, 
    max_workers: int = 8
) -> dict[str, int]:
    """Finds all files with the given extension and counts their lines concurrently.

    Args:
        directory (str | Path): Path to the target directory.
        extension (str): File extension to filter by (e.g., ".txt" or "txt").
        max_workers (int): Maximum threads for concurrent I/O.

    Returns:
        dict[str, int]: A dictionary mapping filenames to their line counts.
            Returns -1 as the line count for files that could not be read.
    """
    dir_path = Path(directory)

    if not dir_path.exists():
        raise FileNotFoundError(f"Directory not found: {directory}")
    if not dir_path.is_dir():
        raise NotADirectoryError(f"Path is not a directory: {directory}")

    ext = extension if extension.startswith(".") else f".{extension}"
    files = [f for f in dir_path.glob(f"*{ext}") if f.is_file()]

    if not files:
        return {}

    with ThreadPoolExecutor(max_workers=max_workers) as executor:
        counts = list(executor.map(_count_lines_single_file, files))

    return {f.name: count for f, count in zip(files, counts)}
