# data_combo_row.py
#
# Copyright 2024 Hari Rana (TheEvilSkeleton)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# SPDX-License-Identifier: GPL-3.0-or-later

from pathlib import Path

from gi.repository import GObject, Gtk

from refine import settings
from refine.widgets.base import InvalidSettingError
from refine.widgets.combo_row import ComboRow


@Gtk.Template.from_resource("/page/tesk/Refine/widgets/data-combo-row.ui")
class DataComboRow(ComboRow):
    """An `Adw.ComboRow` implementing the properties needed to work with `Gio.Settings`."""

    __gtype_name__ = "DataComboRow"

    revert_button = Gtk.Template.Child()
    revealer = Gtk.Template.Child()

    require_file = GObject.Property(type=str, default="")
    lookup_directory = GObject.Property(type=str, default="")
    data_subdirectory = GObject.Property(type=str, default="")

    aliases_dict: dict[str, str] = {}

    def do_setup(self) -> None:
        if not (string := self.settings.get_string(self.key)):
            raise InvalidSettingError

        system_data_dirs_list: list[Path] = []
        for directory in settings.get_system_data_dirs():
            found_directories = Path(directory, self.data_subdirectory).glob("*")
            system_data_dirs_list += found_directories

        data_dirs_list = system_data_dirs_list

        data_dirs_list += Path(
            settings.get_user_data_dir(), self.data_subdirectory
        ).glob("*")

        data_dirs_list = [
            path
            for path in data_dirs_list
            if Path(path, self.lookup_directory).is_dir()
        ]

        data_dirs_list = [
            path
            for path in data_dirs_list
            if Path(path, self.lookup_directory, self.require_file).exists()
        ]

        data_dirs_list = [path.name for path in data_dirs_list if path.is_dir()]

        if self.aliases_dict:
            data_dirs_list = [
                self.aliases_dict.get(str(path), path) for path in data_dirs_list
            ]

        self.original_list = self.transformed_list = sorted(
            {str(path) for path in data_dirs_list}, key=str.lower
        )

        data_dirs_model = Gtk.StringList.new(self.transformed_list)
        self.set_model(data_dirs_model)

        self.set_selected(self.original_list.index(string))
        self.set_is_default(self.key)
        self.connect("notify::selected", self.selected_callback)

        super().do_setup()

    @GObject.Property(type=str)
    def aliases(self) -> dict[str, str]:
        """Get a dictionary of aliases or set a newline-separated string that gets converted to a dictionary."""
        return self.aliases_dict

    @aliases.setter  # type: ignore [no-redef]
    def aliases(self, aliases: str) -> None:
        aliases_list = aliases.split()

        # Credit: https://stackoverflow.com/a/12739974
        self.aliases_dict = dict(
            zip(aliases_list[::2], aliases_list[1::2], strict=False)
        )
