import re
from datetime import datetime, timezone
from typing import List, Tuple

from bs4 import BeautifulSoup
from markdown_it import MarkdownIt
from spacy.lang.en import English

__nlp__ = English()
__nlp__.add_pipe("sentencizer")


def sent_tokenize(text: str) -> List[str]:
    global __nlp__

    text = recover_broken_sentences(text.strip())

    sentences = []
    for line in text.splitlines():
        line = line.strip()
        if not line:
            continue

        doc = __nlp__(line)
        for sent in doc.sents:
            sentences.append(sent.text.strip())

    return sentences


def sent_tokenize_with_newlines(text: str) -> List[str]:
    blocks = [sent_tokenize(block) for block in text.split("\n")]
    sentences = []
    for block in blocks:
        sentences.extend(block)
        sentences.append("\n")
    return sentences[:-1]


def recover_broken_sentences(text: str) -> str:
    return re.sub(r"([^\s\.])[^\S\n]*\n([^\s])", r"\1 \2", text)


def clean_md_to_text(md_doc: str) -> str:
    html = MarkdownIt().render(md_doc)
    soup = BeautifulSoup(html, "html.parser")
    text = soup.get_text()
    return text


def find_and_split_by_regex(pattern: str, string: str) -> Tuple[List, List]:
    separators = [found.strip() for found in re.findall(pattern, string, flags=re.I)]
    separated = [split.strip() for split in re.split(pattern, string, flags=re.I)]
    return separators, separated


def now_string() -> str:
    return datetime.now(tz=timezone.utc).strftime("%Y%m%d_%H%M%S")


def is_now_string(s: str) -> bool:
    now_pattern = r"^\d{8}_\d{6}$"
    return bool(re.match(now_pattern, s))
