import ast
import csv
import ctypes
import os

from qgis.PyQt.QtCore import QVariant
from PyQt5.QtGui import QColor
from qgis.PyQt.QtWidgets import QPushButton, QTableWidgetItem, QHeaderView, QColorDialog, QMessageBox

from qgis.PyQt import QtWidgets, uic, QtCore
from qgis.PyQt.QtCore import pyqtSignal
from qgis._core import QgsProject, QgsVectorLayer, QgsFillSymbol, QgsSymbol, QgsRendererCategory, \
    QgsCategorizedSymbolRenderer, QgsRendererRange, QgsGraduatedSymbolRenderer, QgsField, QgsSingleSymbolRenderer, \
    QgsEmbeddedSymbolRenderer

from .cyanlove_config_read_intfile import readconfig

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


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

    def __init__(self, parent=None):
        super(cyanlove_custom_thematic_maps, self).__init__(parent)
        self.data = None
        self.export_thread = None
        self.setupUi(self)
        self.setFloating(True)
        self.setWindowFlags(QtCore.Qt.Dialog)  # 使对话框始终在前
        # self.setWindowModality(QtCore.Qt.ApplicationModal)  # 或者使用 Qt.WindowModal
        self.mFieldComboBox.setLayer(self.mMapLayerComboBox.currentLayer())
        self.mMapLayerComboBox.currentIndexChanged.connect(self.selectindexchange)
        self.btn_delete_col.clicked.connect(self.btn_delete_colset)
        self.btn_add_col.clicked.connect(self.btn_add_colset)
        self.btn_sav_xml.clicked.connect(self.btn_sav_xmlset)
        self.btn_create_map.clicked.connect(self.btn_create_mapset)
        self.btn_clear_map.clicked.connect(self.btn_clear_mapset)
        self.btn_reset_default.clicked.connect(self.btn_reset_defaultset)  # 新增连接
        self.tableview_init()

    def selectindexchange(self):
        self.mFieldComboBox.setLayer(self.mMapLayerComboBox.currentLayer())

    def tableview_init(self):
        self.tableWidget.setColumnCount(3)  # 列
        self.tableWidget.setHorizontalHeaderLabels(['最大值', '最小值', '颜色'])
        custom_thematic_maps_str = readconfig.read_ini_file('Settings', 'custom_thematic_maps')

        if custom_thematic_maps_str is None:
            self.data = [
                [-160, -120, '#FF0000'],
                [-120, -110, '#FF40FF'],
                [-110, -100, '#ffff00'],
                [-100, -90, '#0000ff'],
                [-90, 0, '#00FF00']
            ]
        else:
            self.data = ast.literal_eval(custom_thematic_maps_str)  # 安全地将字符串转换为列表

        self.tableWidget.setRowCount(len(self.data))
        # 填充数据
        self.tableWidget.setRowCount(len(self.data))
        for row_idx, row_data in enumerate(self.data):
            for col_idx, value in enumerate(row_data):
                if col_idx == 2:  # 颜色列，添加按钮
                    button = QPushButton("")
                    button.setStyleSheet(f"background-color: {value}")
                    button.clicked.connect(lambda checked, row=row_idx: self.change_color(row))
                    self.tableWidget.setCellWidget(row_idx, col_idx, button)
                else:
                    self.tableWidget.setItem(row_idx, col_idx, QTableWidgetItem(str(value)))
                # 设置列宽自适应，所有列均可以拉伸
        for i in range(3):
            self.tableWidget.setColumnWidth(i, 100)  # 设置初始宽度为100
            self.tableWidget.horizontalHeader().setMinimumSectionSize(100)  # 设置每一列的最小宽度为100

        header = self.tableWidget.horizontalHeader()
        header.setSectionResizeMode(0, QHeaderView.ResizeToContents)  # Color_Set 列根据内容自适应
        header.setSectionResizeMode(1, QHeaderView.ResizeToContents)  # 长度列根据内容自适应
        header.setSectionResizeMode(2, QHeaderView.Stretch)  # 颜色列填充剩余空间

    def change_color(self, row):
        # 弹出颜色对话框
        color = QColorDialog.getColor()

        if color.isValid():
            # 获取颜色按钮并改变背景色
            button = self.tableWidget.cellWidget(row, 2)
            button.setStyleSheet(f"background-color: {color.name()}")

    def btn_delete_colset(self):
        # 获取当前选中的行
        current_row = self.tableWidget.currentRow()
        if current_row >= 0:  # 检查是否有选中的行
            # 删除该行
            self.tableWidget.removeRow(current_row)
            # 更新数据列表以反映删除操作
            self.data.pop(current_row)
        else:
            print("没有选中的行可删除。")

    def btn_add_colset(self):
        # 在表格末尾添加新行
        row_count = self.tableWidget.rowCount()
        self.tableWidget.insertRow(row_count)  # 插入新行
        max_value = 100
        min_value = 1
        color = "#FFFFFF"
        # 填充新行的数据
        self.tableWidget.setItem(row_count, 0, QTableWidgetItem(str(max_value)))
        self.tableWidget.setItem(row_count, 1, QTableWidgetItem(str(min_value)))

        # 创建颜色按钮
        button = QPushButton("")
        button.setStyleSheet(f"background-color: {color}")
        button.clicked.connect(lambda checked, row=row_count: self.change_color(row))
        self.tableWidget.setCellWidget(row_count, 2, button)  # 颜色按钮列
        # 更新数据列表
        self.data.append([max_value, min_value, color])

    def btn_sav_xmlset(self):
        spin_box_data = str(self.get_all_data())  # 数据
        readconfig.write_ini_file('Settings', 'custom_thematic_maps', spin_box_data)
        self.label_show.setText('配置成功!')

    def get_layer_fill_style(self, layer):
        """
        获取图层的填充样式
        返回: 'no' - 无填充, 'solid' - 有填充
        """
        try:
            if not layer or not layer.isValid():
                return 'solid'

            renderer = layer.renderer()
            if not renderer:
                return 'solid'

            # 打印调试信息
            print(f"渲染器类型: {type(renderer).__name__}")

            # 单符号渲染器
            if isinstance(renderer, QgsSingleSymbolRenderer):
                symbol = renderer.symbol()
                if symbol:
                    return self.analyze_symbol_fill_style(symbol)

            # 分类渲染器
            elif isinstance(renderer, QgsCategorizedSymbolRenderer):
                categories = renderer.categories()
                if categories:
                    symbol = categories[0].symbol()
                    if symbol:
                        return self.analyze_symbol_fill_style(symbol)

            # 分级渲染器
            elif isinstance(renderer, QgsGraduatedSymbolRenderer):
                ranges = renderer.ranges()
                if ranges:
                    symbol = ranges[0].symbol()
                    if symbol:
                        return self.analyze_symbol_fill_style(symbol)

            return 'solid'  # 默认

        except Exception as e:
            print(f"获取填充样式时出错: {e}")
            return 'solid'

    def analyze_symbol_fill_style(self, symbol):
        """
        分析符号的填充样式
        """
        try:
            # 方法1: 检查符号的简单样式
            if hasattr(symbol, 'symbolLayers') and symbol.symbolLayers():
                for symbol_layer in symbol.symbolLayers():
                    # 检查是否有填充样式属性
                    if hasattr(symbol_layer, 'properties'):
                        props = symbol_layer.properties()
                        if 'style' in props:
                            style = props['style']
                            print(f"符号层样式: {style}")
                            if style == 'no':
                                return 'no'

                    # 检查填充颜色是否完全透明
                    if hasattr(symbol_layer, 'color'):
                        color = symbol_layer.color()
                        if color.alpha() == 0:
                            print("填充颜色完全透明")
                            return 'no'

            # 方法2: 检查符号的颜色
            color = symbol.color()
            print(f"符号颜色: {color.name()}, alpha: {color.alpha()}")
            if color.alpha() == 0:
                return 'no'

            return 'solid'

        except Exception as e:
            print(f"分析符号样式时出错: {e}")
            return 'solid'

    def create_symbol_with_same_style(self, layer, color):
        """
        创建与原始图层相同填充样式的符号
        """
        # 获取原始图层的填充样式
        fill_style = self.get_layer_fill_style(layer)
        print(f"原始图层填充样式: {fill_style}")

        if fill_style == 'no':
            # 无填充样式 - 使用颜色作为边框颜色
            symbol = QgsFillSymbol.createSimple({
                'style': 'no',  # 无填充
                'color_border': color,
                'width_border': '0.5'
            })
            print("创建无填充符号")
        else:
            # 有填充样式 - 使用颜色作为填充颜色，不设置边框
            symbol = QgsFillSymbol.createSimple({
                'style': 'solid',  # 有填充
                'color': color,
                'color_border': '0,0,0,0',  # 透明边框
                'width_border': '0'  # 边框宽度为0
            })
            print("创建有填充符号（无边框）")
        return symbol

    def btn_create_mapset(self):
        self.label_show.setText("")
        # 创建分类符号渲染器
        layer = self.mMapLayerComboBox.currentLayer()
        if not layer:
            self.label_show.setText("请选择有效的图层！")
            return

        print(f"当前图层: {layer.name()}")
        print(f"图层类型: {layer.geometryType()}")

        colname = self.mFieldComboBox.currentField()
        if not colname:
            self.label_show.setText("请选择字段！")
            return

        # 获取字段信息
        field_index = layer.fields().indexOf(colname)
        if field_index == -1:
            self.label_show.setText("选择的字段不存在！")
            return

        field_type = layer.fields().field(field_index).type()

        if field_type not in [QVariant.Int, QVariant.Double]:
            self.label_show.setText("不是数字列，无法创建！")
            return

        ranges = []

        intervals = self.get_all_data()
        if intervals is None:
            self.label_show.setText("设置区间错误！")
            return

        # 获取原始图层的填充样式
        fill_style = self.get_layer_fill_style(layer)
        is_no_fill = (fill_style == 'no')

        print(f"最终判断 - 无填充: {is_no_fill}")

        for interval in intervals:
            try:
                lower_bound = float(interval[0])
                upper_bound = float(interval[1])
                color = interval[2]

                # 创建符号 - 与原始图层相同填充样式
                symbol = self.create_symbol_with_same_style(layer, color)

                # 创建渲染范围
                rangeall = QgsRendererRange(lower_bound, upper_bound, symbol, f"{lower_bound} to {upper_bound}")
                ranges.append(rangeall)

            except (ValueError, IndexError) as e:
                self.label_show.setText(f"区间数据格式错误: {e}")
                return

        # 创建分级渲染器
        try:
            renderer = QgsGraduatedSymbolRenderer(colname, ranges)
            layer.setRenderer(renderer)

            # 刷新图层以应用新样式
            layer.triggerRepaint()

            fill_status = "无填充" if is_no_fill else "有填充"
            self.label_show.setText(f"创建成功！({fill_status})")

        except Exception as e:
            self.label_show.setText(f"创建专题地图时出错: {e}")

    def btn_clear_mapset(self):
        layerselect = self.mMapLayerComboBox.currentLayer()
        if not layerselect:
            self.label_show.setText("请选择有效的图层！")
            return

        # 获取原始图层的填充样式
        fill_style = self.get_layer_fill_style(layerselect)
        is_no_fill = (fill_style == 'no')

        print(f"清空样式 - 无填充: {is_no_fill}")

        # 创建默认符号 - 与原始图层相同填充样式
        if is_no_fill:
            # 无填充样式
            symbol = QgsFillSymbol.createSimple({
                'style': 'no',  # 无填充
                'color_border': 'blue',
                'width_border': '0.5'
            })
        else:
            # 有填充样式 - 不设置边框
            symbol = QgsFillSymbol.createSimple({
                'style': 'solid',  # 有填充
                'color': '100,150,200,100',  # 半透明蓝色
                'color_border': '0,0,0,0',  # 透明边框
                'width_border': '0'  # 边框宽度为0
            })

        # 清除渲染器，设置为默认渲染器
        layerselect.setRenderer(QgsSingleSymbolRenderer(symbol))
        layerselect.triggerRepaint()

        fill_status = "无填充" if is_no_fill else "有填充"
        self.label_show.setText(f'清空完毕！({fill_status})')

    def btn_reset_defaultset(self):
        """恢复默认设置"""
        # 定义默认数据
        default_data = [
            [-160, -120, '#FF0000'],
            [-120, -110, '#FF40FF'],
            [-110, -100, '#ffff00'],
            [-100, -90, '#0000ff'],
            [-90, 0, '#00FF00']
        ]
        reply = QMessageBox.question(self, '确认恢复',
                                     '确定要恢复默认设置吗？这将清除所有自定义配置。',
                                     QMessageBox.Yes | QMessageBox.No,
                                     QMessageBox.No)

        if reply == QMessageBox.Yes:
            # 清空表格
            self.tableWidget.setRowCount(0)

            # 重新填充默认数据
            self.tableWidget.setRowCount(len(default_data))
            for row_idx, row_data in enumerate(default_data):
                for col_idx, value in enumerate(row_data):
                    if col_idx == 2:  # 颜色列，添加按钮
                        button = QPushButton("")
                        button.setStyleSheet(f"background-color: {value}")
                        button.clicked.connect(lambda checked, row=row_idx: self.change_color(row))
                        self.tableWidget.setCellWidget(row_idx, col_idx, button)
                    else:
                        self.tableWidget.setItem(row_idx, col_idx, QTableWidgetItem(str(value)))

            # 更新数据列表
            self.data = default_data.copy()

            # 保存默认配置到配置文件
            readconfig.write_ini_file('Settings', 'custom_thematic_maps', str(default_data))

            self.label_show.setText('已恢复默认设置！')

    def get_all_data(self):
        all_data = []
        row_count = self.tableWidget.rowCount()
        for row in range(row_count):
            row_data = self.get_row_data(row)
            all_data.append(row_data)
        return all_data

    def get_row_data(self, row):
        row_data = []
        for col in range(3):  # 3列
            item = self.tableWidget.item(row, col)

            if item:
                row_data.append(item.text())
            else:
                # 对于按钮列，获取按钮的背景色或其他相关信息
                button = self.tableWidget.cellWidget(row, col)
                if button:
                    # 获取按钮的背景色作为颜色列的值
                    button_color = button.styleSheet().split(':')[-1].strip()
                    row_data.append(button_color)
        return row_data