import re

from dataclasses  import dataclass
from imgui_bundle import imgui, imgui_md


_TABLE_SEPARATOR = re.compile(r"^\|?\s*:?-{2,}:?\s*(\|\s*:?-{2,}:?\s*)+\|?\s*$")

def render_table(block: "TableBlock") -> None:
 """Render a GFM table block via imgui.begin_table.
 [C: src/markdown_helper.py:MarkdownRenderer.render]
 """
 n_cols = len(block.headers)
 if n_cols == 0: return
 flags = imgui.TableFlags_.borders | imgui.TableFlags_.row_bg | imgui.TableFlags_.resizable
 if not imgui.begin_table("md_table", n_cols, flags): return
 for h in block.headers:
  imgui.table_setup_column(h, imgui.TableColumnFlags_.width_stretch)
 imgui.table_headers_row()
 for row in block.rows:
  imgui.table_next_row()
  for c in row:
   imgui.table_next_column()
   imgui_md.render(c)
 imgui.end_table()

@dataclass(frozen=True)
class TableBlock:
 """Frozen GFM table block.
 [C: src/markdown_helper.py:MarkdownRenderer.render]
 """
 headers: list[str]
 rows:    list[list[str]]
 span:    tuple[int, int]

def _split_row(line: str) -> list[str]:
 line = line.strip()
 if line.startswith("|"): line = line[1:]
 if line.endswith("|"): line = line[:-1]
 return [c.strip() for c in line.split("|")]

def _is_table_at(lines: list[str], i: int) -> bool:
 if i + 1 >= len(lines): return False
 if "|" not in lines[i]: return False
 return bool(_TABLE_SEPARATOR.match(lines[i + 1]))

def parse_tables(text: str) -> list[TableBlock]:
 lines    = text.splitlines()
 in_fence = False
 blocks: list[TableBlock] = []
 i = 0
 while i < len(lines):
  line = lines[i]
  if line.strip().startswith("```"):
   in_fence = not in_fence
   i       += 1
   continue
  if in_fence:
   i += 1
   continue
  if _is_table_at(lines, i):
   headers = _split_row(lines[i])
   j       = i + 2
   rows: list[list[str]] = []
   while j < len(lines) and "|" in lines[j] and not _TABLE_SEPARATOR.match(lines[j]):
    rows.append(_split_row(lines[j]))
    j += 1
   blocks.append(TableBlock(headers=headers, rows=rows, span=(i, j)))
   i = j
   continue
  i += 1
 return blocks
