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

import sqlite3
import re
# import os  # 已移除未使用的导入
from qgis.PyQt.QtCore import pyqtSignal, QVariant
from qgis.PyQt import uic
# from qgis._core import QgsLayerTreeGroup  # 已移除未使用的导入（使用 QgsLayerTreeGroup 替代）

from .cyanlove_config_read_intfile import *

from qgis.core import (
    QgsProject, QgsVectorLayer, QgsGeometry, QgsFeature,
    QgsFillSymbol, QgsLineSymbol, QgsField,
    QgsSingleSymbolRenderer, QgsApplication, QgsLayerTreeGroup  # 添加 QgsLayerTreeGroup
)
# from qgis.utils import iface  # 已在下方导入
from qgis.PyQt import QtCore, QtWidgets
from qgis.utils import iface

FORM_CLASS, _ = uic.loadUiType(os.path.join(  # os 仍在使用
    os.path.dirname(__file__), 'cyanlove_dockwidget_base.ui'))


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

    def __init__(self, parent=None):
        super(cyanloveDockWidget, self).__init__(parent)
        self.setupUi(self)
        self.setFloating(True)
        self.tbname_wanggeshow = "tb_3月栅格cell2025"
        self.setWindowFlags(QtCore.Qt.Dialog)
        self.btn_neight5g.clicked.connect(self.GetNeightCell)
        self.btn_neight4g.clicked.connect(self.GetNeightCell)

    def closeEvent(self, event):
        """重写关闭事件"""
        self.closingPlugin.emit()
        print("关闭！")
        event.accept()

    @staticmethod
    def _validate_cgi(cgi_str):
        """验证CGI格式，返回(是否有效, nodeb_id, cell_id)"""
        if not cgi_str:
            return False, None, None

        # 先去掉可选的 "460-00-" 前缀
        if cgi_str.startswith("460-00-"):
            cgi_str = cgi_str[7:]  # 移除 "460-00-"

        # 验证格式：必须是 字母数字-字母数字（两部分）
        if not re.match(r'^[A-Za-z0-9]+-[A-Za-z0-9]+$', cgi_str):
            return False, None, None

        parts = cgi_str.split('-')
        return True, parts[0], parts[1]

    def GetNeightCell(self):
        sender = self.sender()
        cgistr = self.txt_write.toPlainText().strip()
        valid, nodeb_id, cell_id = self._validate_cgi(cgistr)
        if not valid:
            self.label_2.setText('cgi填写错误！请使用格式: NodeBID-CellID (仅字母数字)')
            return

        try:
            db_path = readconfig.read_ini_file('Settings', 'sqlite_栅格分析')
            conn = sqlite3.connect(db_path)

            # ------------------ 加载 SpatiaLite 扩展 ------------------
            conn.enable_load_extension(True)
            bin_dir = QgsApplication.applicationDirPath()
            dll_path = os.path.join(bin_dir, 'mod_spatialite.dll')
            if not os.path.exists(dll_path):
                self.label_2.setText(f"找不到 SpatiaLite DLL: {dll_path}")
                conn.close()
                return
            try:
                conn.execute("SELECT load_extension(?)", (dll_path,))
            except sqlite3.OperationalError as e:
                self.label_2.setText(f"加载 SpatiaLite 失败: {e}")
                conn.close()
                return
            # -------------------------------------------------------

            cursor = conn.cursor()

            if sender == self.btn_neight4g:
                cursor.execute("CREATE INDEX IF NOT EXISTS index_tbcell ON [TB_Cell4g] ([LTE基站标识], [LTE小区标识])")
                cursor.execute(
                    "CREATE INDEX IF NOT EXISTS index_neight ON [TB_Neighbor4g] ([Scell_NodeB], [Scell_CellID])"
                )

                query = """
                    SELECT '主' AS 类型, AsText(A.geometry) AS wkt, A.[LTE小区名称] AS name
                    FROM TB_Cell4g A
                    WHERE A.[LTE基站标识] = ? AND A.[LTE小区标识] = ?
                    UNION ALL
                    SELECT '邻' AS 类型, AsText(A.geometry) AS wkt, A.[LTE小区名称] AS name
                    FROM TB_Cell4g A
                    INNER JOIN TB_Neighbor4g B
                    ON A.[LTE基站标识] = B.Ncell_NodeB AND A.[LTE小区标识] = B.Ncell_CellID
                    WHERE B.Scell_NodeB = ? AND B.Scell_CellID = ?
                """
                cursor.execute(query, (nodeb_id, cell_id, nodeb_id, cell_id))

            elif sender == self.btn_neight5g:
                cursor.execute("CREATE INDEX IF NOT EXISTS index_tbcell ON [TB_Cell5g] ([NR基站标识], [NR小区标识])")
                cursor.execute(
                    "CREATE INDEX IF NOT EXISTS index_neight ON [TB_Neighbor5g] ([Scell_NodeB], [Scell_CellID])"
                )

                query = """
                    SELECT '主' AS 类型, AsText(A.geometry) AS wkt, A.[NR小区名称] AS name
                    FROM TB_Cell5g A
                    WHERE A.[NR基站标识] = ? AND A.[NR小区标识] = ?
                    UNION ALL
                    SELECT '邻' AS 类型, AsText(A.geometry) AS wkt, A.[NR小区名称] AS name
                    FROM TB_Cell5g A
                    INNER JOIN TB_Neighbor5g B
                    ON A.[NR基站标识] = B.Ncell_NodeB AND A.[NR小区标识] = B.Ncell_CellID
                    WHERE B.Scell_NodeB = ? AND B.Scell_CellID = ?
                """
                cursor.execute(query, (nodeb_id, cell_id, nodeb_id, cell_id))

            else:
                self.label_2.setText('无效的操作！')
                cursor.close()
                conn.close()
                return

            results = cursor.fetchall()
            if not results:
                self.label_2.setText('没有查询到数据！')
                cursor.close()
                conn.close()
                return

            # ================ 创建三个独立图层 ================
            canvas = iface.mapCanvas()
            map_extent = canvas.extent()

            # 创建图层（内部会自动移除同名旧图层）
            main_layer = self._create_memory_layer("Polygon", "主小区")      # 主小区（红色）
            neighbor_layer = self._create_memory_layer("Polygon", "邻小区")   # 邻小区（蓝色）
            line_layer = self._create_memory_layer("LineString", "邻区连线")  # 连线（黑色虚线）

            if main_layer is None or neighbor_layer is None or line_layer is None:
                self.label_2.setText('图层创建失败！')
                cursor.close()
                conn.close()
                return

            # 设置样式
            main_layer.setRenderer(QgsSingleSymbolRenderer(
                QgsFillSymbol.createSimple({'color': 'red', 'outline_color': 'black', 'outline_width': '0.2'})
            ))
            neighbor_layer.setRenderer(QgsSingleSymbolRenderer(
                QgsFillSymbol.createSimple({'color': 'blue', 'outline_color': 'black', 'outline_width': '0.2'})
            ))
            line_layer.setRenderer(QgsSingleSymbolRenderer(
                QgsLineSymbol.createSimple({'color': 'black', 'width': '0.2', 'style': 'dash'})
            ))

            # 获取 providers
            main_provider = main_layer.dataProvider()
            neighbor_provider = neighbor_layer.dataProvider()
            line_provider = line_layer.dataProvider()

            # 添加字段（可选，用于属性）
            for provider in (main_provider, neighbor_provider):
                provider.addAttributes([QgsField('name', QVariant.String)])
                if provider == main_provider:
                    main_layer.updateFields()
                else:
                    neighbor_layer.updateFields()

            # 处理查询结果，分门别类添加到对应图层
            first_centroid = None   # 用于地图定位
            first_main_geom = None  # 用于连线起点（取主小区中心）

            for row in results:
                cell_type = row[0]      # '主' 或 '邻'
                wkt_text = row[1]
                cell_name = row[2]

                geom = QgsGeometry.fromWkt(wkt_text)
                if geom.isNull():
                    continue

                # 根据类型添加
                if cell_type == '主':
                    feat = QgsFeature()
                    feat.setGeometry(geom)
                    feat.setAttributes([cell_name])
                    main_provider.addFeatures([feat])
                    if first_main_geom is None:
                        first_main_geom = geom
                else:  # '邻'
                    feat = QgsFeature()
                    feat.setGeometry(geom)
                    feat.setAttributes([cell_name])
                    neighbor_provider.addFeatures([feat])

                # 记录第一个几何用于地图定位（优先使用主小区）
                if first_centroid is None:
                    first_centroid = geom

            # 如果只有邻小区没有主小区，则使用邻小区定位
            if first_centroid is None and first_main_geom is None:
                first_centroid = geom  # 但可能不存在，若没有任何几何则不设置

            # 绘制连线：主小区中心到每个邻小区中心（仅当两者都存在，且邻小区不在当前视图中）
            if first_main_geom is not None:
                main_center = first_main_geom.centroid().asPoint()
                # 遍历邻小区要素（直接使用邻图层的所有要素）
                for feat in neighbor_layer.getFeatures():
                    neighbor_geom = feat.geometry()
                    if neighbor_geom and not map_extent.intersects(neighbor_geom.boundingBox()):
                        neighbor_center = neighbor_geom.centroid().asPoint()
                        line_geom = QgsGeometry.fromPolylineXY([main_center, neighbor_center])
                        line_feat = QgsFeature()
                        line_feat.setGeometry(line_geom)
                        line_provider.addFeatures([line_feat])

            # 刷新图层
            main_layer.updateExtents()
            neighbor_layer.updateExtents()
            line_layer.updateExtents()

            # ================ 将图层放入组并设置顺序 ================
            root = QgsProject.instance().layerTreeRoot()
            # 移除旧的 "Show_邻区" 组
            old_group = root.findGroup("Show_邻区")
            if old_group:
                root.removeChildNode(old_group)

            # 创建新组
            group = QgsLayerTreeGroup("Show_邻区")
            root.insertChildNode(0, group)  # 插入到最前面（索引0）
            # 添加图层的顺序决定显示顺序（先添加的在下方）
            # 要求：从上到下：主 > 邻 > 线  → 添加顺序：线、邻、主
            group.addLayer(main_layer)  # 最上层
            group.addLayer(neighbor_layer)  # 中间
            group.addLayer(line_layer)  # 最下层

            # 设置图层的显示名称（已在创建时指定，但可再确认）
            main_layer.setName("主小区")
            neighbor_layer.setName("邻小区")
            line_layer.setName("邻区连线")

            # 添加图层到项目（其实已通过group.addLayer自动加入项目，但确保可见）
            QgsProject.instance().addMapLayer(main_layer, False)   # False 表示不添加到根节点（已由组管理）
            QgsProject.instance().addMapLayer(neighbor_layer, False)
            QgsProject.instance().addMapLayer(line_layer, False)

            # 定位地图到第一个要素中心
            if first_centroid is not None:
                canvas.setCenter(first_centroid.centroid().asPoint())
            elif first_main_geom is not None:
                canvas.setCenter(first_main_geom.centroid().asPoint())

            canvas.refresh()
            self.label_2.setText('图层添加成功！')

            cursor.close()
            conn.close()

        except Exception as e:
            self.label_2.setText(f"错误: {str(e)}")
            print(f"Error: {e}")

    @staticmethod
    def _create_memory_layer(geom_type, layer_name):
        """创建内存图层，自动移除同名旧图层"""
        # 移除已有同名图层（防止重复）
        layers = QgsProject.instance().mapLayersByName(layer_name)
        for lyr in layers:
            QgsProject.instance().removeMapLayer(lyr.id())

        # 创建内存图层
        if geom_type == "Polygon":
            uri = "Polygon?crs=EPSG:4326"
        elif geom_type == "LineString":
            uri = "LineString?crs=EPSG:4326"
        else:
            return None

        new_layer = QgsVectorLayer(uri, layer_name, "memory")
        if not new_layer.isValid():
            print(f"图层 '{layer_name}' 创建失败！")
            return None
        # 先不添加到项目，由组管理
        return new_layer