"""Parser CSV a datos tabulares (RFC 4180). Complemento de to_csv."""


def _parse_row(line: str, delimiter: str) -> list[str]:
    """Parsea una linea CSV respetando campos entre comillas (RFC 4180)."""
    fields: list[str] = []
    field_chars: list[str] = []
    in_quotes = False
    i = 0

    while i < len(line):
        ch = line[i]

        if in_quotes:
            if ch == '"':
                # Comilla doble escapada o cierre de campo
                if i + 1 < len(line) and line[i + 1] == '"':
                    field_chars.append('"')
                    i += 2
                    continue
                else:
                    in_quotes = False
            else:
                field_chars.append(ch)
        else:
            if ch == '"' and not field_chars:
                in_quotes = True
            elif ch == delimiter:
                fields.append("".join(field_chars))
                field_chars = []
            else:
                field_chars.append(ch)
        i += 1

    fields.append("".join(field_chars))
    return fields


def from_csv(
    text: str,
    delimiter: str = ",",
    has_header: bool = True,
) -> list[dict]:
    """Parser CSV a lista de dicts.

    Complemento de to_csv. Soporta campos entre comillas con escaping RFC 4180.
    Si has_header=False, genera keys col_0, col_1, etc.

    Args:
        text: Contenido CSV completo como string.
        delimiter: Separador de campos. Por defecto coma.
        has_header: Si True, primera fila es el encabezado.
                    Si False, genera keys col_0, col_1, ...

    Returns:
        Lista de dicts. Lista vacia si el texto esta vacio o solo tiene header.
    """
    # Normalizar line endings
    normalized = text.replace("\r\n", "\n").replace("\r", "\n")
    lines = [l for l in normalized.split("\n") if l.strip() != ""]

    if not lines:
        return []

    if has_header:
        headers = _parse_row(lines[0], delimiter)
        data_lines = lines[1:]
    else:
        # Determinar numero de columnas desde la primera fila
        sample = _parse_row(lines[0], delimiter)
        headers = [f"col_{i}" for i in range(len(sample))]
        data_lines = lines

    result: list[dict] = []
    for line in data_lines:
        fields = _parse_row(line, delimiter)
        # Alinear con headers (rellenar con "" si faltan campos)
        row = {}
        for i, header in enumerate(headers):
            row[header] = fields[i] if i < len(fields) else ""
        result.append(row)

    return result
