import os
from qgis.PyQt.QtWidgets import (
    QDialog, QVBoxLayout, QHBoxLayout, QTabWidget, QWidget,
    QLabel, QLineEdit, QPushButton,
    QFileDialog, QMessageBox, QTableWidget, QTableWidgetItem,
    QHeaderView, QCheckBox, QColorDialog, QGroupBox, QTextEdit,
    QApplication, QComboBox
)
from qgis.PyQt.QtCore import Qt
from qgis.PyQt.QtGui import QColor

from .kml_i18n import get_help
from .kml_to_shp import KmlToShpConverter
from .merge_tab import MergeTabWidget
from ..shared.qt_compat import QtCompat, MsgButton


class LvtKmlViewDialog(QDialog):
    def __init__(self, iface, parent=None):
        super().__init__(parent)
        self.iface = iface
        self.plugin_dir = os.path.dirname(__file__)
        self.lang = 'vi'

        screen = QApplication.primaryScreen()
        if screen:
            sh = int(screen.availableGeometry().height() * 0.95)
        else:
            sh = 750
        self.resize(1100, sh)
        self._setup_ui()
        self._refresh_ui_text()
        self.merge_widget.ensure_initialized()

        self.btn_close.clicked.connect(self.close)

    def _setup_ui(self):
        main_layout = QVBoxLayout(self)

        top_ly = QHBoxLayout()
        self.btn_lang = QPushButton()
        self.btn_lang.setFixedWidth(100)
        self.btn_lang.clicked.connect(self._toggle_language)
        top_ly.addWidget(self.btn_lang)
        top_ly.addStretch()
        main_layout.addLayout(top_ly)

        self.tabs = QTabWidget()
        main_layout.addWidget(self.tabs)

        # Tab 0: SHP → KML (MergeTabWidget — supports single & multi-layer)
        self.merge_widget = MergeTabWidget(lang=self.lang)
        self.tabs.addTab(self.merge_widget, "SHP → KML")

        # Tab 1: KML → SHP
        self.tab_kml2shp = QWidget()
        self._setup_tab_kml2shp()
        self.tabs.addTab(self.tab_kml2shp, "KML → SHP")

        # Tab 2: Hướng dẫn
        self.tab_guide = QWidget()
        self._setup_tab_guide()
        self.tabs.addTab(self.tab_guide, "")

        # Hide preview panel when on KML→SHP or other tabs
        self.tabs.currentChanged.connect(self._on_tab_changed)

        btn_layout = QHBoxLayout()
        self.btn_close = QPushButton()
        btn_layout.addStretch()
        btn_layout.addWidget(self.btn_close)
        main_layout.addLayout(btn_layout)

    def _on_tab_changed(self, index):
        """Refresh merge preview when switching to SHP→KML tab."""
        if index == 0:
            self.merge_widget.refresh_geom_tabs()

    def _setup_tab_guide(self):
        ly = QVBoxLayout(self.tab_guide)
        self.guide = QTextEdit()
        self.guide.setReadOnly(True)
        ly.addWidget(self.guide)

    def _setup_tab_kml2shp(self):
        ly = QVBoxLayout(self.tab_kml2shp)

        # --- Layer picker: select from QGIS loaded layers ---
        row_layer = QHBoxLayout()
        self.lbl_layer_pick = QLabel()
        row_layer.addWidget(self.lbl_layer_pick)
        self.cmb_layer_pick = QComboBox()
        self.cmb_layer_pick.setMinimumWidth(200)
        self.cmb_layer_pick.currentIndexChanged.connect(self._on_layer_picked)
        row_layer.addWidget(self.cmb_layer_pick, 1)
        self.btn_refresh_layers = QPushButton("🔄")
        self.btn_refresh_layers.setFixedWidth(32)
        self.btn_refresh_layers.setToolTip("Làm mới danh sách layer / Refresh layers")
        self.btn_refresh_layers.clicked.connect(self._refresh_layer_picker)
        row_layer.addWidget(self.btn_refresh_layers)
        ly.addLayout(row_layer)

        # --- Or browse from file ---
        self.lbl_kml_src = QLabel()
        ly.addWidget(self.lbl_kml_src)

        row_kml = QHBoxLayout()
        self.txt_kml_in = QLineEdit()
        self.btn_browse_kml = QPushButton("...")
        self.btn_browse_kml.setFixedWidth(40)
        self.btn_browse_kml.clicked.connect(self._browse_kml)
        row_kml.addWidget(self.txt_kml_in)
        row_kml.addWidget(self.btn_browse_kml)
        ly.addLayout(row_kml)

        self.lbl_crs = QLabel()
        ly.addWidget(self.lbl_crs)
        self.txt_crs = QLineEdit("EPSG:4326")
        ly.addWidget(self.txt_crs)

        # Format selector: SHP or GPKG
        row_fmt = QHBoxLayout()
        self.lbl_out_fmt = QLabel()
        row_fmt.addWidget(self.lbl_out_fmt)
        self.cmb_out_fmt = QComboBox()
        self.cmb_out_fmt.addItem("SHP (Shapefile)", "shp")
        self.cmb_out_fmt.addItem("GPKG (GeoPackage — tên trường đầy đủ)", "gpkg")
        self.cmb_out_fmt.currentIndexChanged.connect(self._on_format_changed)
        row_fmt.addWidget(self.cmb_out_fmt)
        ly.addLayout(row_fmt)

        # --- KML info & field selection ---
        self.gp_kml_fields = QGroupBox("Fields")
        kf_ly = QVBoxLayout(self.gp_kml_fields)

        self.lbl_kml_info = QLabel("")
        self.lbl_kml_info.setStyleSheet("color: #555; font-size: 12px;")
        self.lbl_kml_info.setWordWrap(True)
        kf_ly.addWidget(self.lbl_kml_info)

        kf_btn_ly = QHBoxLayout()
        self.btn_kml_scan = QPushButton("🔍 Scan")
        self.btn_kml_scan.setFixedWidth(100)
        self.btn_kml_scan.clicked.connect(self._scan_kml_fields)
        kf_btn_ly.addWidget(self.btn_kml_scan)
        self.btn_kml_check_all = QPushButton("✅ All")
        self.btn_kml_check_all.setFixedWidth(80)
        self.btn_kml_check_all.clicked.connect(self._kml_check_all)
        kf_btn_ly.addWidget(self.btn_kml_check_all)
        self.btn_kml_uncheck_all = QPushButton("❎ None")
        self.btn_kml_uncheck_all.setFixedWidth(80)
        self.btn_kml_uncheck_all.clicked.connect(self._kml_uncheck_all)
        kf_btn_ly.addWidget(self.btn_kml_uncheck_all)
        kf_btn_ly.addStretch()
        kf_ly.addLayout(kf_btn_ly)

        self.tbl_kml_fields = QTableWidget(0, 3)
        self.tbl_kml_fields.setHorizontalHeaderLabels(["√", "Field", "Sample"])
        self.tbl_kml_fields.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeMode.Stretch)
        self.tbl_kml_fields.setMaximumHeight(200)
        kf_ly.addWidget(self.tbl_kml_fields)
        ly.addWidget(self.gp_kml_fields)

        self.btn_extract = QPushButton()
        self.btn_extract.clicked.connect(self._convert_kml)
        ly.addWidget(self.btn_extract)
        ly.addStretch()

    def _refresh_ui_text(self):
        self.setWindowTitle("LVT4U KML view")
        self.btn_lang.setText(
            "🌐 " + ("English" if self.lang == 'vi' else "Tiếng Việt"))
        is_vi = self.lang == 'vi'

        self.btn_close.setText("Đóng" if is_vi else "Close")

        self.lbl_kml_src.setText(
            "📂 Hoặc dẫn file:" if is_vi else "📂 Or browse file:")
        self.lbl_layer_pick.setText(
            "📋 Layer QGIS:" if is_vi else "📋 QGIS Layer:")
        self.btn_refresh_layers.setToolTip(
            "Làm mới danh sách" if is_vi else "Refresh list")
        self._refresh_layer_picker()
        self.lbl_crs.setText("Hệ tọa độ:" if is_vi else "Target CRS:")
        self.lbl_out_fmt.setText("Định dạng xuất:" if is_vi else "Output Format:")
        self.cmb_out_fmt.setItemText(
            1, "GPKG (GeoPackage — tên trường đầy đủ)" if is_vi
            else "GPKG (GeoPackage — full field names)")
        self._update_extract_btn_text()
        self.gp_kml_fields.setTitle(
            "Trường dữ liệu xuất" if is_vi else "Export Fields")
        self.btn_kml_scan.setText("🔍 Quét" if is_vi else "🔍 Scan")
        self.btn_kml_check_all.setText("✅ Tất cả" if is_vi else "✅ All")
        self.btn_kml_uncheck_all.setText("❎ Bỏ chọn" if is_vi else "❎ None")
        self.tbl_kml_fields.setHorizontalHeaderLabels(
            ["√", "Trường" if is_vi else "Field", "Mẫu" if is_vi else "Sample"])

        self.tabs.setTabText(0, "SHP → KML")
        self.merge_widget.update_labels(self.lang)
        self.tabs.setTabText(1, "KML → SHP / GPKG")
        self.tabs.setTabText(2, "Hướng dẫn" if is_vi else "Guide")

        self.guide.setHtml(get_help(self.lang))

    def _load_current_layers(self):
        """Refresh layer list — delegates to merge_widget."""
        self.merge_widget.refresh_geom_tabs()

    def _toggle_language(self):
        self.lang = 'en' if self.lang == 'vi' else 'vi'
        self._refresh_ui_text()

    def _pick_color(self, btn):
        c = QColorDialog.getColor(QColor(btn.text()))
        if c.isValid():
            btn.setText(c.name())
            btn.setStyleSheet("background-color: {}".format(c.name()))

    # ── Layer picker ────────────────────────────────────────

    def _refresh_layer_picker(self):
        """Populate the layer picker combobox with loaded KML/KMZ layers."""
        self.cmb_layer_pick.blockSignals(True)
        self.cmb_layer_pick.clear()
        is_vi = self.lang == 'vi'
        self.cmb_layer_pick.addItem(
            "— Chọn layer từ QGIS —" if is_vi else "— Pick loaded layer —",
            None)

        from qgis.core import QgsProject
        for layer in QgsProject.instance().mapLayers().values():
            src = layer.source()
            # Include KML, KMZ layers
            ext = os.path.splitext(src)[1].lower()
            if ext in ('.kml', '.kmz') or '|' in src and any(
                    s in src.lower() for s in ('.kml', '.kmz')):
                # Strip sub-layer suffix
                base_src = src.split('|')[0]
                self.cmb_layer_pick.addItem(
                    f"📍 {layer.name()}", base_src)

        self.cmb_layer_pick.blockSignals(False)

    def _on_layer_picked(self, index):
        """When a layer is picked, populate the file path and auto-scan."""
        src = self.cmb_layer_pick.currentData()
        if not src or not os.path.exists(src):
            return
        self.txt_kml_in.setText(src)
        self._scan_kml_fields()

    def _current_fmt(self):
        """Return 'shp' or 'gpkg' from the format combobox."""
        return self.cmb_out_fmt.currentData() or 'shp'

    def _update_extract_btn_text(self):
        """Sync the convert button text with the selected format."""
        fmt = self._current_fmt().upper()
        is_vi = self.lang == 'vi'
        self.btn_extract.setText(
            f"🔄 CHUYỂN ĐỔI {fmt}" if is_vi else f"🔄 EXTRACT {fmt}")

    def _on_format_changed(self, _index):
        """Re-scan fields when output format changes (SHP vs GPKG names differ)."""
        self._update_extract_btn_text()
        if self.txt_kml_in.text():
            self._scan_kml_fields()

    def _browse_kml(self):
        file_path, _ = QFileDialog.getOpenFileName(
            self, "Chọn File KML/KMZ", "", "KML/KMZ Files (*.kml *.kmz)")
        if file_path:
            self.txt_kml_in.setText(file_path)
            self._scan_kml_fields()

    def _scan_kml_fields(self):
        """Scan KML file and populate field selection table."""
        kml_path = self.txt_kml_in.text()
        if not kml_path or not os.path.exists(kml_path):
            self.lbl_kml_info.setText(
                "⚠ Chưa chọn file" if self.lang == 'vi' else "⚠ No file selected")
            return

        use_gpkg = self._current_fmt() == 'gpkg'
        converter = KmlToShpConverter()
        result = converter.discover_fields(kml_path, use_gpkg=use_gpkg)
        if result is None:
            self.lbl_kml_info.setText(
                "❌ Không đọc được file" if self.lang == 'vi' else "❌ Cannot read file")
            return

        all_fields = result['fields']
        total_features = result['total_features']
        geom_types = result['geom_types']

        # Update info label
        geom_str = ", ".join(sorted(geom_types)) if geom_types else "?"
        fmt_label = "GPKG" if use_gpkg else "SHP"
        info = ("📊 {} features | 📐 {} | "
                "📋 {} fields → {}").format(
            total_features, geom_str, len(all_fields), fmt_label)
        if len(geom_types) > 1:
            if use_gpkg:
                if self.lang == 'vi':
                    info += "\n💡 Multi-geometry → {} layer trong 1 file GPKG".format(
                        len(geom_types))
                else:
                    info += "\n💡 Multi-geometry → {} layers in 1 GPKG file".format(
                        len(geom_types))
            else:
                if self.lang == 'vi':
                    info += "\n💡 Multi-geometry → {} file SHP riêng".format(
                        len(geom_types))
                else:
                    info += "\n💡 Multi-geometry → {} separate SHP files".format(
                        len(geom_types))
        self.lbl_kml_info.setText(info)

        # Populate field table
        self.tbl_kml_fields.setRowCount(0)
        for i, (fname, sample) in enumerate(all_fields.items()):
            self.tbl_kml_fields.insertRow(i)
            chk = QCheckBox()
            chk.setChecked(True)
            self.tbl_kml_fields.setCellWidget(i, 0, chk)
            item_name = QTableWidgetItem(fname)
            item_name.setFlags(item_name.flags() & ~QtCompat.ItemIsEditable)
            self.tbl_kml_fields.setItem(i, 1, item_name)
            item_sample = QTableWidgetItem(sample)
            item_sample.setFlags(item_sample.flags() & ~QtCompat.ItemIsEditable)
            self.tbl_kml_fields.setItem(i, 2, item_sample)

    def _kml_check_all(self):
        for i in range(self.tbl_kml_fields.rowCount()):
            chk = self.tbl_kml_fields.cellWidget(i, 0)
            if chk:
                chk.setChecked(True)

    def _kml_uncheck_all(self):
        for i in range(self.tbl_kml_fields.rowCount()):
            chk = self.tbl_kml_fields.cellWidget(i, 0)
            if chk:
                chk.setChecked(False)

    def _convert_kml(self):
        kml_path = self.txt_kml_in.text()
        if not kml_path or not os.path.exists(kml_path):
            QMessageBox.warning(
                self,
                "Lỗi" if self.lang == 'vi' else "Error",
                "Vui lòng chọn file KML!" if self.lang == 'vi' else "Please select valid KML!")
            return

        use_gpkg = self._current_fmt() == 'gpkg'
        if use_gpkg:
            save_title = "Lưu GPKG" if self.lang == 'vi' else "Save GeoPackage"
            save_filter = "GeoPackage (*.gpkg)"
        else:
            save_title = "Lưu SHP" if self.lang == 'vi' else "Save Shapefile"
            save_filter = "Shapefile (*.shp)"

        out_path, _ = QFileDialog.getSaveFileName(
            self, save_title, "", save_filter)
        if not out_path:
            return

        # Collect selected fields
        selected_fields = None  # None means all
        if self.tbl_kml_fields.rowCount() > 0:
            selected = []
            for i in range(self.tbl_kml_fields.rowCount()):
                chk = self.tbl_kml_fields.cellWidget(i, 0)
                if chk and chk.isChecked():
                    item = self.tbl_kml_fields.item(i, 1)
                    if item:
                        selected.append(item.text())
            if selected:
                selected_fields = selected

        converter = KmlToShpConverter()
        result = converter.convert(
            kml_path, out_path, self.txt_crs.text(),
            selected_fields=selected_fields,
            output_format=self._current_fmt())

        # convert() returns (success, msg) or (success, msg, output_paths)
        if len(result) == 3:
            success, msg, output_paths = result
        else:
            success, msg = result
            output_paths = []

        if success:
            # Auto-load exact output layer(s) into QGIS
            self._load_output_to_qgis(output_paths, use_gpkg)
            QMessageBox.information(
                self,
                "✅ " + ("Thành công" if self.lang == 'vi' else "Success"),
                msg)
        else:
            QMessageBox.warning(
                self,
                "❌ " + ("Lỗi" if self.lang == 'vi' else "Error"),
                msg)

    def _load_output_to_qgis(self, output_paths, use_gpkg):
        """Load converted output file(s) into the QGIS layer panel.

        Args:
            output_paths: list of (file_path, layer_name) tuples from converter
            use_gpkg:     True if output is GPKG, False if SHP
        """
        from qgis.core import QgsMessageLog

        if not output_paths:
            QgsMessageLog.logMessage(
                '[LVT KML] No output_paths to load', 'LVT4U')
            return

        for file_path, layer_name in output_paths:
            try:
                if use_gpkg:
                    # GPKG: uri must specify layer name
                    uri = f'{file_path}|layername={layer_name}'
                else:
                    # SHP: uri is the file path directly
                    uri = file_path

                if self.iface:
                    lyr = self.iface.addVectorLayer(uri, layer_name, 'ogr')
                    if lyr and lyr.isValid():
                        QgsMessageLog.logMessage(
                            f'[LVT KML] Loaded layer: {layer_name}', 'LVT4U')
                    else:
                        QgsMessageLog.logMessage(
                            f'[LVT KML] Layer invalid: {uri}', 'LVT4U')
                else:
                    QgsMessageLog.logMessage(
                        '[LVT KML] iface is None — cannot add layer', 'LVT4U')

            except Exception as e:
                QgsMessageLog.logMessage(
                    f'[LVT KML] Load error ({layer_name}): {e}', 'LVT4U')

        if self.iface:
            self.iface.mapCanvas().refresh()
