"""Markdown parser — headings, links, code block languages."""

from __future__ import annotations

import re

from codectx.parser.types import DependencyRecord, EntityRecord, ParseResult

_HEADING_RE   = re.compile(r"^(#{1,6})\s+(.+)$", re.MULTILINE)
_LINK_RE      = re.compile(r"\[([^\]]+)\]\(([^)]+)\)", re.MULTILINE)
_IMAGE_RE     = re.compile(r"!\[([^\]]*)\]\(([^)]+)\)", re.MULTILINE)
_FENCE_RE     = re.compile(r"^```(\w*)\s*$", re.MULTILINE)
_FRONT_RE     = re.compile(r"^---\s*\n(.*?)\n---", re.DOTALL)


_HEADING_TYPES = {1: "h1", 2: "h2", 3: "h3", 4: "h4", 5: "h5", 6: "h6"}


def _ln(content: str, pos: int) -> int:
    return content[:pos].count("\n") + 1


def parse_markdown(file_path: str, content: str) -> ParseResult:
    result = ParseResult(file_path=file_path, language="markdown")

    for m in _HEADING_RE.finditer(content):
        level = len(m.group(1))
        text = m.group(2).strip()
        result.entities.append(EntityRecord(
            name=text, qualified_name=text,
            type="heading", kind=_HEADING_TYPES.get(level, "heading"),
            start_line=_ln(content, m.start()), end_line=_ln(content, m.start()),
            language="markdown",
        ))

    # images before links to avoid overlap
    image_spans: set[int] = set()
    for m in _IMAGE_RE.finditer(content):
        image_spans.add(m.start())
        alt = m.group(1)
        src = m.group(2)
        result.dependencies.append(DependencyRecord(
            path=src, type="image", line_number=_ln(content, m.start()),
        ))

    for m in _LINK_RE.finditer(content):
        if m.start() in image_spans:
            continue
        url = m.group(2)
        if url.startswith("http"):
            dep_type = "url"
        elif url.startswith("#"):
            dep_type = "anchor"
        else:
            dep_type = "file"
        result.dependencies.append(DependencyRecord(
            path=url, type=dep_type, line_number=_ln(content, m.start()),
        ))

    for m in _FENCE_RE.finditer(content):
        lang = m.group(1).strip()
        if lang:
            result.entities.append(EntityRecord(
                name=lang, qualified_name=lang, type="code_block",
                start_line=_ln(content, m.start()), end_line=_ln(content, m.start()),
                language="markdown",
            ))

    return result
