import csv
import os
import re


from qgis.PyQt.QtCore import QThread
from qgis.PyQt.QtWidgets import QFileDialog, QProgressBar

from qgis.PyQt import QtWidgets, uic, QtCore
from qgis.PyQt.QtCore import pyqtSignal
from qgis.core import QgsGeometry, QgsPointXY

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


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

    def __init__(self, parent=None):
        super(cyanlove_exportwkt, self).__init__(parent)
        self.export_thread = None
        self.setupUi(self)
        self.setFloating(True)
        self.setWindowFlags(QtCore.Qt.Dialog)  # 使对话框始终在前
        self.btn_wkt.clicked.connect(self.export_wkt)
        self.btn_douhaofenhao.clicked.connect(self.export_wkt)

    def closeEvent(self, event):
        self.closingPlugin.emit()
        event.accept()

    def export_wkt(self, event):
        button = self.sender()
        button_name = ""
        if button:
            # 获取按钮的文本
            button_name = button.objectName()
        options = QFileDialog.Options()  # 创建文件对话框选项
        options |= QFileDialog.ReadOnly  # 可以设置一些选项，例如只读
        file_name, _ = QFileDialog.getSaveFileName(self,
                                                   "选择文件",
                                                   "",
                                                   "CSV文件 (*.csv);;所有文件 (*)",  # 可以添加其他过滤器
                                                   options=options)  # 传递 options 参数
        # 检查用户是否选择了文件
        if file_name:

            selected_layer = self.mMapLayerComboBox.currentLayer()
            if selected_layer is None:
                print("未选择有效图层!")
            else:
                print(f"选择的图层: {selected_layer.name()}")
                csv_file_path = file_name
                self.label_2.setText('开始导出.....')
                # 确保使用现有的进度条
                self.progressBar.setRange(0, 100)  # 设置进度条范围
                self.progressBar.setValue(0)  # 初始化进度条值
                self.progressBar.show()  # 显示进度条 (如果之前是隐藏状态)

                # 启动导出线程
                self.export_thread = ExportThread(selected_layer, csv_file_path, button_name)
                self.export_thread.progress.connect(self.update_progress)  # 连接信号到槽
                self.export_thread.finished.connect(self.export_finished)  # 导出完成后连接到槽
                self.export_thread.start()  # 启动线程


        else:
            print("用户取消了文件选择")  # 处理取消选择的情况

    def update_progress(self, value):
        self.progressBar.setValue(value)  # 更新进度条的值

    def export_finished(self):
        print("导出完成！")
        self.label_2.setText('导出完毕')
        self.progressBar.setValue(100)


class ExportThread(QThread):
    progress = pyqtSignal(int)  # 声明一个信号

    def __init__(self, selected_layer, csv_file_path, select_button):
        super().__init__()
        self.selected_layer = selected_layer
        self.csv_file_path = csv_file_path
        self.select_button = select_button

    def geometry_to_wkt_with_precision(self, geometry, precision=6):
        """将几何对象转换为指定精度的WKT字符串"""
        if geometry is None or geometry.isEmpty():
            return ""

        # 复制几何对象
        geom = QgsGeometry(geometry)

        # 设置坐标精度
        geom_coords = []

        # 根据几何类型处理
        if geom.isMultipart():
            # 处理多部分几何
            parts = []
            for part in geom.asMultiPolygon() if geom.type() == 2 else \
                    (geom.asMultiPolyline() if geom.type() == 1 else geom.asMultiPoint()):
                if isinstance(part, list):
                    if geom.type() == 2:  # 多边形
                        rings = []
                        for ring in part:
                            points = [f"{round(p.x(), precision)} {round(p.y(), precision)}" for p in ring]
                            rings.append(f"({', '.join(points)})")
                        parts.append(f"({', '.join(rings)})")
                    elif geom.type() == 1:  # 线
                        points = [f"{round(p.x(), precision)} {round(p.y(), precision)}" for p in part]
                        parts.append(f"({', '.join(points)})")
                    else:  # 点
                        points = [f"{round(p.x(), precision)} {round(p.y(), precision)}" for p in part]
                        parts.append(f"({', '.join(points)})")

            if geom.type() == 2:
                return f"MULTIPOLYGON({', '.join(parts)})"
            elif geom.type() == 1:
                return f"MULTILINESTRING({', '.join(parts)})"
            else:
                return f"MULTIPOINT({', '.join(parts)})"
        else:
            # 处理单部分几何
            if geom.type() == 2:  # 多边形
                rings = []
                for ring in geom.asPolygon():
                    points = [f"{round(p.x(), precision)} {round(p.y(), precision)}" for p in ring]
                    rings.append(f"({', '.join(points)})")
                return f"POLYGON({', '.join(rings)})"
            elif geom.type() == 1:  # 线
                points = [f"{round(p.x(), precision)} {round(p.y(), precision)}" for p in geom.asPolyline()]
                return f"LINESTRING({', '.join(points)})"
            else:  # 点
                p = geom.asPoint()
                return f"POINT({round(p.x(), precision)} {round(p.y(), precision)})"

    def run(self):
        # 获取字段名，并添加 WKT_BJ，字段名两边加上双引号
        field_names = [f"{field.name()}" for field in self.selected_layer.fields()] + ['WKT_BJ']

        # 获取要素总数以计算进度
        total_features = self.selected_layer.featureCount()

        with open(self.csv_file_path, mode='w', newline='', encoding='gbk') as csv_file:
            writer = csv.writer(csv_file)
            writer.writerow(field_names)

            for index, feature in enumerate(self.selected_layer.getFeatures()):
                row = []
                for field_name in field_names[:-1]:  # 不包括 WKT_BJ
                    value = feature[field_name]  # 获取每个字段的值
                    row.append(f'{value}')  # 在每个值两边添加双引号

                # 计算边界的 WKT 并添加到行中
                if self.select_button == "btn_wkt":
                    # 使用精度为6位的WKT导出
                    boundary_wkt = self.geometry_to_wkt_with_precision(feature.geometry(), precision=6)
                    row.append(f'{boundary_wkt}')  # 在 WKT_BJ 的值两边添加双引号

                if self.select_button == "btn_douhaofenhao":
                    geometry_line = feature.geometry().asWkt()
                    matches = re.findall(r'\((.*?)\)', geometry_line)
                    for match in matches:
                        extracted_string = match.replace('(', '').replace(')', '')
                        li = extracted_string.split(",")
                        m1 = ";".join(i.strip().replace(" ", ",") for i in li)
                        row.append(f"{m1}")  # 在 WKT_BJ 的值两边添加双引号

                writer.writerow(row)

                # 发送进度更新
                progress_value = int((index + 1) / total_features * 100)
                self.progress.emit(progress_value)