"""
Silique (https://www.silique.fr)
Copyright (C) 2022-2026

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 rich.console import Console
from rich.tree import Tree
from rich.table import Table
from rich.panel import Panel

from ..i18n import _
from ..util import CommonOutput


class OutputFamily(CommonOutput):
    level = 10
    name = "console"
    variable_hidden_color = "orange1"
    variable_normal_color = None
    value_unmodified_color = "gold1"
    value_modified_color = "green"
    value_default_color = None
    error_color = "bright_red"
    error_icon = "stop_sign"
    warning_color = "bright_yellow"
    warning_icon = "bell"
    guide_style = "bold bright_blue"

    def set_config(self, rougailconfig):
        self.max_width = rougailconfig["display.console.max_width"]

    def _run(self, root):
        console = Console(force_terminal=True, width=self.max_width)
        with console.capture() as capture:
            console.print(self.header())
            if self.layer_datas:
                console.print(self.layers())
            console.print(root)
        return True, capture.get()

    def header(self):
        caption_line = ""
        if self.variable_default_enable:
            caption_line += _("Variable") + "\n"
        if self.variable_hidden_enable:
            caption_line += (
                self.set_color(self.variable_hidden_color, _("Unmodifiable variable"))
                + "\n"
            )
        header_value = ""
        if self.value_unmodified_enable:
            header_value += (
                self.set_color(self.value_unmodified_color, _("Default value")) + "\n"
            )
        if self.value_modified_enable:
            header_value += (
                self.set_color(self.value_modified_color, _("Modified value")) + "\n"
            )
        if self.value_default_enable:
            header_value += (
                f'(:hourglass_flowing_sand: {_("Original default value")})\n'
            )
        caption = Table.grid(padding=1, collapse_padding=True)
        caption.pad_edge = False
        caption.add_row(caption_line[:-1], header_value[:-1])
        caption.pad_edge = False
        return Panel.fit(caption, title=_("Caption"))

    def layers(self):
        layers = Table.grid(padding=1, collapse_padding=True)
        first_char = "• "
        display_layers = [first_char + data for data in self.layer_datas]
        layers.add_row("\n".join(display_layers))
        return Panel.fit(layers, title=_("Layers"))

    def error_header(self):
        tree = Tree(
            f"[bold][{self.error_color}]:{self.error_icon}: {_('Caution')}[/{self.error_color}][/bold]",
            guide_style=f"bold {self.error_color}",
        )
        #        self.out.append(tree)
        return tree

    def display_error(self, level, tree, msg, default_color):
        if default_color == "errors":
            color = self.error_color
        else:
            color = self.warning_color
        if isinstance(msg, tuple):
            if len(msg) == 3:
                if msg[2] == "error":
                    color = self.error_color
                    icon = self.error_icon
                else:
                    color = self.warning_color
                    icon = self.warning_icon
                msg = f"{msg[0]}: [{color}]:{icon}: {msg[1]}[/{color}]"
            else:
                if msg[1] == "error":
                    icon = self.error_icon
                else:
                    color = self.warning_color
                    icon = self.warning_icon
                msg = f"[{color}]:{icon}: {msg[0]}[/{color}]"
        tree.guide_style = f"bold {color}"
        return tree.add(msg, guide_style=f"bold {color}")

    def display(self, tree):
        console = Console(force_terminal=True, width=self.max_width)
        with console.capture() as capture:
            console.print(tree)
        return capture.get()

    def warning_header(self):
        tree = Tree(
            f"[bold][{self.warning_color}]:{self.warning_icon}: {_('Warning')}[/{self.warning_color}][/bold]",
            guide_style=f"bold {self.warning_color}",
        )
        #        self.out.append(tree)
        return tree

    #
    #    def display_warning(self, level, tree, msg):
    #        if isinstance(msg, tuple):
    #            msg = f"{msg[0]}: [{self.warning_color}]:{self.warning_icon}: {msg[1]}[/{self.warning_color}]"
    #        return tree.add(msg, guide_style=f"bold {self.warning_color}")

    def add_variable(
        self,
        parent,
        description,
        value,
        icon,
        level,
    ):
        if icon == "leaf":
            icon = "notebook"
        else:
            icon = "open_file_folder"
        if isinstance(value, list):
            subtree = parent.add(
                f":{icon}: " + _("{0}:").format(description),
                guide_style=self.guide_style,
            )
            for val in value:
                subtree.add(str(val))
        else:
            parent.add(f":{icon}: " + _("{0}: {1}").format(description, value))

    def set_color(self, color, msg):
        if not color:
            return msg
        return f"[{color}]{msg}[/{color}]"

    def get_parent(self, parent, description, level):
        if parent is None:
            return Tree(
                description,
                guide_style=self.guide_style,
            )
        return parent.add(
            f":open_file_folder: {description}",
            guide_style=self.guide_style,
        )
