"""
Silique (https://www.silique.fr)
Copyright (C) 2022-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 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'


    def run(self):
        max_width = self.root.rougailconfig["display.console.max_width"]
        self.console = Console(force_terminal=True, width=max_width)
        with self.console.capture() as capture:
            ret = self.root.print()
        return ret, capture.get()

    def print(self) -> None:
        ret = self.root.exporter()
        for out in self.out:
            self.console.print(out)
        return ret

    def header(self):
        caption_line = ""
        if self.root_family.variable_default_enable:
            caption_line += _("Variable") + "\n"
        if self.root_family.variable_hidden_enable:
            caption_line += f'[{self.variable_hidden_color}]{_("Unmodifiable variable")}[/{self.variable_hidden_color}]\n'
        header_value = ""
        if self.root_family.value_unmodified_enable:
            header_value += f'[{self.value_unmodified_color}]{_("Default value")}[/{self.value_unmodified_color}]\n'
        if self.root_family.value_modified_enable:
            header_value += f'[{self.value_modified_color}]{_("Modified value")}[/{self.value_modified_color}]\n'
        if self.root_family.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])
        self.out.append(Panel.fit(caption, title=_("Caption")))
        #
        layers = Table.grid(padding=1, collapse_padding=True)
        caption.pad_edge = False
        if self.root.layer_datas:
            max_len = 0
            for datas in self.root.layer_datas.values():
                for data in datas.values():
                    max_len = max(max_len, len(data))
                display_layers = ["" for i in range(max_len)]
            for datas in self.root.layer_datas.values():
                for data in datas.values():
                    last_index = len(data) - 1
                    for idx in range(max_len):
                        if last_index < idx:
                            display_layers[idx] += "\n"
                        else:
                            display_layers[idx] += data[idx] + "\n"
            layers.add_row(*[layer[:-1] for layer in display_layers])
            self.out.append(Panel.fit(layers, title=_("Layers")))

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

    def display_error(self, tree, error, level):
        return tree.add(error)

    def display_warnings(
        self,
        warnings: list,
    ) -> None:
        tree = Tree(
            f"[bold][bright_yellow]:bell: {_('WARNINGS')}[/bright_yellow][/bold]",
            guide_style="bold bright_yellow",
        )
        for warning in warnings:
            tree.add(warning)
        self.out.append(tree)

    def add_variable(
        self, *args, **kwargs,
    ):
        key, value = super().add_variable(*args, **kwargs)
        if isinstance(value, list):
            subtree = self.get_tree().add(
                ":notebook: " + _("{0}:").format(key),
                guide_style="bold bright_blue",
            )
            for val in value:
                subtree.add(str(val))
        else:
            self.get_tree().add(":notebook: " + _("{0}: {1}").format(key, value))

    def colorize(
        self,
        values,
        option=None,
    ) -> str:
        multi = False
        ret = []
        default = []
        for idx, data in enumerate(values):
            value = data["value"]
            if isinstance(value, list):
                multi = True
            else:
                value = [value]
            for vidx, val in enumerate(value):
                if len(ret) == vidx:
                    ret.append("")
                    default.append(False)
                if idx:
                    if not default[vidx]:
                        if ret[vidx]:
                            ret[vidx] += " "
                        ret[vidx] += "("
                        default[vidx] = True
                    else:
                        ret[vidx] += " "
                    ret[vidx] += ":hourglass_flowing_sand: "
                if option:
                    val = self.convert_value(
                        option,
                        val,
                    )
                color = data["color"]
                if color is not None:
                    ret[vidx] += f"[{color}]{val}[/{color}]"
                else:
                    ret[vidx] += val
                loaded_from = data["loaded_from"]
                if loaded_from:
                    ret[vidx] += f" :arrow_backward: {loaded_from}"
        for idx in range(len(ret)):
            if default[idx]:
                ret[idx] += ")"
        if not multi:
            if not ret:
                return ""
            return ret[0]
        return ret

    def get_tree(self):
        if self.tree is None:
            if self.parent is None:
                tree = Tree
            else:
                tree = self.parent.add
#            if self.is_leader:
#                self.tree = tree(
#                    ":notebook: " + _("{0}:").format(self.family),
#                    guide_style="bold bright_blue",
#                )
#            elif self.no_icon:
            if self.no_icon:
                self.tree = tree(
                    self.family,
                    guide_style="bold bright_blue",
                )
            else:
                self.tree = tree(
                    f":open_file_folder: {self.family}",
                    guide_style="bold bright_blue",
                )
        return self.tree
