# -*- coding: utf-8 -*-
import os
from qgis.PyQt import QtWidgets, uic, QtCore
from qgis.PyQt.QtCore import pyqtSignal, QVariant, QThread
from qgis.core import (
    QgsGeometry, QgsVectorLayer, QgsField, QgsProject, QgsFeature,
    QgsWkbTypes, QgsProcessing, QgsProcessingFeedback
)
from qgis.utils import iface
from qgis import processing

FORM_CLASS, _ = uic.loadUiType(os.path.join(
    os.path.dirname(__file__), 'cyanlove_intersects_combine_base.ui'))


class MergeThread(QThread):
    """后台处理线程（带实时进度反馈）"""
    progress = pyqtSignal(int)
    status = pyqtSignal(str)
    finished_signal = pyqtSignal(object, str)  # result_layer, error_msg

    def __init__(self, layer, prefix):
        super().__init__()
        self.layer = layer
        self.prefix = prefix

    def run(self):
        try:
            self.status.emit("⏳ 正在准备数据...")
            self.progress.emit(5)

            # ----- 自定义反馈类，转发算法内部进度 -----
            class DissolveFeedback(QgsProcessingFeedback):
                def __init__(self, progress_signal):
                    super().__init__()
                    self.progress_signal = progress_signal

                def setProgress(self, progress):
                    # 直接转发溶解算法的进度值 (0-100)
                    self.progress_signal.emit(progress)

            feedback = DissolveFeedback(self.progress)

            self.status.emit("⏳ 正在融合要素...")
            dissolve_result = processing.run("native:dissolve", {
                'INPUT': self.layer,
                'FIELD': [],           # 不按字段分组，全部合并
                'OUTPUT': 'memory:'
            }, feedback=feedback)

            dissolved_layer = dissolve_result['OUTPUT']
            if dissolved_layer.featureCount() == 0:
                self.finished_signal.emit(None, "溶解后没有生成任何要素")
                return

            # 溶解完成后进度已经由 feedback 更新到 100
            # 为了后续步骤的进度显示，重置到 85
            self.progress.emit(85)
            self.status.emit("⏳ 正在分离独立区域...")

            # 获取溶解后的几何（已经是多部件）
            dissolved_feature = next(dissolved_layer.getFeatures())
            merged_geom = dissolved_feature.geometry()
            if merged_geom is None or merged_geom.isEmpty():
                self.finished_signal.emit(None, "溶解后的几何为空")
                return

            # 分解为单部件
            parts = self.explode_geometry(merged_geom)

            # 创建输出内存图层
            layer_name = f"{self.layer.name()}_merged_{self.prefix}"
            result_layer = QgsVectorLayer(
                f"MultiPolygon?crs={self.layer.crs().authid()}",
                layer_name,
                "memory"
            )

            # 准备字段（保留原始字段，并添加编号字段）
            fields = self.layer.fields()
            fields.append(QgsField("merged_id", QVariant.String))
            data_provider = result_layer.dataProvider()
            data_provider.addAttributes(fields)
            result_layer.updateFields()

            # 对每个独立部分编号并写入
            output_features = []
            for i, part_geom in enumerate(parts, 1):
                if part_geom.type() != QgsWkbTypes.PolygonGeometry:
                    continue
                out_feature = QgsFeature(result_layer.fields())
                out_feature.setGeometry(part_geom)
                out_feature["merged_id"] = f"{self.prefix}_{i}"
                output_features.append(out_feature)

            data_provider.addFeatures(output_features)
            result_layer.updateExtents()
            self.set_layer_style(result_layer)

            self.progress.emit(100)
            self.status.emit("处理完成")
            self.finished_signal.emit(result_layer, None)

        except Exception as e:
            import traceback
            error_msg = f"处理出错: {str(e)}\n{traceback.format_exc()}"
            self.finished_signal.emit(None, error_msg)

    def explode_geometry(self, geometry):
        """分解多部件几何为单部件列表"""
        parts = []
        if geometry.isMultipart():
            const_geom = geometry.constGet()
            for i in range(const_geom.partCount()):
                part_geom = const_geom.geometryN(i)
                if part_geom:
                    parts.append(QgsGeometry(part_geom.clone()))
        else:
            parts.append(QgsGeometry(geometry))
        return parts

    def set_layer_style(self, layer):
        """设置默认样式"""
        from qgis.core import QgsFillSymbol, QgsSimpleFillSymbolLayer
        from qgis.PyQt.QtGui import QColor
        symbol = QgsFillSymbol()
        symbol_layer = QgsSimpleFillSymbolLayer()
        symbol_layer.setColor(QColor(100, 150, 200, 180))
        symbol_layer.setStrokeColor(QColor(50, 50, 50))
        symbol_layer.setStrokeWidth(0.5)
        symbol.changeSymbolLayer(0, symbol_layer)
        layer.renderer().setSymbol(symbol)
        layer.triggerRepaint()


class cyanlove_intersects_combine(QtWidgets.QDockWidget, FORM_CLASS):
    closingPlugin = pyqtSignal()

    def __init__(self, parent=None):
        super(cyanlove_intersects_combine, self).__init__(parent)
        self.iface = iface
        self.canvas = iface.mapCanvas()
        self.setupUi(self)
        self.setFloating(True)
        self.setWindowFlags(QtCore.Qt.Dialog)

        # 连接按钮信号
        self.btn_merge_and_split.clicked.connect(self.merge_and_split_features)
        # 进度条初始隐藏
        self.progressBar.setVisible(False)
        self.merge_thread = None

    def update_status_message(self, message, is_error=False):
        """更新状态显示"""
        if is_error:
            self.label_show.setStyleSheet("""
                color: #d9534f; 
                background-color: #f2dede; 
                padding: 6px; 
                border-radius: 4px; 
                border-left: 3px solid #d9534f;
                font-weight: bold;
            """)
        else:
            self.label_show.setStyleSheet("""
                color: #5a6c7d; 
                background-color: #f0f4f8; 
                padding: 6px; 
                border-radius: 4px; 
                border-left: 3px solid #4a6fa5;
                font-weight: bold;
            """)
        self.label_show.setText(message)
        QtWidgets.QApplication.processEvents()

    def merge_and_split_features(self):
        """启动后台处理"""
        if self.merge_thread and self.merge_thread.isRunning():
            self.update_status_message("⏳ 已有任务正在运行，请稍后...", is_error=True)
            return

        layer = self.mMapLayerComboBox.currentLayer()
        if not layer:
            self.update_status_message("❌ 错误：请先选择一个图层！", is_error=True)
            return

        if layer.geometryType() != QgsWkbTypes.PolygonGeometry:
            self.update_status_message("❌ 错误：请选择多边形图层！", is_error=True)
            return

        prefix = self.lineEdit_prefix.text().strip()
        if not prefix:
            self.update_status_message("❌ 错误：请输入编号前缀！", is_error=True)
            return

        # 显示进度条，禁用按钮
        self.progressBar.setVisible(True)
        self.progressBar.setValue(0)
        self.btn_merge_and_split.setEnabled(False)
        self.update_status_message(f"⏳ 正在处理图层：{layer.name()} ...")

        # 启动线程
        self.merge_thread = MergeThread(layer, prefix)
        self.merge_thread.progress.connect(self.update_progress)
        self.merge_thread.status.connect(self.update_status_message)
        self.merge_thread.finished_signal.connect(self.on_merge_finished)
        self.merge_thread.start()

    def update_progress(self, value):
        self.progressBar.setValue(value)

    def on_merge_finished(self, result_layer, error_msg):
        self.progressBar.setVisible(False)
        self.btn_merge_and_split.setEnabled(True)

        if error_msg:
            self.update_status_message(f"❌ {error_msg}", is_error=True)
            print(error_msg)
        elif result_layer and result_layer.featureCount() > 0:
            QgsProject.instance().addMapLayer(result_layer)
            prefix = self.lineEdit_prefix.text().strip()
            success_msg = f"✅ 处理完成！生成 {result_layer.featureCount()} 个独立区域，已按前缀'{prefix}'编号"
            self.update_status_message(success_msg, is_error=False)
        else:
            self.update_status_message("⚠️ 警告：处理失败或没有有效的几何要素！", is_error=True)

        self.merge_thread = None

    def closeEvent(self, event):
        if self.merge_thread and self.merge_thread.isRunning():
            self.merge_thread.quit()
            self.merge_thread.wait()
        event.accept()