"""
Silique (https://www.silique.fr)
Copyright (C) 2024-2025
            
This program is free software: you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
details.

You should have received a copy of the GNU Lesser General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
"""

from typing import List, Optional
from html import escape

from ..utils import dump, CommonFormatter
from ..i18n import _


def to_id(path):
    # https://www.w3.org/TR/html4/types.html#type-name
    return ''.join(e if e in ["-", "_", ":", "."] or e.isalnum() else ":" for e in path )


class Formatter(CommonFormatter):
    """The markdown (for github) formatter"""

    name = "github"
    _table_name = "github"
    level = 50
    enter_table = "<br/>"

    def __init__(self, rougailconfig, **kwarg) -> None:
        self.max_line_variable = 0
        self.max_line_description = 0
        super().__init__(rougailconfig, **kwarg)

    def title(
        self,
        title: str,
        level: int,
    ) -> str:
        """Display family name as a title"""
        char = "#"
        return f"{char * level} {title}\n\n"

    def join(
        self,
        lst: List[str],
    ) -> str:
        """Display line in table from a list"""
        return self.enter_table.join([l.replace("\n", self.enter_table) for l in lst])

    def bold(
        self,
        msg: str,
    ) -> str:
        """Set a text to bold"""
        return f"**{msg}**"

    def italic(
        self,
        msg: str,
    ) -> str:
        """Set a text to italic"""
        return f"*{msg}*"

    def delete(
        self,
        msg: str,
    ) -> str:
        """Set a text to deleted"""
        return f"~~{msg}~~"

    def underline(
        self,
        msg: str,
    ) -> str:
        """Set a text to underline"""
        return f"<ins>{msg}</ins>"

    def stripped(
        self,
        text: str,
    ) -> str:
        """Return stripped text (as help)"""
        return text.strip().replace("\n", self.enter_table)

    def list(
        self,
        choices: list,
        *,
        inside_table: bool=True,
        type_: str="variable",
    ):
        """Display a liste of element"""
        if type_ == 'variable':
            if inside_table:
                char = f"{self.enter_table}• "
            else:
                char = "\n- "
        else:
            char = f"\n{self.family_informations_starts_line()}- "
        ret = ""
        for choice in choices:
            if not isinstance(choice, str):
                choice = dump(choice)
            ret += char + choice
        return ret

    def prop(
        self,
        prop: str,
        italic: bool,
        delete: bool,
        underline: bool,
    ) -> str:
        """Display property"""
        prop = f"`{prop}`"
        if italic:
            prop = self.italic(prop)
        if delete:
            prop = self.delete(prop)
        if underline:
            prop = self.underline(prop)
        return prop

    def table_header(self, lst):
        """Manage the header of a table"""
        return [l + "&nbsp;" * (self.max_line_variable - len(l)) for l in lst]

    def yaml(self, _dump):
        """Dump yaml part of documentation"""
        return f"```yaml\n---\n{dump(_dump)}\n```\n"

    def link_variable(self,
                      path: str,
                      true_path: str,
                      description: str,
                      filename: Optional[str],
                      ) -> str:
        name = to_id(true_path)
        if filename:
            link = f'{filename}#{name}'
        else:
            link = f'#{name}'
        return f"[{description}]({link})"

    def anchor(self,
               path: str,
               true_path: str,
               ) -> str:
        name = to_id(true_path)
        return f'<a id="{name}" name="{name}">{path}</a>'

    def link(
        self,
        comment: str,
        link: str,
        underline: bool,
    ) -> str:
        """Add a link"""
        comment = self.prop(comment, False, False, underline)
        return f"[{comment}]({link})"

    def columns(
        self,
        col: List[str],
    ) -> None:
        """count columns length"""
        for line in col:
            for l in line.split(self.enter_table):
                self.max_line_variable = max(self.max_line_variable, len(l) + 1)
                self.max_line_description = self.max_line_variable

    def to_phrase(self, text: str) -> str:
        return escape(text)

    def family_informations(self) -> str:
        info = self.bold(f"🛈 {_('Informations')}")  # ℹ️
        starts_line = self.family_informations_starts_line()
        return starts_line + info + "\n" + starts_line + "\n"

    def family_informations_starts_line(self) -> str:
        return "> "

    def family_informations_ends_line(self) -> str:
        return "\\\n"
#
#    def family_to_string(self, *args, **kwargs) -> List[str]:
#        lst = super().family_to_string(*args, **kwargs)
#        if self.name != 'github':
#            return lst
#        # remove the title
#        ret = lst.pop(0)
#        if lst:
#            ret = "\n> ".join([l.strip() for l in lst]).strip() + "\n\n"
#        return [ret]
