from __future__ import annotations

import csv
import json
from pathlib import Path


def load_csv_file_records(
    path: str | Path,
    *,
    delimiter: str = ",",
) -> list[dict[str, object]]:
    """Load one CSV file and convert rows into record dictionaries.

    Parameters
    ----------
    path : str | Path
        Path to CSV file.
    delimiter : str, default=","
        CSV delimiter.

    Returns
    -------
    list[dict[str, object]]
        Row dictionaries with parsed scalar values.
    """
    file_path = Path(path).expanduser()
    records: list[dict[str, object]] = []

    with file_path.open("r", encoding="utf-8", newline="") as handle:
        reader = csv.DictReader(handle, delimiter=delimiter)
        for row in reader:
            parsed_row: dict[str, object] = {}
            for raw_key, raw_value in row.items():
                if raw_key is None:
                    continue
                key = raw_key.strip()
                if not key:
                    continue
                value = _parse_cell(raw_value)
                if value is None:
                    continue
                parsed_row[key] = value
            if parsed_row:
                records.append(parsed_row)

    return records


def _parse_cell(value: str | None) -> object:
    """Parse one CSV cell into a typed Python value.

    Parameters
    ----------
    value : str | None
        Raw CSV cell.

    Returns
    -------
    object
        Parsed value, or ``None`` for empty cells.
    """
    if value is None:
        return None

    text = value.strip()
    if not text:
        return None

    lowered = text.lower()
    if lowered == "true":
        return True
    if lowered == "false":
        return False
    if lowered in {"none", "null"}:
        return None

    if text.startswith("{") or text.startswith("["):
        try:
            return json.loads(text)
        except json.JSONDecodeError:
            return text

    try:
        if "." not in text and "e" not in lowered:
            return int(text)
        return float(text)
    except ValueError:
        return text
