# Window.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 logging

from PyQt5.QtCore import QCoreApplication

from PyQt5.QtGui import (
    QKeySequence,
)

from PyQt5.QtCore import (
    Qt, QRect, QVariant, QAbstractTableModel, pyqtSlot, pyqtSignal,
    QEvent,
)

from PyQt5.QtWidgets import (
    QTableView, QItemDelegate, QComboBox, QLineEdit, QHBoxLayout, QSlider,
    QPushButton, QCheckBox, QStyledItemDelegate, QStyleOptionButton, QStyle,
    QApplication, QToolBar, QAction, QHeaderView, QAbstractItemView,
    QUndoStack, QShortcut,
)

from Modules import Modules
from Model.River import RiverNode, RiverReach, River

from View.WaitingDialog import WaitingDialog
from View.Tools.PamhyrWindow import PamhyrWindow
from View.Scenarios.GraphWidget import GraphWidget
from View.Scenarios.UndoCommand import *
from View.Scenarios.translate import ScenariosTranslate
from View.Scenarios.Table import ScenariosTableModel

# Reservoir short cut
from View.Reservoir.Edit.Window import EditReservoirWindow
import View.Reservoir.UndoCommand as ResUndoCommand


logger = logging.getLogger()

_translate = QCoreApplication.translate


class ScenariosWindow(PamhyrWindow):
    _pamhyr_ui = "Scenarios"
    _pamhyr_name = "Scenarios"

    def __init__(self, study=None, config=None, parent=None):
        trad = ScenariosTranslate()
        name = trad[self._pamhyr_name] + " - " + study.name

        super(ScenariosWindow, self).__init__(
            title=name,
            study=study,
            config=config,
            trad=trad,
            options=['undo'],
            parent=parent,
        )

        self._table_headers_scenarios = self._trad.get_dict(
            "table_headers_scenarios"
        )

        self.setup_graph()
        self.setup_table()
        self.setup_connections()

    def setup_graph(self):
        self._graph_widget = GraphWidget(
            self._study,
            undo=self._undo_stack,
            trad=self._trad,
            parent=self,
        )

        self._graph_layout = self.find(
            QHBoxLayout, "horizontalLayout_graph"
        )

        self._graph_layout.addWidget(self._graph_widget)

    def setup_table(self):
        table = self.find(QTableView, "tableView_scenarios")
        self._scenarios_model = ScenariosTableModel(
            table_view=table,
            table_headers=self._table_headers_scenarios,
            editable_headers=["name", "description"],
            data=self._study,
            undo=self._undo_stack,
        )
        table.setModel(self._scenarios_model)

        table.setSelectionBehavior(QAbstractItemView.SelectRows)
        table.horizontalHeader()\
             .setSectionResizeMode(QHeaderView.Stretch)

    def setup_connections(self):
        self._scenarios_model.dataChanged.connect(self.update)
        self._graph_widget.changeScenario.connect(self.update)

    def _undo(self):
        def fn():
            self._undo_stack.undo()

        dlg = WaitingDialog(
            payload_fn=fn,
            title="undo_waiting",
            trad=self._trad,
            parent=self
        )
        dlg.exec_()

        self.update()

    def _redo(self):
        def fn():
            self._undo_stack.redo()

        dlg = WaitingDialog(
            payload_fn=fn,
            title="redo_waiting",
            trad=self._trad,
            parent=self
        )
        dlg.exec_()

        self.update()

    def update(self):
        self._scenarios_model.update()
        self._graph_widget.display_update()
        self._set_title()

        self._propagate_update(key=Modules.SCENARIOS)
