# standard
from pathlib import Path
from typing import Optional

# PyQGIS
from qgis.PyQt import uic
from qgis.PyQt.QtCore import Qt
from qgis.PyQt.QtGui import QCursor, QIcon, QPixmap
from qgis.PyQt.QtWidgets import QDialog, QLabel, QWidget


class WdgImageList(QWidget):
    def __init__(self, parent: Optional[QWidget] = None):
        """Widget to display list of images

        :param parent: parent widget, defaults to None
        :type parent: Optional[QWidget], optional
        """
        super().__init__(parent)
        uic.loadUi(Path(__file__).parent / f"{Path(__file__).stem}.ui", self)

        self.btn_next.clicked.connect(self.next)
        self.btn_prev.clicked.connect(self.prev)
        self.btn_next.setIcon(QIcon(":images/themes/default/mActionArrowRight.svg"))
        self.btn_prev.setIcon(QIcon(":images/themes/default/mActionArrowLeft.svg"))
        self.btn_next.setCursor(Qt.CursorShape.PointingHandCursor)
        self.btn_prev.setCursor(Qt.CursorShape.PointingHandCursor)

    def next(self) -> None:
        """Display next image"""
        cur_index = self.stackedWidget.currentIndex()
        if cur_index < self.stackedWidget.count():
            self.stackedWidget.setCurrentIndex(cur_index + 1)
        self._update_button_status()

    def prev(self) -> None:
        """Display previous image"""
        cur_index = self.stackedWidget.currentIndex()
        if cur_index != 0:
            self.stackedWidget.setCurrentIndex(cur_index - 1)
        self._update_button_status()

    def _update_button_status(self) -> None:
        """Update button status from current stacked index"""
        self.btn_next.setEnabled(
            self.stackedWidget.currentIndex() != self.stackedWidget.count() - 1
        )
        self.btn_prev.setEnabled(self.stackedWidget.currentIndex() != 0)

    def set_image_list(
        self, image_path_list: list[Path], display_name: Optional[str] = None
    ) -> None:
        """Defined displayed image list

        :param image_path_list: image file paths
        :type image_path_list: list[Path]
        :param display_name: display name for large image show
        :type display_name: Optional[str]
        """
        # Remove all inserted images
        while self.stackedWidget.count():
            self.stackedWidget.removeWidget(self.stackedWidget.widget(0))

        # Add label for all images
        for image_path in image_path_list:
            lbl_image = QLabel()
            # Display image if it exists
            if image_path.exists():
                name = display_name
                if name is None:
                    name = str(image_path)

                image = QPixmap(str(image_path))
                lbl_image.setCursor(QCursor(Qt.CursorShape.PointingHandCursor))
                image_small = image.scaled(
                    600,
                    300,
                    Qt.AspectRatioMode.KeepAspectRatio,
                    Qt.TransformationMode.SmoothTransformation,
                )
                lbl_image.setPixmap(image_small)
                lbl_image.setAlignment(Qt.AlignmentFlag.AlignCenter)

                # Display large image with mousePressEvent
                lbl_image.mousePressEvent = lambda event, name=name, image=image: (
                    self.show_large_image(event, name=name, image=image)
                )
            # Display message if image doesn't exists
            else:
                lbl_image.setText(self.tr("Image {} not available.").format(image_path))

            # Add label
            self.stackedWidget.insertWidget(self.stackedWidget.count(), lbl_image)

        nb_image = self.stackedWidget.count()
        self.btn_next.setVisible(nb_image > 1)
        self.btn_prev.setVisible(nb_image > 1)
        self.btn_next.setEnabled(nb_image > 1)
        self.btn_prev.setEnabled(False)
        if nb_image != 0:
            self.stackedWidget.setCurrentIndex(0)

    def show_large_image(self, event, name: str, image: QPixmap) -> None:
        """Display a full-size image in a QDialog

        :param name: Name of the windows
        :type name: str
        :param image: Image to display
        :type image: QPixmap
        """

        large_window = QDialog(self)
        large_window.setWindowTitle(name)
        large_label = QLabel(large_window)
        large_label.setPixmap(image)
        large_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        large_window.setFixedSize(image.size())
        large_window.exec()
