# -*- coding: utf-8 -*-

import os
import pandas as pd
import json
from qgis.PyQt import uic
from qgis.PyQt.QtWidgets import QDialog, QTableWidgetItem, QVBoxLayout, QHBoxLayout, QGridLayout, QLineEdit, QPushButton, QLabel, QHeaderView, QAbstractItemView, QComboBox
from qgis.PyQt.QtCore import pyqtSignal, Qt

# Load and normalize data at module level
try:
    json_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), "resources", "tiepoints.json")
    with open(json_path, "r") as f:
        raw_data = json.load(f)
    # Normalize key casing: "PROVINCE" → "Province"
    normalized_data = [{k.title(): v for k, v in row.items()} for row in raw_data]
    # Create DataFrame and clean data
    _TIEPOINT_DF = pd.DataFrame(normalized_data)
    
    # For entries with null Municipality, use the Province value as the Municipality
    _TIEPOINT_DF["Municipality"] = _TIEPOINT_DF.apply(
        lambda row: row["Province"] if pd.isna(row["Municipality"]) else row["Municipality"], 
        axis=1
    )
    
    # Remove rows with missing critical data
    _TIEPOINT_DF.dropna(subset=["Tie Point Name", "Province"], inplace=True)
    # Remove rows with empty strings in critical fields
    _TIEPOINT_DF = _TIEPOINT_DF[_TIEPOINT_DF["Tie Point Name"].astype(str).str.strip() != ""]
except Exception as e:
    print(f"Error loading tie points: {e}")
    _TIEPOINT_DF = pd.DataFrame()

# This loads your .ui file so that PyQt can populate your plugin with the elements from Qt Designer
FORM_CLASS, _ = uic.loadUiType(os.path.join(
    os.path.dirname(os.path.dirname(__file__)), 'forms', 'tie_point_selector_dialog_base.ui'))

# Modern Stylesheet for Tie Point Selector
MODERN_STYLESHEET = """
/* Main Dialog */
QDialog {
    background-color: #f1fcfb;
    color: #06292d;
    font-family: 'Segoe UI', Arial, sans-serif;
    font-size: 9pt;
}

/* Labels */
QLabel {
    color: #06292d;
    font-weight: bold;
}

/* Input Fields */
QLineEdit {
    background-color: #ffffff;
    border: 2px solid #16474b;
    border-radius: 6px;
    padding: 6px;
    color: #06292d;
    selection-background-color: #14575b;
    selection-color: #f1fcfb;
}

QLineEdit:focus {
    border: 2px solid #14575b;
    background-color: #f8ffff;
}

QLineEdit:hover {
    border: 2px solid #1a6b70;
}

/* ComboBox */
QComboBox {
    background-color: #ffffff;
    border: 2px solid #16474b;
    border-radius: 6px;
    padding: 4px 10px;
    color: #06292d;
    selection-background-color: #14575b;
    selection-color: #f1fcfb;
}

QComboBox:hover {
    border: 2px solid #1a6b70;
}

QComboBox:on { /* shift the text when the popup opens */
    padding-top: 3px;
    padding-left: 4px;
}

QComboBox::drop-down {
    subcontrol-origin: padding;
    subcontrol-position: top right;
    width: 24px;
    border-left-width: 1px;
    border-left-color: #16474b;
    border-left-style: solid;
    border-top-right-radius: 6px;
    border-bottom-right-radius: 6px;
    background-color: #e0f5f3; /* Light teal accent for the button */
}

QComboBox::drop-down:hover {
    background-color: #d0f0ee;
}

QComboBox::down-arrow {
    image: none; /* No image, we can try a simple shape if supported or default */
    width: 0; 
    height: 0; 
    border-left: 5px solid transparent;
    border-right: 5px solid transparent;
    border-top: 5px solid #14575b;
    margin: 0px 6px 0px 0px;
}

/* Popup List */
QComboBox QAbstractItemView {
    border: 2px solid #16474b;
    border-radius: 4px;
    background-color: #ffffff;
    color: #06292d;
    selection-background-color: #1a6b70;
    selection-color: #ffffff;
    outline: none;
}

/* Table Widget */
QTableWidget {
    background-color: #ffffff;
    alternate-background-color: #e0f5f3;
    gridline-color: #d1d9d9;
    border: 2px solid #16474b;
    border-radius: 8px;
    selection-background-color: #1a6b70;
    selection-color: #ffffff;
    color: #06292d;
}

QTableWidget::item {
    padding: 4px;
    border-bottom: 1px solid #f0f0f0;
}

QTableWidget::item:selected {
    background-color: #1a6b70;
    color: #ffffff;
}

QHeaderView::section {
    background-color: #14575b;
    color: #f1fcfb;
    padding: 8px;
    border: none;
    font-weight: bold;
    font-size: 9pt;
}

QHeaderView::section:horizontal {
    border-right: 1px solid #1a6b70;
}

/* Scroll Area & Bars */
QScrollBar:vertical {
    background-color: #e0f5f3;
    width: 12px;
    border-radius: 6px;
    margin: 2px;
}

QScrollBar::handle:vertical {
    background-color: #14575b;
    border-radius: 5px;
    min-height: 30px;
}

QScrollBar::handle:vertical:hover {
    background-color: #1a6b70;
}

QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical {
    height: 0px;
}

/* Buttons */
QPushButton {
    background-color: #14575b;
    border: none;
    border-radius: 6px;
    padding: 8px 16px;
    color: #f1fcfb;
    font-weight: bold;
    font-size: 9pt;
}

QPushButton:hover {
    background-color: #1a6b70;
}

QPushButton:pressed {
    background-color: #0f4548;
}

QPushButton:disabled {
    background-color: #a8d4d6;
    color: #5a8a8d;
}
"""


class TiePointSelectorDialog(QDialog, FORM_CLASS):
    # Signal to emit when a tie point is selected
    tie_point_selected = pyqtSignal(str, str)

    def __init__(self, parent=None):
        """Constructor."""
        super(TiePointSelectorDialog, self).__init__(parent)
        self.setupUi(self)
        
        # Apply modern styling
        self.setStyleSheet(MODERN_STYLESHEET)
        
        # Setup custom UI layout and placeholders
        self.setup_custom_ui()
        
        # Additional table customization
        self.tiePointTable.setAlternatingRowColors(True)
        self.tiePointTable.setShowGrid(False)  # Cleaner look without full grid
        self.tiePointTable.verticalHeader().setVisible(False) # Hide row numbers
        
        self.setup_connections()
        self.setup_table_headers()
        self.setup_province_combo()
        # Initialize empty table
        self.tiePointTable.setRowCount(0)
        self.tiePointTable.setColumnCount(6)
        self.tiePointTable.setHorizontalHeaderLabels([
            "Tie Point Name", "Description", "Province", "Municipality", "Northing", "Easting"
        ])
        # Update status label
        self.statusLabel.setText("Status: No data loaded. Use search to find tie points.")

    def setup_connections(self):
        # Remove textChanged connections and add search button connection
        self.searchButton.clicked.connect(self.apply_filters)
        self.tiePointTable.itemDoubleClicked.connect(self.accept_selection)
        self.selectButton.clicked.connect(self.accept_selection)
        self.cancelButton.clicked.connect(self.reject)

    def setup_province_combo(self):
        """Set up the province ComboBox with unique provinces"""
        provinces = sorted(_TIEPOINT_DF["Province"].dropna().unique())
        self.provinceComboBox.addItem("")  # Blank = no filter
        self.provinceComboBox.addItems(provinces)

    def setup_table_headers(self):
        """Set up table headers and tooltips"""
        headers = ["Tie Point Name", "Description", "Province", "Municipality", "Northing", "Easting"]
        self.tiePointTable.setColumnCount(len(headers))
        self.tiePointTable.setHorizontalHeaderLabels(headers)

        # Set header resize mode and enable sorting
        header = self.tiePointTable.horizontalHeader()
        header.setSectionResizeMode(QHeaderView.ResizeToContents)
        self.tiePointTable.setSortingEnabled(True)

        # Set tooltips for headers
        tooltips = [
            "Name of the tie point (case and space insensitive)",
            "Description of the tie point (partial match)",
            "Province where the tie point is located (select from list)",
            "Municipality where the tie point is located (partial match)",
            "Northing coordinate of the tie point",
            "Easting coordinate of the tie point"
        ]
        for i, tooltip in enumerate(tooltips):
            self.tiePointTable.horizontalHeaderItem(i).setToolTip(tooltip)

        # Allow single row selection
        self.tiePointTable.setSelectionMode(QAbstractItemView.SingleSelection)
        self.tiePointTable.setSelectionBehavior(QAbstractItemView.SelectRows)

    def populate_table(self, df):
        """Populate table with data from DataFrame"""
        # Clear existing contents and reset row count
        self.tiePointTable.clearContents()
        self.tiePointTable.setRowCount(0)

        # Set new row count and ensure column count
        self.tiePointTable.setRowCount(len(df))
        self.tiePointTable.setColumnCount(6)
        self.tiePointTable.setHorizontalHeaderLabels([
            "Tie Point Name", "Description", "Province", "Municipality", "Northing", "Easting"
        ])

        # Populate table with data
        for row_idx, (_, row) in enumerate(df.iterrows()):
            self.tiePointTable.setItem(row_idx, 0, QTableWidgetItem(str(row["Tie Point Name"])))
            self.tiePointTable.setItem(row_idx, 1, QTableWidgetItem(str(row["Description"])))
            self.tiePointTable.setItem(row_idx, 2, QTableWidgetItem(str(row["Province"])))
            self.tiePointTable.setItem(row_idx, 3, QTableWidgetItem(str(row["Municipality"])))
            self.tiePointTable.setItem(row_idx, 4, QTableWidgetItem(str(row["Northing"])))
            self.tiePointTable.setItem(row_idx, 5, QTableWidgetItem(str(row["Easting"])))

        # Resize columns to content after populating
        self.tiePointTable.resizeColumnsToContents()

        # Update status label
        self.statusLabel.setText(f"Status: {len(df)} rows shown")

    def apply_filters(self):
        """Apply filters based on input fields"""
        name_filter = self.nameInput.text().replace(" ", "").lower()
        description_filter = self.descriptionInput.text().strip().lower()
        municipality_filter = self.municipalityInput.text().strip().lower()
        province_filter = self.provinceComboBox.currentText().strip()

        df = _TIEPOINT_DF.copy()

        # Normalize name column for flexible matching
        df["__name"] = df["Tie Point Name"].astype(str).str.replace(" ", "").str.lower()

        # Apply filters
        if name_filter:
            df = df[df["__name"].str.contains(name_filter)]

        if description_filter:
            df = df[df["Description"].astype(str).str.lower().str.contains(description_filter)]

        if municipality_filter:
            df = df[df["Municipality"].astype(str).str.lower().str.contains(municipality_filter)]

        if province_filter:
            df = df[df["Province"] == province_filter]

        # Drop temporary columns
        df = df.drop(columns=["__name"])

        self.populate_table(df)

    def accept_selection(self):
        """Handle selection of a tie point"""
        current_row = self.tiePointTable.currentRow()
        if current_row >= 0:
            self.selected_row = {
                'name': self.tiePointTable.item(current_row, 0).text(),
                'description': self.tiePointTable.item(current_row, 1).text(),
                'province': self.tiePointTable.item(current_row, 2).text(),
                'municipality': self.tiePointTable.item(current_row, 3).text(),
                'northing': float(self.tiePointTable.item(current_row, 4).text()),
                'easting': float(self.tiePointTable.item(current_row, 5).text())
            }
            self.accept()

    def setup_custom_ui(self):
        """Rearrange UI elements and add placeholders programmatically."""
        # 1. Add Placeholders
        self.nameInput.setPlaceholderText("e.g., BLLM 1, BLBM 10")
        self.municipalityInput.setPlaceholderText("e.g., Tagaytay City, Malolos City")
        self.descriptionInput.setPlaceholderText("e.g., Cadastral Survey")
        self.provinceComboBox.setToolTip("Select Province")
        
        # 2. Rearrange Widgets using a Grid Layout
        # Create a new grid layout
        grid = QGridLayout()
        grid.setContentsMargins(0, 0, 0, 10) # Add some bottom spacing
        grid.setSpacing(10)

        # Row 0: Top Left (Province) & Top Right (Municipality + Search)
        # Province
        grid.addWidget(self.label_3, 0, 0) # Province Label
        grid.addWidget(self.provinceComboBox, 0, 1)
        
        # Municipality
        grid.addWidget(self.label_4, 0, 2) # Municipality Label
        grid.addWidget(self.municipalityInput, 0, 3)
        
        # Search Button (Keep it accessible in the top row)
        grid.addWidget(self.searchButton, 0, 4)
        
        # Row 1: Lower Left (Name) & Lower Right (Description)
        # Name
        grid.addWidget(self.label, 1, 0) # Name Label
        grid.addWidget(self.nameInput, 1, 1)
        
        # Description
        grid.addWidget(self.label_2, 1, 2) # Description Label
        grid.addWidget(self.descriptionInput, 1, 3, 1, 2) # Span 2 columns to align with search button edge

        # Remove the old horizontal layouts from the main vertical layout
        # Note: The widgets are automatically reparented to the grid when added, 
        # so the old layouts are now empty. We just need to remove them.
        
        # The .ui file has 'verticalLayout' containing:
        # 0: horizontalLayout (Name, Desc)
        # 1: horizontalLayout_2 (Prov, Muni, Search)
        # 2: tiePointTable
        
        # Remove the first two items (the old layouts)
        item0 = self.verticalLayout.takeAt(0) # horizontalLayout
        item1 = self.verticalLayout.takeAt(0) # Now horizontalLayout_2 is at 0
        
        # Delete the old layout objects to clean up
        if item0.layout(): 
            item0.layout().deleteLater()
        if item1.layout():
            item1.layout().deleteLater()
            
        # Insert the new grid layout at the top
        self.verticalLayout.insertLayout(0, grid)

    def get_selected_row(self):
        """Return the selected tie point data"""
        return getattr(self, 'selected_row', None) 