# PamhyrWindow.py -- Pamhyr
# Copyright (C) 2023-2026  INRAE
#
# 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 <https://www.gnu.org/licenses/>.

# -*- coding: utf-8 -*-

import os
import logging

from PyQt5.QtGui import (
    QKeySequence, QIcon,
)

from PyQt5.QtWidgets import (
    QUndoStack, QShortcut,
)

from Modules import Modules

from View.Tools.ASubWindow import ASubMainWindow, ASubWindow
from View.Tools.ListedSubWindow import ListedSubWindow

logger = logging.getLogger()


class PamhyrWindowTools(object):
    def __init__(self, options=["undo", "copy"], parent=None, **kwargs):
        super(PamhyrWindowTools, self).__init__()

        self._hash_data = []
        self._undo_stack = None

        if "undo" in options:
            self._init_undo()

        if "copy" in options:
            self._init_copy()

    # Undo/Redo

    def _init_undo(self):
        self._undo_stack = QUndoStack()

        self._undo_sc = QShortcut(QKeySequence.Undo, self)
        self._redo_sc = QShortcut(QKeySequence.Redo, self)

        self._undo_sc.activated.connect(self._undo)
        self._redo_sc.activated.connect(self._redo)

    def _undo(self):
        if self._undo_stack is not None:
            self._undo_stack.undo()
            self._update()

    def _redo(self):
        if self._undo_stack is not None:
            self._undo_stack.redo()
            self._update()

    # Copy/Paste

    def _init_copy(self):
        self._copy_sc = QShortcut(QKeySequence.Copy, self)
        self._paste_sc = QShortcut(QKeySequence.Paste, self)

        self._copy_sc.activated.connect(self._copy)
        self._paste_sc.activated.connect(self._paste)

    def _copy(self):
        return

    def _paste(self):
        return

    # Display

    def _set_title(self):
        """Apply `self._title` at current window title displayed

        Returns:
            Nothing
        """
        self.ui.setWindowTitle(self._title)

    def _set_icon(self):
        self.setWindowIcon(
            QIcon(
                os.path.join(
                    self._get_ui_directory(),
                    "ressources",
                    "Pamhyr2_logo.png"
                )
            )
        )

    def _update(self):
        """Update window display component

        Returns:
            Nothing
        """
        self._set_title()

    def _propagate_update(self, key=Modules(0)):
        logger.debug(f"_propagate_update({key}) to {self._parent}")
        if self._parent is not None:
            self._parent._propagate_update(key=key)

    def _propagated_update(self, key=Modules(0)):
        if key is Modules(0):
            return

        # Update ...
        return

    # Hash methods

    @classmethod
    def _hash(cls, data):
        """Compute window hash

        Args:
            data: window data parameters

        Returns:
            The hash
        """
        hash_str = cls._pamhyr_name
        hash_str += cls._pamhyr_ui

        for el in data:
            hash_str += repr(el)

        h = hash(hash_str)

        return h

    def hash(self):
        """Compute window hash

        Returns:
            The hash
        """
        return self._hash(self._hash_data)


class PamhyrWindow(ASubMainWindow, ListedSubWindow, PamhyrWindowTools):
    _pamhyr_ui = "dummy"
    _pamhyr_name = "PamhyrWindow"

    def __init__(self,
                 title="Pamhyr2",
                 study=None, config=None, trad=None,
                 options=["undo", "copy"],
                 parent=None):
        self._title = title
        self._study = study
        self._config = config
        self._trad = trad
        self._parent = parent

        super(PamhyrWindow, self).__init__(
            name=self._pamhyr_name,
            ui=self._pamhyr_ui,
            parent=parent,
        )

        self._hash_data.append(self._study)
        self._hash_data.append(self._config)

        self._set_title()
        self._set_icon()
        self._setup_save_sc()

    def _set_title(self):
        title = self._title

        if self._study is not None:
            if self._study.is_read_only():
                title = "⛔ " + title

            scenario = self._study.status.scenario
            if scenario is not None and scenario.name != "default":
                title += f" | {scenario.name}"

        self.ui.setWindowTitle(title)

    def _setup_save_sc(self):
        if self._parent is None:
            return

        self._save_sc = QShortcut(QKeySequence("Ctrl+S"), self)
        self._save_sc.activated.connect(lambda: self._save(self))

    def closeEvent(self, event):
        self._close_sub_window()
        self._propagate_update(Modules.WINDOW_LIST)

        super(PamhyrWindow, self).closeEvent(event)

    def _save(self, source):
        if self._parent is None:
            return

        return self._parent._save(source)


class PamhyrDialog(ASubWindow, ListedSubWindow, PamhyrWindowTools):
    _pamhyr_ui = "dummy"
    _pamhyr_name = "PamhyrWindow"

    def __init__(self,
                 title="Pamhyr2",
                 study=None, config=None, trad=None,
                 options=["undo", "copy"],
                 parent=None):
        self._title = title
        self._study = study
        self._config = config
        self._trad = trad
        self._parent = parent

        super(PamhyrDialog, self).__init__(
            name=self._pamhyr_name,
            ui=self._pamhyr_ui,
            parent=parent,
        )

        self._hash_data.append(self._study)
        self._hash_data.append(self._config)

        self._set_title()

    def done(self, result):
        if self.parent is not None:
            self.parent.sub_win_del(self.hash())
        super(PamhyrDialog, self).done(result)
