"""
This module contains four napari widgets declared in
different ways:

- a pure Python function flagged with `autogenerate: true`
    in the plugin manifest. Type annotations are used by
    magicgui to generate widgets for each parameter. Best
    suited for simple processing tasks - usually taking
    in and/or returning a layer.
- a `magic_factory` decorated function. The `magic_factory`
    decorator allows us to customize aspects of the resulting
    GUI, including the widgets associated with each parameter.
    Best used when you have a very simple processing task,
    but want some control over the autogenerated widgets. If you
    find yourself needing to define lots of nested functions to achieve
    your functionality, maybe look at the `Container` widget!
- a `magicgui.widgets.Container` subclass. This provides lots
    of flexibility and customization options while still supporting
    `magicgui` widgets and convenience methods for creating widgets
    from type annotations. If you want to customize your widgets and
    connect callbacks, this is the best widget option for you.
- a `QWidget` subclass. This provides maximal flexibility but requires
    full specification of widget layouts, callbacks, events, etc.

References:
- Widget specification: https://napari.org/stable/plugins/building_a_plugin/guides.html#widgets
- magicgui docs: https://pyapp-kit.github.io/magicgui/

Replace code below according to your needs.
"""

from typing import TYPE_CHECKING

from napari.utils import notifications
from qtpy.QtWidgets import QPushButton, QVBoxLayout, QWidget

from .inference import YoloInferencer

if TYPE_CHECKING:
    import napari

from pathlib import Path
import subprocess
import sys
import os

homedir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
dossier = Path(os.path.join(homedir,"models"))
script = Path(os.path.join(homedir,"deepphenotree","models.py"))                    # <- à adapter si besoin

# Cas où un fichier existe avec le même nom (ce n'est pas un dossier)
if dossier.exists() and not dossier.is_dir():
    raise RuntimeError(f"'{dossier}' existe mais ce n'est pas un dossier.")

# Si le dossier n'existe pas, on lance moi.py
if not dossier.is_dir():
    if not script.is_file():
        raise FileNotFoundError(f"Script introuvable : {script}")

    # Lance moi.py avec le même interpréteur Python que le programme courant
    result = subprocess.run([sys.executable, str(script)], check=False)

    # Optionnel : arrêter le programme si moi.py échoue
    if result.returncode != 0:
        raise SystemExit(result.returncode)

class ThreeButtonsWidget(QWidget):
    def __init__(self, viewer: "napari.viewer.Viewer"):
        super().__init__()
        self.viewer = viewer

        # 🔹 Trois modèles différents
        self_model1 = YoloInferencer(task="Flowering")
        self_model2 = YoloInferencer(task="Fruitlet")
        self_model3 = YoloInferencer(task="Fruit")

        # 🔹 Trois boutons
        self.btn1 = QPushButton("Flowering")
        self.btn2 = QPushButton("Fruitlet")
        self.btn3 = QPushButton("Fruit")

        self.btn1.clicked.connect(
            lambda: self._detect(self_model1, "Flowering")
        )
        self.btn2.clicked.connect(
            lambda: self._detect(self_model2, "Fruitlet")
        )
        self.btn3.clicked.connect(lambda: self._detect(self_model3, "Fruit"))

        # Layout
        layout = QVBoxLayout()
        layout.addWidget(self.btn1)
        layout.addWidget(self.btn2)
        layout.addWidget(self.btn3)
        self.setLayout(layout)

    def _detect(self, model: YoloInferencer, layer_name: str):
        # 1️⃣ Récupérer le layer image actif
        image_layer = self.viewer.layers.selection.active
        if image_layer is None or image_layer.__class__.__name__ != "Image":
            notifications.show_info("Select layer Image")
            return

        # 2️⃣ Récupérer les rectangles du modèle choisi
        rectangles = model.predict_boxes(image_layer.data)

        # 3️⃣ Affichage dans napari Shapes layer
        if layer_name in self.viewer.layers:
            self.viewer.layers[layer_name].data = rectangles
        else:
            self.viewer.add_shapes(
                rectangles,
                shape_type="rectangle",
                name=layer_name,
                edge_color="red",
                face_color="transparent",
                edge_width=2,
            )

        notifications.show_info(
            f"{len(rectangles)} objects detected in {layer_name}"
        )
