import html
import re


_TABLE_BLOCK_RE = re.compile(
    r"(?P<header>\|\s*[^|\n]+(?:\s*\|\s*[^|\n]+)+\s*\|)\s*"
    r"(?P<separator>\|\s*:?-{3,}:?(?:\s*\|\s*:?-{3,}:?)+\s*\|)\s*"
    r"(?P<body>(?:\|\s*[^|\n]+(?:\s*\|\s*[^|\n]+)+\s*\|\s*)+)",
    re.MULTILINE,
)
_TABLE_ROW_RE = re.compile(r"\|\s*[^|\n]+(?:\s*\|\s*[^|\n]+)+\s*\|")
_BOLD_RE = re.compile(r"\*\*(.+?)\*\*")


def _split_row_cells(row_text: str) -> list[str]:
    raw_cells = row_text.strip().strip("|").split("|")
    return [cell.strip() for cell in raw_cells]


def _format_inline_html(text: str) -> str:
    escaped = html.escape(text.strip())
    if not escaped:
        return ""

    escaped = _BOLD_RE.sub(lambda m: f"<b>{m.group(1)}</b>", escaped)
    paragraphs = [segment.strip() for segment in escaped.split("\n") if segment.strip()]
    return "<br>".join(paragraphs)


def _render_table_html(table_match: re.Match[str]) -> str:
    header_cells = _split_row_cells(table_match.group("header"))
    body_rows = []

    for row_match in _TABLE_ROW_RE.finditer(table_match.group("body")):
        row_cells = _split_row_cells(row_match.group(0))
        if len(row_cells) == len(header_cells):
            body_rows.append(row_cells)

    if not header_cells or not body_rows:
        return _format_inline_html(table_match.group(0))

    thead_html = "".join(
        f"<th style='padding:8px 10px; border:1px solid #d9d1b0; background:#f7f0d2; text-align:left;'>{html.escape(cell)}</th>"
        for cell in header_cells
    )
    tbody_parts = []
    for row in body_rows:
        row_html = "".join(
            f"<td style='padding:8px 10px; border:1px solid #e3dcc3;'>{html.escape(cell)}</td>"
            for cell in row
        )
        tbody_parts.append(f"<tr>{row_html}</tr>")

    return (
        "<table cellspacing='0' cellpadding='0' "
        "style='margin-top:8px; margin-bottom:8px; border-collapse:collapse; width:100%;'>"
        f"<thead><tr>{thead_html}</tr></thead>"
        f"<tbody>{''.join(tbody_parts)}</tbody>"
        "</table>"
    )


def format_ai_response_html(text: str) -> str:
    normalized = (text or "").replace("\r\n", "\n").strip()
    if not normalized:
        return ""

    parts = []
    last_index = 0

    for table_match in _TABLE_BLOCK_RE.finditer(normalized):
        before_text = normalized[last_index:table_match.start()]
        before_html = _format_inline_html(before_text)
        if before_html:
            parts.append(before_html)
        parts.append(_render_table_html(table_match))
        last_index = table_match.end()

    after_html = _format_inline_html(normalized[last_index:])
    if after_html:
        parts.append(after_html)

    return "<br>".join(part for part in parts if part)




