# -*- coding: utf-8 -*-
"""
Dock widget - Sen Hydro - Delimitation de Bassins Versants
Auteur : Adiouma FALL - Geo Senegal 2026

Panneau lateral inspire des options du site mghydro.com/watersheds :
options de calcul, style d'affichage, et rapport du bassin versant.
"""

from qgis.PyQt.QtCore import Qt, pyqtSignal
from qgis.PyQt.QtGui import QColor
from qgis.PyQt.QtWidgets import (
    QDockWidget, QWidget, QVBoxLayout, QFormLayout, QGroupBox, QCheckBox,
    QDoubleSpinBox, QPushButton, QLabel, QTextEdit, QComboBox,
    QSlider, QScrollArea,
)
from qgis.gui import QgsColorButton


class SenHydroDockWidget(QDockWidget):

    reportExportRequested = pyqtSignal()

    def __init__(self, parent=None):
        super().__init__("Sen Hydro - Bassins versants", parent)
        self.setObjectName("SenHydroDockWidget")

        content = QWidget()
        layout = QVBoxLayout(content)

        # --- Mode ---
        mode_box = QGroupBox("Mode")
        mode_layout = QVBoxLayout(mode_box)
        self.mode_combo = QComboBox()
        self.mode_combo.addItem("Amont - Delimiter le bassin versant")
        mode_layout.addWidget(self.mode_combo)
        mode_note = QLabel(
            "Note : le mode Aval (trace du trajet d'ecoulement, flowpath_api) "
            "existe cote mghydro.com mais n'est pas encore integre a Sen "
            "Hydro. Seul le mode amont (bassin versant) est disponible ici."
        )
        mode_note.setWordWrap(True)
        mode_note.setStyleSheet("color: gray; font-size: 10px;")
        mode_layout.addWidget(mode_note)
        layout.addWidget(mode_box)

        # --- Options de calcul ---
        # Correspond exactement aux 3 parametres optionnels acceptes par
        # l'API Global Watersheds (mghydro.com/app/watershed_api) :
        # precision, simplify, beautify.
        opt_box = QGroupBox("Options de calcul")
        opt_layout = QFormLayout(opt_box)

        self.chk_high_res = QCheckBox("Haute precision")
        self.chk_high_res.setChecked(True)
        opt_layout.addRow(self.chk_high_res)

        self.chk_simplify = QCheckBox("Simplifier")
        opt_layout.addRow(self.chk_simplify)

        self.chk_smooth = QCheckBox("Beautifier (lissage)")
        opt_layout.addRow(self.chk_smooth)

        layout.addWidget(opt_box)

        # --- Affichage ---
        disp_box = QGroupBox("Afficher")
        disp_layout = QVBoxLayout(disp_box)
        self.chk_show_rivers = QCheckBox("Reseau hydrographique")
        self.chk_show_rivers.setChecked(True)
        self.chk_show_watershed = QCheckBox("Limite du bassin versant")
        self.chk_show_watershed.setChecked(True)
        self.chk_show_outlet = QCheckBox("Point exutoire")
        self.chk_show_outlet.setChecked(True)
        disp_layout.addWidget(self.chk_show_rivers)
        disp_layout.addWidget(self.chk_show_watershed)
        disp_layout.addWidget(self.chk_show_outlet)

        self.chk_outlet_both = QCheckBox(
            "  Afficher les 2 points (clique + ajuste a la riviere)"
        )
        self.chk_outlet_both.setChecked(True)
        outlet_note = QLabel(
            "  Le point exutoire est parfois legerement deplace ('ajuste') "
            "vers le cours d'eau le plus proche pour un calcul plus precis. "
            "Decochez pour ne garder que le point ajuste (utilise pour le calcul)."
        )
        outlet_note.setWordWrap(True)
        outlet_note.setStyleSheet("color: gray; font-size: 10px;")
        disp_layout.addWidget(self.chk_outlet_both)
        disp_layout.addWidget(outlet_note)

        layout.addWidget(disp_box)

        # --- Emprise ---
        extent_box = QGroupBox("Emprise")
        extent_layout = QVBoxLayout(extent_box)
        self.chk_clip_senegal = QCheckBox(
            "Limiter au territoire du Senegal (limites communales)"
        )
        self.chk_clip_senegal.setChecked(True)
        extent_layout.addWidget(self.chk_clip_senegal)
        extent_note = QLabel(
            "Le bassin versant et le reseau hydrographique seront decoupes "
            "selon la frontiere du Senegal (limites communales officielles, "
            "integrees au plugin). Aucune couche a charger manuellement."
        )
        extent_note.setWordWrap(True)
        extent_note.setStyleSheet("color: gray; font-size: 10px;")
        extent_layout.addWidget(extent_note)
        layout.addWidget(extent_box)

        # --- Nappes phreatiques et pedologie ---
        aquifer_box = QGroupBox("Nappes phreatiques et pedologie")
        aquifer_layout = QVBoxLayout(aquifer_box)
        self.chk_cross_aquifers = QCheckBox(
            "Croiser avec les unites aquiferes et les types de sol"
        )
        aquifer_layout.addWidget(self.chk_cross_aquifers)
        aquifer_note = QLabel(
            "Si coche, le bassin versant delimite sera croise avec les "
            "unites aquiferes (nappes phreatiques) et les unites "
            "morphopedologiques (types de sol), integrees au plugin : les "
            "unites concernees et leur surface seront ajoutees au rapport, "
            "et deux couches d'intersection seront chargees sur la carte."
        )
        aquifer_note.setWordWrap(True)
        aquifer_note.setStyleSheet("color: gray; font-size: 10px;")
        aquifer_layout.addWidget(aquifer_note)
        layout.addWidget(aquifer_box)

        # --- Style ---
        style_box = QGroupBox("Style")
        style_layout = QFormLayout(style_box)

        self.btn_river_color = QgsColorButton()
        self.btn_river_color.setColor(QColor(30, 120, 220))
        style_layout.addRow("Couleur rivieres", self.btn_river_color)

        self.btn_watershed_color = QgsColorButton()
        self.btn_watershed_color.setColor(QColor(46, 125, 50))
        style_layout.addRow("Couleur bassin", self.btn_watershed_color)

        self.slider_opacity = QSlider(Qt.Horizontal)
        self.slider_opacity.setRange(0, 100)
        self.slider_opacity.setValue(35)
        style_layout.addRow("Transparence remplissage (%)", self.slider_opacity)

        self.spin_line_width = QDoubleSpinBox()
        self.spin_line_width.setRange(0.1, 5.0)
        self.spin_line_width.setSingleStep(0.1)
        self.spin_line_width.setValue(0.6)
        self.spin_line_width.setSuffix(" mm")
        style_layout.addRow("Epaisseur des lignes", self.spin_line_width)

        layout.addWidget(style_box)

        # --- Action ---
        self.btn_activate = QPushButton("Cliquer sur la carte pour delimiter")
        self.btn_activate.setCheckable(True)
        layout.addWidget(self.btn_activate)

        # --- Rapport ---
        report_box = QGroupBox("Rapport du bassin versant")
        report_layout = QVBoxLayout(report_box)
        self.report_text = QTextEdit()
        self.report_text.setReadOnly(True)
        self.report_text.setPlaceholderText(
            "Cliquez sur la carte pour generer un bassin versant : "
            "les statistiques s'afficheront ici."
        )
        self.report_text.setMinimumHeight(120)
        report_layout.addWidget(self.report_text)
        self.btn_export_report = QPushButton("Exporter le rapport (.txt)")
        self.btn_export_report.setEnabled(False)
        report_layout.addWidget(self.btn_export_report)
        layout.addWidget(report_box)

        layout.addStretch()
        content.setLayout(layout)

        scroll = QScrollArea()
        scroll.setWidgetResizable(True)
        scroll.setWidget(content)
        self.setWidget(scroll)

        self.btn_export_report.clicked.connect(self.reportExportRequested.emit)
        self._last_report_text = ""

    # ------------------------------------------------------------------
    def get_config(self):
        """
        Retourne un dict avec les options de calcul, traduites en parametres
        de l'API Global Watersheds (precision/simplify/beautify) par
        WatershedDelineatorPlugin._build_api_url().
        """
        return {
            "high_res": self.chk_high_res.isChecked(),
            "simplify": self.chk_simplify.isChecked(),
            "smooth": self.chk_smooth.isChecked(),
        }

    def get_style(self):
        return {
            "river_color": self.btn_river_color.color(),
            "watershed_color": self.btn_watershed_color.color(),
            "opacity": self.slider_opacity.value() / 100.0,
            "line_width": self.spin_line_width.value(),
        }

    def show_report(self, stats, lat, lon):
        lines = []
        lines.append("Point exutoire : lat %.5f, lon %.5f" % (lat, lon))
        if stats.get("clipped_outside_senegal"):
            lines.append(
                "Le bassin versant obtenu est entierement hors du territoire "
                "senegalais (Limites_communes) : aucune surface n'a ete conservee."
            )
        if "area_km2" in stats:
            lines.append("Surface du bassin versant : %.2f km2" % stats["area_km2"])
        if "perimeter_km" in stats:
            lines.append("Perimetre : %.2f km" % stats["perimeter_km"])
        if "river_length_km" in stats:
            lines.append("Longueur du reseau hydrographique : %.2f km" % stats["river_length_km"])
        if "river_reach_count" in stats:
            lines.append("Nombre de troncons de riviere : %d" % stats["river_reach_count"])
        if "max_stream_order" in stats:
            lines.append("Ordre d'ecoulement maximal (Strahler) : %d" % stats["max_stream_order"])
        if stats.get("aquifer_layer_missing"):
            lines.append(
                "Couche 'unites_aquiferes_corrige' introuvable dans le projet : "
                "croisement avec les nappes phreatiques ignore."
            )
        if "aquifer_units" in stats:
            lines.append("Unites aquiferes concernees : %s" % ", ".join(stats["aquifer_units"]))
        if "aquifer_unit_areas_km2" in stats:
            for nom in stats["aquifer_units"]:
                area = stats["aquifer_unit_areas_km2"].get(nom, 0.0)
                lines.append("   - %s : %.2f km2" % (nom, area))
        if "aquifer_area_km2" in stats:
            lines.append("Surface totale en zone aquifere : %.2f km2" % stats["aquifer_area_km2"])
        if stats.get("soil_layer_missing"):
            lines.append(
                "Couche 'Morpho_Pedo' introuvable : croisement avec les "
                "types de sol ignore."
            )
        if "soil_units" in stats:
            lines.append("Types de sol concernes : %s" % ", ".join(stats["soil_units"]))
        if "soil_unit_areas_km2" in stats:
            for nom in stats["soil_units"]:
                area = stats["soil_unit_areas_km2"].get(nom, 0.0)
                lines.append("   - %s : %.2f km2" % (nom, area))
        if "soil_area_km2" in stats:
            lines.append("Surface totale couverte (sol) : %.2f km2" % stats["soil_area_km2"])
        if len(lines) == 1:
            lines.append("Aucune statistique supplementaire disponible pour ce bassin.")
        text = "\n".join(lines)
        self.report_text.setPlainText(text)
        self._last_report_text = text
        self.btn_export_report.setEnabled(True)

    def get_report_text(self):
        return self._last_report_text
