from qgis.PyQt.QtWidgets import *
from qgis.PyQt.QtCore import Qt, QTimer, QSize
from qgis.PyQt.QtGui import QIcon, QColor
from qgis.utils import iface
from qgis.gui import QgsDockWidget
from qgis.core import *
import csv, os, re, json

from .map_search import karten_suche
from .search_gemarkung import such_die_gemarkung

class FlurstuckDockWidget(QgsDockWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("Flurstückssuche")
        #self.setFeatures(QgsDockWidget.DockWidgetFeature.AllDockWidgetFeatures)
        
        #self.setFeatures(QDockWidget.DockWidgetFeature.AllDockWidgetFeatures)
        self.setFeatures(
            QDockWidget.DockWidgetFeature.DockWidgetClosable |
            QDockWidget.DockWidgetFeature.DockWidgetMovable |
            QDockWidget.DockWidgetFeature.DockWidgetFloatable
)
        
        
        self.scroll = QScrollArea(widgetResizable=True, horizontalScrollBarPolicy=Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
        self.setWidget(self.scroll)
        
        main_widget = QWidget()
        main_layout = QVBoxLayout(main_widget)
        self.tabs = QTabWidget()
        
        self.tabs.addTab(self._create_search_tab(), "Suche")
        #self.tabs.addTab(self._create_history_tab(), "Historie")
        #self.tabs.addTab(self._create_info_tab(), "Info")
        
        self.tabs.setStyleSheet("""
            QTabBar::tab {
                background: white; 
                color: blue;
                border: 2px solid black; 
                padding: 5px 10px;
                font-weight: bold;
                font-size: 12px;
                width: 100px; 
            } 
        
            QTabBar::tab:selected { 
                background: yellow;
                color: blue; 
                margin-bottom: -1px; 
            }
        """)
        
        main_layout.addWidget(self.tabs)
        self.scroll.setWidget(main_widget)
        
        self.load_config() 

    def load_config(self):
        config_path = os.path.join(os.path.dirname(__file__), 'bundeslaender_config.json')
        with open(config_path, 'r', encoding='utf-8') as f:
            self.laender_config = json.load(f)
        
        self.code_to_config = {}
        for land, config in self.laender_config.items():
            try:
                code = config['code']
                self.code_to_config[code] = config
                print(f"✅ {land}: {code}")
            except KeyError as e:
                print(f"❌ FEHLER bei '{land}':")
                print(f"   Keys vorhanden: {list(config.keys())}")
                print(f"   Inhalt: {config}")
    
    def _create_search_tab(self):
        tab = QWidget()
        layout = QVBoxLayout(tab)
        
        # Land Dropdown
        layout.addWidget(self._create_land_dropdown())
        
         # Radio Group
        layout.addWidget(self._create_radio_group())
        
        # GEMARK EINGABE (initial VERSTECKT, nur Option 2)
        self.gemark_label = QLabel('Gemarkung:')
        self.gemark_eingabe = QLineEdit() ###minimumWidth=400
        
        self.gemark_label.setVisible(False)
        self.gemark_eingabe.setVisible(False)
        layout.addWidget(self.gemark_label)
        layout.addWidget(self.gemark_eingabe)
        
        self.gemark_eingabe.returnPressed.connect(self.search_mark)
        
        ##gemarkung suchen 
        self.btn_suche12 = QPushButton('Suche Gemarkung')
        self.btn_suche12.setStyleSheet("background-color: royalblue;font-weight: bold;")
        self.btn_suche12.clicked.connect(self.search_mark)  
        self.btn_suche12.setVisible(False)  
        layout.addWidget(self.btn_suche12)
        
        # Eingabefelder (initial versteckt)
        self.input_groups = {
            1: self._create_fields_group(['Gemarkungsnummer:', 'Flur:', 'Zähler:', 'Nenner:']),
            2: self._create_fields_group(['Flur:', 'Zähler:', 'Nenner:']),
            3: self._create_fields_group(['Flurstückskennzeichen (20-stellig):'])
        }
        
        
        for group in self.input_groups.values():
            layout.addWidget(group)
        
        ####folgenummer
        self.folge_label = QLabel('Flurstücksfolgenummer:')
        self.folge_eingabe = QLineEdit() #minimumWidth=400
        self.folge_label.setVisible(False)
        self.folge_eingabe.setVisible(False)
        layout.addWidget(self.folge_label)
        layout.addWidget(self.folge_eingabe)
        self.dropdown_land.currentTextChanged.connect(self.update_visibility)
        self.radio1.toggled.connect(self.update_visibility)
        self.radio2.toggled.connect(self.update_visibility)
        
        self.dropdown_land.currentTextChanged.connect(self.hide_field)
        self.radio1.toggled.connect(self.hide_field)
        self.radio2.toggled.connect(self.hide_field)
        
        # Buttons
        btn_layout = QVBoxLayout()

        # Grüner "Suchen" Button 
        suchen_btn = QPushButton('Suchen')
        suchen_btn.clicked.connect(self.searching)
        suchen_btn.setAutoFillBackground(True) 
        suchen_btn.setStyleSheet("""
            QPushButton {
                background-color: green; 
                color: white; 
                border: 1px solid gray;
                padding: 8px 16px;
                font-weight: bold;
            }
            QPushButton:pressed {
                background-color: red;  
                border-style: inset ;
            }
        """)
        btn_layout.addWidget(suchen_btn)

        # Blauer "Inverse Suche" Button
        inverse_btn = QPushButton('📍🗺️ Inverse Suche (Klick in Karte)')
        inverse_btn.clicked.connect(karten_suche)
        inverse_btn.setStyleSheet("""
            QPushButton { 
                background-color: orange; 
                color: black; 
                border: 1px solid gray;
                padding: 8px 16px;
                font-weight: bold;
            }
            QPushButton:pressed {
                background-color: red ;  
                border-style: inset;
            }
        """)
        btn_layout.addWidget(inverse_btn)
        layout.addLayout(btn_layout)
        layout.addStretch()
        ####!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        self.on_land_changed(self.dropdown_land.currentText())
        return tab
    
    def _create_land_dropdown(self):
        widget = QWidget()
        layout = QHBoxLayout(widget)
        layout.addWidget(QLabel('Land:'))
        self.dropdown_land = QComboBox()
        laender = ['Rheinland-Pfalz (07)', 'Sachsen (14)', 'Berlin (11)', 'Saarland (10)', 'Hamburg (02)', 
                  'Sachsen-Anhalt (15)', 'Brandenburg (12)', 'Hessen (06)', 'Mecklenburg-Vorpommern (13)', 
                  'Nordrhein-Westfalen (05)', 'Niedersachsen (03)', 'Baden-Württemberg (08)', 'Bremen (04)', 'Thüringen (16)', 
                  'Schleswig-Holstein (01)']
        self.dropdown_land.addItems(sorted(laender))
        
        self.dropdown_land.currentTextChanged.connect(self.on_land_changed)
        #self.on_land_changed(self.dropdown_land.currentText())
        #QTimer.singleShot(500, lambda: self.on_land_changed(self.dropdown_land.currentText()))
        layout.addWidget(self.dropdown_land)
        layout.addStretch()
        return widget
    
    
    def _create_radio_group(self):
        group = QGroupBox('')
        layout = QVBoxLayout(group)
        
        self.radio1 = QRadioButton('Gemarkungsnummer / Flur / Flurstück')
        self.radio2 = QRadioButton('Gemarkungsname / Flur / Flurstück')
        self.radio3 = QRadioButton('Flurstückskennzeichen')
        
        layout.addWidget(self.radio1)
        layout.addWidget(self.radio2)
        layout.addWidget(self.radio3)
        
        self.radio_group = QButtonGroup(self)
        self.radio_group.addButton(self.radio1, 1)
        self.radio_group.addButton(self.radio2, 2)
        self.radio_group.addButton(self.radio3, 3)
        self.radio1.setChecked(True)  # ← Radio1 als Standard
        self.on_radio_toggled(self.radio1)  # Trigger initial
        self.radio_group.buttonClicked.connect(self.on_radio_toggled)
        
        return group
    
    def _create_fields_group(self, labels):
        group = QWidget()
        layout = QVBoxLayout(group)
        widgets = []
        fields = {}
        
        for text in labels:
            label = QLabel(text)
            lineedit = QLineEdit()
            layout.addWidget(label)
            layout.addWidget(lineedit)
            widgets.extend([label, lineedit])
        
            field_name = text
            fields[field_name] = {'label': label, 'lineedit': lineedit}
        
        group.widgets = widgets
        group.fields = fields 
        group.setVisible(False)  
        return group
    
    def update_visibility(self):
        # Bedingung folgenummer
        zeige_folge = (
            (self.dropdown_land.currentText() == "Sachsen (14)" or self.dropdown_land.currentText() == "Baden-Württemberg (08)") and 
            (self.radio1.isChecked() or self.radio2.isChecked())
        )
        self.folge_label.setVisible(zeige_folge)
        self.folge_eingabe.setVisible(zeige_folge)
        
    def hide_field(self):
        """Versteckt flur"""
        zeige_flur = not(
            (self.dropdown_land.currentText() == "Sachsen (14)" or self.dropdown_land.currentText() == "Hamburg (02)") and 
            (self.radio1.isChecked() or self.radio2.isChecked())
        )
        self.input_groups[1].fields.get('Flur:')['label'].setVisible(zeige_flur)
        self.input_groups[1].fields.get('Flur:')['lineedit'].setVisible(zeige_flur)
        self.input_groups[2].fields.get('Flur:')['label'].setVisible(zeige_flur)
        self.input_groups[2].fields.get('Flur:')['lineedit'].setVisible(zeige_flur)
    
    def search_mark(self):
        gmk_num = self.extract_gemark_number_regex() 
        
        mark_neu = str(gmk_num)
        #print("mark_neu: " + mark_neu)
        markungstext = self.gemark_eingabe.text()
        #print(markungstext)
        such_die_gemarkung(mark_neu, selected_state, markungstext)
        
    def extract_gemark_number_regex(self):
        text = self.gemark_eingabe.text()
        #gemark_num = re.sub(r'\D', '', text)  # Alles Nicht-Ziffer löschen
        gemark_num = re.findall(r'\((\d+)\)', text)[0] ##liest das zwischen () aus 
        return gemark_num


    def on_land_changed(self, land_text):
        """Dynamisch CSV je nach Dropdown-Auswahl laden"""
        print(f"DEBUG: land_text = {land_text}, type = {type(land_text)}")
        
        global selected_state
        selected_state = land_text
        
        clean_text = re.sub(r'[^a-zA-ZäöüÄÖÜ\s]', '', land_text)
        land_str = clean_text.lower().replace(' ', '').strip()
        csv_filename = f"{land_str}.csv"
        print(csv_filename)
        unterordner = "gemarkungen"
        csv_path = os.path.join(os.path.dirname(__file__), unterordner, csv_filename)
        self.set_completer_from_csv(csv_path)
        
        ###eingaben clearen bei landeswechsel
        for line_edit in self.findChildren(QLineEdit):
            line_edit.clear()

    def set_completer_from_csv(self, csv_path):
        """Lädt die Daten aus der CSV-Datei und setzt den Completer für das LineEdit."""
        try:
            if hasattr(self, 'completer') and self.completer:
                self.completer.deleteLater()
            # Lade die CSV-Datei und extrahiere die Daten
            with open(csv_path, 'r', encoding='utf-8') as file:
                reader = csv.reader(file)
                gemarkungen = [row[0] for row in reader if row]  # Angenommen, die Gemarkung ist in der ersten Spalte

            gemarkungen = sorted(gemarkungen)  

            # Setze den Completer für das LineEdit
            self.completer = QCompleter(gemarkungen)
            self.completer.setCaseSensitivity(Qt.CaseSensitivity.CaseInsensitive)  # Groß-/Kleinschreibung ignorieren
            self.completer.setFilterMode(Qt.MatchFlag.MatchContains)  # Teilwortsuche aktivieren
            self.gemark_eingabe.setCompleter(self.completer)
            
        
        except Exception as e:
            print(f"Fehler beim Laden der CSV-Datei: {e}")
    
    
    def on_radio_toggled(self, button):
        if not hasattr(self, 'input_groups') or not self.input_groups:
            return
        
        # Gemark nur bei Option 2
        mode = self.radio_group.id(button)
        gemark_visible = mode == 2
        self.gemark_label.setVisible(gemark_visible)
        self.gemark_eingabe.setVisible(gemark_visible)
        
        self.btn_suche12.setVisible(mode == 2)
        
        # Alle Gruppen verstecken
        for group in self.input_groups.values():
            group.setVisible(False)
        
        # Aktive Gruppe zeigen
        if mode in self.input_groups:
            self.input_groups[mode].setVisible(True)
        
        self.updateGeometry()

    
    
    def get_inputs(self):
        mode = self.radio_group.checkedId()
        global flurstueck_kennzeichen
        
        if mode == 1:  # Radio1
            group = self.input_groups[1].widgets
            return (group[1].text(), group[3].text(), group[5].text(), group[7].text())
        
        elif mode == 2:  # Radio2
            if self.gemark_eingabe.text() == '':
                return 
            gemarkung = self.gemark_eingabe.text().split('(')[1].split(')')[0]
            print(gemarkung)
            group = self.input_groups[2].widgets
            return (gemarkung, group[1].text(), group[3].text(), group[5].text())
        
        elif mode == 3:  # Radio3
            group = self.input_groups[3].widgets
            return (group[1].text(),)  # Erstes LineEdit
        
        return None

    
    def process_inputs(self, gemarkung, flur, zaehler, nenner):
        reverse_zaehler = zaehler.zfill(5) if zaehler else "_____"
        reverse_nenner = nenner.zfill(4) if nenner else "____"
        reverse_flur = flur.zfill(3) if flur else "___"
        
        if len(gemarkung) == 6:
            gemarkung = gemarkung[2:]
        if len(gemarkung) == 9:
            gemarkung = gemarkung[2:6]
        
        ####neu, statt if, elif --- selected_state > laendercode
        laendercode = re.findall(r'\((\d+)\)', selected_state)[0]
        
        if selected_state == 'Sachsen (14)' or selected_state == 'Baden-Württemberg (08)': ######folgenummer sonderfall
            #flurstueck_kennzeichen = "{0}{1}{2}{3}{4}*".format(laendercode, gemarkung.zfill(4), reverse_flur, reverse_zaehler, reverse_nenner)
            flurstueck_kennzeichen = "{0}{1}{2}{3}{4}__".format(laendercode, gemarkung.zfill(4), reverse_flur, reverse_zaehler, reverse_nenner)
            folge_text = self.folge_eingabe.text()
            if folge_text:
                flurstueck_kennzeichen = flurstueck_kennzeichen[:-2] + folge_text.zfill(2)
            else:
                flurstueck_kennzeichen = flurstueck_kennzeichen[:-2] + "00"
        
        ####berlin ###
        elif selected_state == 'Berlin (11)':
            flurstueck_kennzeichen = "{0}{1}{2}{3}{4}".format(laendercode, gemarkung.zfill(4), reverse_flur, reverse_zaehler, reverse_nenner)
        
        else:
            flurstueck_kennzeichen = "{0}{1}{2}{3}{4}__".format(laendercode, gemarkung.zfill(4), reverse_flur, reverse_zaehler, reverse_nenner)
        
        return flurstueck_kennzeichen
    
    
    def searching(self):
        inputs = self.get_inputs()
        
        if inputs is None:
            iface.messageBar().pushMessage("Ooops", "Leere Eingabe", level=Qgis.MessageLevel.Critical, duration=10)
            return

        if self.radio1.isChecked() or self.radio2.isChecked():
            flurstueck_kennzeichen = self.process_inputs(*inputs)
        elif self.radio3.isChecked():
            flurstueck_kennzeichen = inputs[0]
            
        print(f"{flurstueck_kennzeichen}")
        
        if flurstueck_kennzeichen == '':
            iface.messageBar().pushMessage("Ooops", "Leere Eingabe", level=Qgis.MessageLevel.Critical, duration=10)
            return
        
        laendercode = flurstueck_kennzeichen[:2]
        config = self.code_to_config.get(laendercode)
       
        url = config['url'].format(flurstueck_kennzeichen=flurstueck_kennzeichen)
        
        layer = QgsVectorLayer(url, flurstueck_kennzeichen, 'ogr')
        layer.setCrs(QgsCoordinateReferenceSystem(config['crs']))
       
        if not layer.geometryType() == QgsWkbTypes.GeometryType.PolygonGeometry or layer.featureCount() == 0:
            iface.messageBar().pushMessage("Ooops", "Flurstück nicht gefunden", level=Qgis.MessageLevel.Critical, duration=10)
        else:
            
            # In Memory-Layer konvertieren
            geom_type = ["Point", "LineString", "Polygon"][layer.geometryType()]
            crs = layer.crs().authid()
            
            memory_layer = QgsVectorLayer(f"{geom_type}?crs={crs}", flurstueck_kennzeichen, "memory")
            
            ###crs konkret setzen und aus config holen 
            memory_layer.setCrs(QgsCoordinateReferenceSystem(config['crs']))
            
            memory_provider = memory_layer.dataProvider()
            # Felder kopieren
            memory_provider.addAttributes(layer.fields())
            memory_layer.updateFields()
            
            # Features kopieren
            memory_provider.addFeatures(list(layer.getFeatures()))
            memory_layer.updateExtents()
            
            QgsProject.instance().addMapLayer(memory_layer)
            layer = memory_layer
            
            # CRS-Transformation: Layer → Canvas
            feats = list(layer.getFeatures())
            feat = feats[0]
            layer_crs = layer.crs()
            canvas_crs = iface.mapCanvas().mapSettings().destinationCrs()
            bbox_layer = feat.geometry().boundingBox()

            if layer_crs != canvas_crs:
                transform = QgsCoordinateTransform(layer_crs, canvas_crs, QgsProject.instance())
                bbox_canvas = transform.transformBoundingBox(bbox_layer)
            else:
                bbox_canvas = bbox_layer

            iface.mapCanvas().setExtent(bbox_canvas)
            iface.mapCanvas().refresh()
            
            symbol = QgsFillSymbol.createSimple({
                'color': '0,0,255,100',  # No fill (transparent)
                'outline_color': '0,0,255',  # Blue outline
                'outline_width': '0.5'  # Outline width
            })
            layer.renderer().setSymbol(symbol)
            layer.triggerRepaint()


class FlurstueckssucheDE:
    def __init__(self, iface):
        self.iface = iface
        self.dockwidget = None
        self.action = None

    def initGui(self):      
        icon_path = os.path.join(os.path.dirname(__file__), "icon.png")
        self.action = QAction(QIcon(icon_path), "Flurstückssuche DE", self.iface.mainWindow())
        
        # Dock nur einmal erstellen!
        if not hasattr(self, 'dockwidget') or self.dockwidget is None:
            self.dockwidget = FlurstuckDockWidget(iface.mainWindow())
            iface.addDockWidget(Qt.DockWidgetArea.RightDockWidgetArea, self.dockwidget)
        
        self.action.triggered.connect(self.toggle_dockwidget)
        self.iface.addToolBarIcon(self.action)


    def unload(self):
        self.iface.removeToolBarIcon(self.action)
        self.iface.removePluginMenu('&Flurstückssuche DE', self.action)
        
        if self.dockwidget is not None:
            # aus QGIS entfernen
            self.iface.removeDockWidget(self.dockwidget)
            # optional zerstören
            self.dockwidget.deleteLater()
            self.dockwidget = None
        
    def toggle_dockwidget(self):
        if self.dockwidget is None:
            self.dockwidget = FlurstuckDockWidget(iface.mainWindow())
            iface.addDockWidget(Qt.DockWidgetArea.RightDockWidgetArea, self.dockwidget)
            self.dockwidget.show()
        self.dockwidget.setVisible(not self.dockwidget.isVisible())