"""
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

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


class Formatter(CommonFormatter):
    """The console formatter"""

    name = "console"
    level = 10
    enter_table = "\n"
    titles_color = {
        "title1": "bright_cyan underline bold",
        "title2": "bright_green underline bold",
        "title3": "green1 underline bold",
        "title4": "green3 underline bold",
        "title5": "dark_green underline bold",
    }

    def __init__(self, rougailconfig, **kwargs) -> None:
        from rich.table import Table
        from rich.theme import Theme
        from rich.console import Console
        from rich.syntax import Syntax

        self.rich_table = Table
        self.rich_console = Console
        self.rich_syntaxt = Syntax
        self.custom_theme = Theme(self.titles_color)
        self.max_line = 0
        super().__init__(rougailconfig, **kwargs)

    def _run(self, dico: dict, level: int, dico_is_already_treated=False) -> str:
        if not dico_is_already_treated:
            dico = self.dict_to_dict(dico, level, init=True)
        return self.compute(dico)

    def compute(self, dico):
        if self.rougailconfig["doc.force_true_color_terminal"]:
            force_terminal = 'xterm-256color'
        else:
            force_terminal = None
        console = self.rich_console(theme=self.custom_theme, force_terminal=force_terminal)
        with console.capture() as capture:
            for data in dico:
                console.print(data)
        return capture.get()

    def title(
        self,
        title: str,
        level: int,
    ) -> str:
        """Display family name as a title"""
        space = " " * (2 * (level - 1))
        return f"{space}[title{level}]{title}[/title{level}]\n"

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

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

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

    def delete(
        self,
        msg: str,
    ) -> str:
        """Set a text to delete"""
        return f"[strike]{msg}[/strike]"

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

    def stripped(
        self,
        text: str,
    ) -> str:
        """Return stripped text (as help)"""
        return text

    def list(
        self,
        choices: list,
        *,
        inside_table: bool=True,
        type_: str="variable",
    ) -> str:
        """Display a liste of element"""
        if type_ == "variable":
            char = f"{self.enter_table} • "
        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"""
        if italic:
            prop = self.italic(prop)
        if delete:
            prop = self.delete(prop)
        if underline:
            prop = self.underline(prop)
        prop = f"[reverse][bold] {prop} [/bold][/reverse]"
        return prop

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

    def link(
        self,
        comment: str,
        link: str,
        underline: bool,
    ) -> str:
        """Add a link"""
        return 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 = max(self.max_line, len(l) + 1)

    def table(self, with_header: bool = True) -> str:
        """Transform list to a table in string format"""
        table = self.rich_table(show_lines=True)
        if with_header:
            for column in self.table_datas.headers():
                table.add_column(column, width=self.max_line)
        for data in self.table_datas.get():
            table.add_row(*data)
        return table

    def family_informations(self) -> str:
        info = "[blue]" + self.bold(f"🛈 {_('Informations')}") + "[/blue]"
        starts_line = self.family_informations_starts_line()
        return starts_line + info + "\n" + starts_line

    def family_informations_starts_line(self) -> str:
        return "[blue]▌ [/blue]"

    def family_informations_ends_line(self) -> str:
        return "\n"

    def end_family_informations(self) -> str:
        return "\n"
