from typing import (
    Dict,
    List,
    Union,
    NewType,
)

from ._HTMLTextFormatter import HTMLTextFormatter

JSON = Union[Dict[str, "JSON"], List["JSON"], str, int, float, bool, None]  # type: NewType("JSON", JSON)


class LineParser(object):

    def __init__(
        self,       # type: LineParser
        columns,    # type: int
    ):
        # type: (...) -> None

        self.columns = columns

    def parse(
        self,    # type: LineParser
        line,    # type: JSON
    ):
        # type: (...) -> List[str]

        lines = self._get_lines_split_by_columns(text=line.get("text"))
        return self._format_lines(
            lines=lines,
            customization=line.get("customization"),
        )

    def _format_lines(
        self,             # type: LineParser
        lines,            # type: List[str]
        customization,    # type: Dict[str, Union[str, bool, int, float]]
    ):
        # type: (...) -> List[str]

        formatted = []
        html_text_formatter = HTMLTextFormatter(
            customization=customization,
            columns=self.columns,
        )
        for line in lines:
            formatted.append(html_text_formatter.format(text=line))
            formatted.append("<br/>")

        formatted.pop()

        return formatted

    def _get_lines_split_by_columns(
        self,    # type: LineParser
        text,    # type: str
    ):
        # type: (...) -> List[str]

        if len(text) <= self.columns:
            return [text]
        elif text.count("\\n") > 0:
            return text.split("\\n")

        lines = []
        words = text.split()
        current_line = ""
        index = 0
        while True:
            current_line += words[index] + " "
            index += 1
            if index >= len(words):
                lines.append(current_line.strip())
                break

            if len(current_line + words[index]) > self.columns:
                lines.append(current_line.strip())
                current_line = ""

        return lines
