"""ParseResult — resultado completo de parsear un documento."""

from __future__ import annotations

from dataclasses import dataclass, field
from datetime import datetime
from typing import Any

from node_type import NodeType
from resource_node import ResourceNode


@dataclass
class ParseResult:
    """Resultado completo de parsear un documento.

    Contiene el arbol de nodos, metadata del proceso de parsing y
    lista de warnings. Es el tipo de retorno unificado de todos los
    parsers del registry.

    Attributes:
        root:             Nodo raiz del arbol de documento.
        source_path:      Path o URL del documento origen.
        source_format:    Formato del documento ("pdf", "markdown", "html", "docx", etc.).
        parser_name:      Nombre del parser usado ("PDFParser", "MarkdownParser", etc.).
        parser_version:   Version del parser.
        parse_time:       Duracion del parsing en segundos.
        parse_timestamp:  Momento en que se realizo el parsing.
        meta:             Metadata adicional del proceso.
        warnings:         Lista de advertencias no fatales durante el parsing.
    """

    root: ResourceNode
    source_path: str | None = None
    source_format: str | None = None
    parser_name: str | None = None
    parser_version: str | None = None
    parse_time: float | None = None
    parse_timestamp: datetime | None = None
    meta: dict[str, Any] = field(default_factory=dict)
    warnings: list[str] = field(default_factory=list)

    @property
    def success(self) -> bool:
        """True si el parsing no genero warnings."""
        return len(self.warnings) == 0

    def get_all_nodes(self) -> list[ResourceNode]:
        """Retorna todos los nodos del arbol en orden de visita (BFS).

        Returns:
            Lista plana de ResourceNode incluyendo el nodo raiz y todos
            sus descendientes.
        """
        result: list[ResourceNode] = []
        queue = [self.root]
        while queue:
            node = queue.pop(0)
            result.append(node)
            queue.extend(node.children)
        return result

    def get_sections(
        self, min_level: int = 0, max_level: int = 10
    ) -> list[ResourceNode]:
        """Retorna todos los nodos SECTION dentro del rango de niveles indicado.

        Args:
            min_level: Nivel minimo de seccion (inclusive).
            max_level: Nivel maximo de seccion (inclusive).

        Returns:
            Lista de ResourceNode de tipo SECTION dentro del rango.
        """
        return [
            node
            for node in self.get_all_nodes()
            if node.type == NodeType.SECTION
            and min_level <= node.level <= max_level
        ]


def create_parse_result(
    root: ResourceNode,
    source_path: str | None = None,
    source_format: str | None = None,
    parser_name: str | None = None,
    parse_time: float | None = None,
    meta: dict[str, Any] | None = None,
    warnings: list[str] | None = None,
) -> ParseResult:
    """Helper para construir un ParseResult con valores por defecto sensatos.

    Args:
        root:          Nodo raiz del arbol de documento.
        source_path:   Path o URL del documento origen.
        source_format: Formato del documento.
        parser_name:   Nombre del parser.
        parse_time:    Duracion del parsing en segundos.
        meta:          Metadata adicional.
        warnings:      Lista de warnings.

    Returns:
        ParseResult construido con los parametros dados.
    """
    return ParseResult(
        root=root,
        source_path=source_path,
        source_format=source_format,
        parser_name=parser_name,
        parse_time=parse_time,
        meta=meta or {},
        warnings=warnings or [],
    )
