from __future__ import annotations

import re

from backend.node_registry import register_node
from backend.data_types import DataTable
from backend.nodes.helpers import _resolve_path, _import_ibw_loader


def _parse_ibw_note(note_bytes: bytes) -> list[dict]:
    try:
        text = note_bytes.decode("utf-8", errors="replace")
    except Exception:
        return []

    rows = []
    for line in text.splitlines():
        line = line.strip()
        if not line:
            continue
        match = re.match(r'^([^:=]+)[=:](.+)$', line)
        if not match:
            continue
        key = match.group(1).strip()
        value = match.group(2).strip()
        if not key:
            continue
        rows.append({"key": key, "value": value})

    return rows


@register_node(display_name="Note")
class Note:
    @classmethod
    def INPUT_TYPES(cls):
        return {
            "required": {
                "filename": ("FILE_PICKER", {"default": "", "hide_when_input_connected": "path"}),
            },
            "optional": {
                "path": ("FILE_PATH", {"label": "path"}),
            },
        }

    OUTPUTS = (
        ('DATA_TABLE', 'note'),
    )
    FUNCTION = "load"

    DESCRIPTION = (
        "Read the Note metadata from an .ibw file and display all entries "
        "as a table of key/value pairs."
    )

    def load(self, filename: str = "", path: str | None = None) -> tuple:
        selected = str(path).strip() if path is not None else str(filename).strip()
        if not selected:
            raise ValueError("No file selected.")
        path_obj = _resolve_path(selected)
        if not path_obj.exists():
            raise FileNotFoundError(f"File not found: {path_obj}")
        if path_obj.suffix.lower() != ".ibw":
            raise ValueError(f"Expected an .ibw file, got: {path_obj.suffix}")

        load_ibw = _import_ibw_loader()
        wave = load_ibw(str(path_obj))
        note_bytes = wave["wave"].get("note", b"") or b""

        rows = _parse_ibw_note(note_bytes)
        if not rows:
            raise ValueError("No metadata found in the .ibw note.")

        return (DataTable(rows),)
