import json
import os
import re
import time
import traceback

import requests
from PyQt5.QtCore import QTimer, QStringListModel
from PyQt5.QtGui import QColor, QIcon, QStandardItem
from qgis.PyQt import QtWidgets, uic, QtCore
from qgis.PyQt.QtCore import pyqtSignal
from qgis._core import QgsWkbTypes, QgsProject, QgsCoordinateTransform, Qgis, QgsPointXY, QgsSettings, QgsGeometry, \
    QgsRectangle, QgsPoint, QgsCoordinateReferenceSystem
from qgis._gui import QgsRubberBand
from qgis.utils import iface

from .cyanlove_copy_longitude_latitude import CopyLatLonTool, ShowBaiduMapTool
from .cyanlove_config_read_intfile import readconfig
from .cyanlove_transform_gps_to_gps import CoordinateConverter

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


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

    def __init__(self, parent=None):
        super(cyanlove_zoom_to_longitude_latitude, self).__init__(parent)
        self.mapTool = None
        self.property_dict = None  # 存储搜索出来的名称，经度，纬度，从在线地图接口
        self.search_data = None
        self.search_model = None
        self.marker = None
        self.setupUi(self)
        self.iface = iface
        self.canvas = iface.mapCanvas()
        self.settings = Settings()
        self.setWindowFlags(QtCore.Qt.Dialog)  # 使对话框始终在前

        self.textEdit_city.setTabChangesFocus(True)  # TAB跳转
        self.setTabOrder(self.textEdit_city, self.textEdit_location)
        self.setTabOrder(self.textEdit_location, self.search_dili_btn)
        # 设置按钮图标
        self.zoom_btn.setIcon(QIcon(':/plugins/cyanlove/icon/search_one.svg'))
        self.zoom_btn.clicked.connect(self.zoomTo_search_points)
        self.clear_btn.setIcon(QIcon(':/plugins/cyanlove/icon/clear_one.svg'))
        self.clear_btn.clicked.connect(self.removeMarker)
        self.search_dili_btn.setIcon(QIcon(':/plugins/cyanlove/icon/search_one.svg'))
        self.search_dili_btn.clicked.connect(self.zoomTo_search_address)

        self.lnglat_shiqu_btn.clicked.connect(self.CopyLatLon)
        self.btn_show_baidu.clicked.connect(self.CopyLatLon)

        # 添加点Marker初始化
        self.marker = QgsRubberBand(self.canvas, QgsWkbTypes.PointGeometry)
        self.marker.setColor(self.settings.markerColor)
        self.marker.setStrokeColor(self.settings.markerColor)
        self.marker.setWidth(self.settings.markerWidth)
        self.marker.setIconSize(self.settings.markerSize)
        self.marker.setIcon(QgsRubberBand.ICON_CROSS)

        # 添加线Marker初始化
        self.crossRb = QgsRubberBand(self.canvas, QgsWkbTypes.LineGeometry)
        # 列表连接双击信号
        self.listview_show.doubleClicked.connect(self.on_item_double_clicked)

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

    def CopyLatLon(self):
        # 获取当前按钮名称并输出
        button_name = self.sender().objectName()  # 假设按钮文本为其名称
        if button_name == "lnglat_shiqu_btn":
            self.mapTool = CopyLatLonTool(self.iface)
        else:
            self.mapTool = ShowBaiduMapTool(self.iface)
        self.canvas.setMapTool(self.mapTool)

    def zoomTolongitude_and_latitude(self, coords):
        try:
            lon = float(coords[0])
            lat = float(coords[1])
            point = QgsPointXY(lon, lat)  # 创建点对象
            epsg4326 = QgsCoordinateReferenceSystem('EPSG:4326')
            # 转到该位置
            self.zoomTo(epsg4326, lon, lat)
            # 添加点Marker
            self.marker.reset(QgsWkbTypes.PointGeometry)
            self.marker.setColor(self.settings.markerColor)
            self.marker.setStrokeColor(self.settings.markerColor)
            self.marker.setWidth(self.settings.markerWidth)
            self.marker.setIconSize(self.settings.markerSize)
            self.marker.setIcon(QgsRubberBand.ICON_CROSS)
            self.marker.addPoint(point)

        except Exception as e:
            traceback.print_exc()
            self.label_lnglat_shuoming.setText(f"无效的经纬度格式,{str(e)}")

    def zoomTo_search_points(self):
        try:
            self.label_lnglat_shuoming.setText("")
            text = self.textEdit.toPlainText().strip()

            pattern = r'(?<=\d)\s*[^0-9.]+\s*(?=\d)'
            input_string = text.strip().replace("，", ",")
            # 替换匹配到的内容为逗号
            output_string = re.sub(pattern, ',', input_string)
            lon, lat = map(float, output_string.split(','))  # 转换为浮点数
            coords = lon, lat
            if len(coords) < 2:
                self.label_lnglat_shuoming.setText("无效的经纬度格式")
            else:
                self.zoomTolongitude_and_latitude(coords)
        except Exception as e:
            traceback.print_exc()
            self.label_lnglat_shuoming.setText(f"无效的经纬度格式")

    def zoomTo_search_address(self):
        city = self.textEdit_city.toPlainText().strip()
        locationstr = self.textEdit_location.toPlainText().strip()
        keyname = readconfig.read_ini_file('Settings', 'tencentkey')

        self.search_model = QStringListModel()
        if keyname == "":
            self.search_data = ["没有腾讯key值，需要配置！"]
            self.listview_show.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)  # 设置为不可编辑
            self.search_model.setStringList(self.search_data)
            self.listview_show.setModel(self.search_model)
            return
        elif city.strip() == "":
            self.search_data = ["没有填写城市！"]
            self.listview_show.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)  # 设置为不可编辑
            self.search_model.setStringList(self.search_data)
            self.listview_show.setModel(self.search_model)
            return
        elif locationstr.strip() == "":
            self.search_data = ["没有填写搜索的名称！"]
            self.listview_show.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)  # 设置为不可编辑
            self.search_model.setStringList(self.search_data)
            self.listview_show.setModel(self.search_model)
        else:
            try:
                self.search_data = ["搜索中..."]
                self.listview_show.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)  # 设置为不可编辑
                self.search_model.setStringList(self.search_data)
                self.listview_show.setModel(self.search_model)
                # 处理事件以更新界面
                QtWidgets.QApplication.processEvents()

                urlb = ("https://apis.map.qq.com/ws/place/v1/search?boundary=region("
                        + city + ",0)&keyword=" + locationstr + "&page_size=20&page_index=1&orderby=_distance&key=" +
                        keyname)

                response = requests.get(urlb, timeout=5)
                jsondata = response.json()
                message = jsondata['message']
                if message != "Success":
                    self.search_data = [f"{message}"]
                    self.listview_show.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)  # 设置为不可编辑
                    self.search_model.setStringList(self.search_data)
                    self.listview_show.setModel(self.search_model)
                    return
                # 获取 data 列表
                properties = jsondata['data']
                self.property_dict = {}  # 初始化
                for p in properties:
                    title = p['title']
                    lng = p['location']['lng']
                    lat = p['location']['lat']
                    self.property_dict[title] = {'lng': lng, 'lat': lat}
                # title视图转为列表
                self.search_data = list(self.property_dict.keys())
                self.listview_show.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)  # 设置为不可编辑
                self.search_model.setStringList(self.search_data)
                self.listview_show.setModel(self.search_model)

            except Exception as e:
                error_message = str(e)
                traceback.print_exc()
                self.search_data = [f"{error_message}"]
                self.listview_show.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)  # 设置为不可编辑
                self.search_model.setStringList(self.search_data)
                self.listview_show.setModel(self.search_model)

    def on_item_double_clicked(self, index):
        # 获取双击的项
        if not self.property_dict:
            return
        item_text = self.search_model.data(index, QtCore.Qt.DisplayRole)
        print(self.property_dict[item_text])
        coordinates = self.property_dict[item_text]
        # 获取 lng 和 lat，GCJ02坐标系
        lng = coordinates['lng']
        lat = coordinates['lat']
        # 转为WGS84坐标系
        list1 = CoordinateConverter.gcj02_to_wgs84(lng, lat)
        # 定位调用
        self.zoomTolongitude_and_latitude(list1)

    def removeMarker(self):
        self.marker.reset(QgsWkbTypes.PointGeometry)
        self.canvas.refresh()

    def zoomTo(self, src_crs, lon, lat):
        # 代码来自Lat Lon Tools 感谢
        canvas_crs = self.canvas.mapSettings().destinationCrs()
        transform = QgsCoordinateTransform(src_crs, canvas_crs, QgsProject.instance())
        x, y = transform.transform(float(lon), float(lat))

        rect = QgsRectangle(x, y, x, y)
        self.canvas.setExtent(rect)

        pt = QgsPointXY(x, y)
        self.highlight(pt)
        self.canvas.refresh()
        return pt

    def highlight(self, point):
        # 代码来自Lat Lon Tools 感谢
        currextent = self.canvas.extent()
        left_pt = QgsPoint(currextent.xMinimum(), point.y())
        right_pt = QgsPoint(currextent.xMaximum(), point.y())

        top_pt = QgsPoint(point.x(), currextent.yMaximum())
        bottom_pt = QgsPoint(point.x(), currextent.yMinimum())

        horizline = QgsGeometry.fromPolyline([left_pt, right_pt])
        vertline = QgsGeometry.fromPolyline([top_pt, bottom_pt])

        self.crossRb.reset(QgsWkbTypes.LineGeometry)
        self.crossRb.setWidth(self.settings.markerWidth)
        self.crossRb.setColor(self.settings.markerColor)
        self.crossRb.addGeometry(horizline, None)
        self.crossRb.addGeometry(vertline, None)

        QTimer.singleShot(700, self.resetRubberbands)

    def resetRubberbands(self):
        self.crossRb.reset()


class Settings:
    def __init__(self):
        self.gridWidth = None
        self.gridColor = None
        self.markerColor = None
        self.markerSize = None
        self.markerWidth = None
        self.readSettings()

    def readSettings(self):
        self.markerWidth = 2
        self.markerSize = 18
        self.markerColor = QColor("red")
        self.markerColor.setAlpha(255)
