import csv
import hashlib
import json
import math
import os
import time
import urllib



import requests
from qgis.PyQt.QtCore import QVariant, QThread, pyqtSignal
from qgis.PyQt import uic
from qgis.core import QgsFillSymbol,  QgsVectorLayer, QgsProject, QgsFields, \
     QgsField, QgsGeometry, QgsPointXY, QgsFeature, QgsSingleSymbolRenderer
from qgis.utils import iface
from qgis.PyQt import QtCore, QtWidgets

from .cyanlove_config_read_intfile import readconfig
from .cyanlove_transform_gps_to_gps import Mecator_to_gps

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


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

    def __init__(self, parent=None):
        super(cyanlove_aoi_draw, self).__init__(parent)

        self.export_thread = None
        self.iface = iface
        self.canvas = iface.mapCanvas()
        self.setupUi(self)
        self.setFloating(True)
        self.layer = None
        self.setWindowFlags(QtCore.Qt.Dialog)  # 使对话框始终在前
        # 设置为模态窗口
        # self.setWindowModality(QtCore.Qt.ApplicationModal)  # 或者使用 Qt.WindowModal
        self.toolButton.clicked.connect(self.draw_aoi)
        self.plainTextEdit.setTabChangesFocus(True)

    def update_label(self, value):
        self.label_show.setText(value)  # 更新值

    # 重写

    def draw_aoi(self):
        city = self.plainTextEdit.toPlainText().strip()
        searchstr = self.plainTextEdit_aoi.toPlainText().strip()
        if city is None or searchstr is None:
            self.label_show.setText("填写不正确！")
            return
        else:
            aky = readconfig.read_ini_file('Settings', 'baidu_key')
            if aky == "":
                self.label_show.setText("没有配置百度Key")
                return
            layName = "SSJ_AOI"
            layerlist = QgsProject.instance().mapLayersByName(layName)
            if layerlist:
                print('cunzai')
                self.layer = layerlist[0]  # 获取列表中的第一个图层
                fields = self.layer.fields()
                provider = self.layer.dataProvider()  # 获取图层的数据提供者
                self.export_thread = ExportThread(provider, fields, city, searchstr, aky)
                self.export_thread.updatelabel.connect(self.update_label)
                self.export_thread.pan_to_featureid.connect(self.pan_to_featureid)
                self.export_thread.start()  # 启动线程
            else:
                self.layer = QgsVectorLayer("Polygon?crs=EPSG:4326", layName, "memory")
                provider = self.layer.dataProvider()  # 获取图层的数据提供者
                fields = QgsFields()  # 创建字段集合
                fields.append(QgsField("name", QVariant.String))  # 添加字符串类型字段
                provider.addAttributes(fields)  # 将字段添加到数据提供者
                self.layer.updateFields()  # 更新图层的字段
                fill_symbol = QgsFillSymbol.createSimple({'color': '241,248,44,128',
                                                          'outline_color': '255,0,35,255',
                                                          'outline_width': '0.5',
                                                          'style': 'solid'})  # alpha 值范围 0-255，0 完全透明，255 不透明
                renderer = QgsSingleSymbolRenderer(fill_symbol)
                self.layer.setRenderer(renderer)
                QgsProject.instance().addMapLayer(self.layer, True)
                # 开始线程
                self.export_thread = ExportThread(provider, fields, city, searchstr, aky)
                self.export_thread.updatelabel.connect(self.update_label)
                self.export_thread.pan_to_featureid.connect(self.pan_to_featureid)
                self.export_thread.start()  # 启动线程

    # 平移到位置
    def pan_to_featureid(self, feature_id_list):
        if self.layer:
            self.canvas.setCenter(feature_id_list)
            self.canvas.refresh()


class ExportThread(QThread):
    updatelabel = pyqtSignal(str)  # 声明一个更新label新增信号
    pan_to_featureid = pyqtSignal(QgsPointXY)

    def __init__(self, provider, fields, city, searchstr, aky):
        super().__init__()
        self.provider = provider
        self.fields = fields
        self.city = city
        self.searchstr = searchstr
        self.aky = aky

    def run(self):

        self.updatelabel.emit("查询中...")
        result = self.get_baidu_json(self.city, self.searchstr, self.aky)
        print(result['status'])
        if result['status'] == 0:
            panToFeatureIds = None
            counta = len(result['result'])
            k = 1
            for dt in result['result']:
                try:
                    # 查询的结果
                    time.sleep(0.2)
                    self.updatelabel.emit(f"Start: {k}/{counta}")
                    k = k + 1
                    AOI_name, point_transformlist = self.getaoi(dt)
                    # 只提取有边界的AOI
                    if len(point_transformlist) > 0:
                        points = [QgsPointXY(x, y) for x, y in point_transformlist]
                        # 使用 fromPolygonXY 创建多边形几何对象
                        geom = QgsGeometry.fromPolygonXY([points])
                        if geom.isGeosValid():
                            feature = QgsFeature(self.fields)  # 创建新特征
                            feature["name"] = AOI_name
                            feature.setGeometry(geom)  # 设置几何对象
                            panToFeatureIds = points[0]
                            self.provider.addFeatures([feature])  # 将特征添加到数据提供者
                        else:
                            print("error,不是边界")

                except Exception as e:
                    print(f"  {str(e)}")
                    self.updatelabel.emit(f"其余：{str(e)})")

            # 平移
            if panToFeatureIds:
                self.pan_to_featureid.emit(panToFeatureIds)

            self.updatelabel.emit("查询完毕！")
        else:
            error_dict = {
                "1": "服务器内部错误",
                "2": "请求参数非法",
                "3": "权限校验失败",
                "4": "配额校验失败",
                "5": "ak不存在或者非法",
                "8": "数据解析失败",
                "9": "高级权限校验失败",
                "101": "AK参数不存在",
                "200": "APP不存在，AK有误请检查再重试",
                "201": "APP被用户自己禁用，请在控制台解禁",
                "202": "APP被管理员删除",
                "203": "APP类型错误",
                "210": "APP IP校验失败",
                "211": "APP SN校验失败",
                "240": "APP 服务被禁用",
                "250": "用户不存在",
                "251": "用户被自己删除",
                "252": "用户被管理员删除",
                "260": "服务不存在",
                "261": "服务被禁用",
                "302": "天配额超限，限制访问",
                "401": "当前并发量已经超过约定并发配额，限制访问"
            }
            if str(result['status']) in error_dict:
                print("S:" + str(result['status']))  # 确保你打印的是字符串
                self.updatelabel.emit(f"错误：{error_dict[str(result['status'])]}")
            else:
                self.updatelabel.emit("错误：出现异常，无法识别的状态")

    @staticmethod
    def get_baidu_json(city, searchstr, aky):
        baiduurl = "https://api.map.baidu.com"
        # 有额度限制
        queryStr = ("/place/v2/suggestion?query=" + searchstr + "&region=" + city +
                    "&city_limit=true&coord_type=1&output=json&ak=" + aky)

        encodedStr = urllib.parse.quote(queryStr, safe="/:=&?#+!$,;'@()*[]")
        sign = hashlib.md5(urllib.parse.quote_plus(encodedStr).encode("utf8"),usedforsecurity=False).hexdigest()
        # 拼接
        qqurl = baiduurl + queryStr + '&sn=' + sign
        data = requests.request('GET', qqurl, timeout=5).content.decode('utf-8')
        dataa = json.loads(data)

        return dataa

    @staticmethod
    def getaoi(dts):
        point_transform = []
        AOI_name = None
        if 'location' in dts:
            try:
                AOI_id = dts['uid']
                AOI_name = dts['name']
                uel_AOI = 'https://map.baidu.com/?newmap=1&qt=ext&uid=' + AOI_id + '&ext_ver=new&ie=utf-8&l=11'
                r_AOI = requests.request('GET', uel_AOI, timeout=5).content.decode('utf-8')
                data_AOI = json.loads(r_AOI)
                xy = dts['location']
                nxy = Mecator_to_gps.BD092WGS84([float(xy['lng']), float(xy['lat'])])
                dts['location'] = nxy
                if 'geo' in data_AOI['content']:
                    print('有aoi')
                    geo_AOI = data_AOI['content']['geo']
                    geo_AOI = geo_AOI.split('|')
                    point = geo_AOI[2].split(",")
                    for i in range(int(len(point) / 2)):  # 全部点的坐标，分别是x,y,的形式
                        if i == 0:  # 第一个点的x坐标删除‘1-’
                            point[2 * i] = point[2 * i][2:]
                        if i == int((len(point) / 2) - 1):  # 最后的点的y坐标删除‘;’
                            point[2 * i + 1] = point[2 * i + 1][:-1]
                        point_Mecator2BD09 = Mecator_to_gps.Mecator2BD09(float(point[2 * i]), float(point[2 * i + 1]))
                        point_BD092WGS84 = Mecator_to_gps.BD092WGS84(point_Mecator2BD09)
                        point_transform.append(point_BD092WGS84)

            except requests.exceptions.Timeout:
                print("请求超时")
            except requests.exceptions.RequestException as e:
                print(f"请求发生错误: {e}")

        return [AOI_name, point_transform]
