# pylint: disable=all
# type: ignore
"""
QGIS插件主模块 - 申少军工具箱
"""

import os
from typing import Optional, List, Callable, Any

from qgis.core import QgsApplication
from qgis import processing
from PyQt5.QtCore import QTranslator, QSettings, Qt, QCoreApplication
from PyQt5.QtWidgets import QMenu, QAction, QMessageBox
from PyQt5.QtGui import QIcon
import webbrowser
from qgis._gui import QgisInterface

from .resources import *  # noqa: F401,F403  # 初始化资源，没有这句，图标不会显示

# 导入所有功能模块
from .cyanlove_updatecolumnattribute_layer import cyanlove_updatecolumnattribute_layer
from .cyanlove_sg_search import cyanlove_sg_search
from .cyanlove_postgresqlset import cyanlove_postgresqlset
from .cyanlove_create_luxianguihua import cyanlove_create_luxianguihua
from .cyanlove_export_centroid_geometry import cyanlove_export_centroid_geometry
from .cyanlove_custom_thematic_maps import cyanlove_custom_thematic_maps
from .cyanlove_create_hotmap import cyanlove_create_hotmap
from .cyanlove_aoi_draw import cyanlove_aoi_draw
from .cyanlove_import_create_sector_geometry import cyanlove_import_create_sector_geometry
from .cyanlove_import_cell_neight_tosqlite import cyanlove_import_cell_neight_tosqlite
from .cyanlove_customdraw import cyanlove_customdraw
from .cyanlove_import_create_point import cyanlove_createpoint
from .cyanlove_import_create_geometry import cyanlove_import_geometry
from .cyanlove_import_create_mutiline import cyanlove_import_create_mutiline
from .cyanlove_export_wkt import cyanlove_exportwkt
from .cyanlove_sqliteset import cyanlove_sqliteset
from .cyanlove_dockwidget import cyanloveDockWidget
from .cyanlove_export_sheetattribute import cyanlove_export_sheetattribute
from .cyanlove_import_csv_excel_sqlite import cyanlove_import_csv_excel_sqlite
from .cyanlove_zoom_to_longitude_latitude import cyanlove_zoom_to_longitude_latitude
from .cyanlove_tencent_keyset import cyanlove_tencent_keyset
from .cyanlove_cell_nodeb_search import cyanlove_cell_nodeb_search
from .cyanlove_export_tab_kml import cyanlove_export_tab_kml
from .cyanlove_buffer import cyanlove_buffer
from .cyanlove_import_layer_tosqlite import cyanlove_import_layerattribute_tosqlite
from .cyanlove_calc_area import cyanlove_calc_area
from .cyanlove_calc_intersects_area import cyanlove_calc_intersects_area
from .cyanlove_calc_intersects_geometry import cyanlove_calc_intersects_geometry
from .cyanlove_calc_contain_point_in_geometry import cyanlove_calc_contain_point_in_geometry
from .cyanlove_sqlite_create_index import cyanlove_sqlite_create_index
from .cyanlove_import_create_shange_geometry import cyanlove_import_create_shange_geometry


class CyanLove:
    """QGIS插件主类 - 申少军工具箱"""

    def __init__(self, iface: QgisInterface) -> None:
        """
        初始化插件

        Args:
            iface: QGIS界面接口
        """
        self.iface: QgisInterface = iface
        self.plugin_dir: str = os.path.dirname(__file__)

        # 设置国际化
        locale = QSettings().value('locale/userLocale', 'zh-CN')
        if isinstance(locale, str):
            locale_code = locale[0:2]
        else:
            locale_code = 'zh'

        locale_path: str = os.path.join(
            self.plugin_dir,
            'i18n',
            f'cyanlove_{locale_code}.qm'
        )

        if os.path.exists(locale_path):
            self.translator: QTranslator = QTranslator(parent=None)
            self.translator.load(locale_path)
            QCoreApplication.installTranslator(self.translator)

        # 初始化成员变量
        self.menu: Optional[QMenu] = None
        self.actions: List[QAction] = []

        # DockWidget实例缓存
        self._dockwidgets = {}

        # 创建工具栏
        self.toolbar = self.iface.addToolBar('申少军工具箱')
        self.toolbar.setObjectName('申少军工具箱')
        self.toolbar.setToolTip('申少军工具箱')

    def _get_dockwidget(self, key: str, widget_class: Any, *args, **kwargs) -> Any:

        if key not in self._dockwidgets:
            self._dockwidgets[key] = widget_class(*args, **kwargs)
        return self._dockwidgets[key]

    def initGui(self) -> None:
        """初始化GUI界面"""
        # 创建主菜单
        self.menu = QMenu(QCoreApplication.translate("cyanlove", "申少军工具箱"), parent=None)
        self.iface.mainWindow().menuBar().addMenu(self.menu)

        # 图标路径
        icon_paths = {
            'icon1': ':/plugins/cyanlove/icon/flab-b-o-svgrepo-com.svg',
            'icon2': ':/plugins/cyanlove/icon/globe-users-svgrepo-com.svg',
            'icon3': ':/plugins/cyanlove/icon/map-search-svgrepo-com.svg',
            'icon4': ':/plugins/cyanlove/icon/location-man-svgrepo-com.svg',
            'icon5': ':/plugins/cyanlove/icon/location-on-svgrepo-com.svg',
        }

        icon2 = icon_paths['icon2']

        # 定义子菜单项
        db_submenu = [
            ("Sqlite数据库配置", self.sub_sqlite, icon2),
            ("PostGreSQL数据库配置", self.sub_postgresql, icon2),
            ("腾讯/百度/高德地图_Key值配置", self.sub_tencent_keyset, icon2)
        ]

        export_submenu = [
            ("边界经纬度集合导出", self.sub_export_wkt_tocsv, icon2),
            ("属性表信息导出", self.sub_export_attribute, icon2),
            ("几何中心/质心导出", self.sub_export_centroid, icon2),
            ("导出为TAB/KML格式", self.sub_export_tab_kml_file, icon2),
        ]

        import_submenu = [
            ("选择图层数据导入(Sqlite)", self.sub_import_layerattribute_tosqlite, icon2),
            ("邻区表CSV导入(Sqlite)", self.sub_import_cell_neigth_file_tosqlite, icon2),
            ("其他文件CSV/Excel导入(Sqlite)", self.sub_import_csv_excel_tosqlite, icon2),
            ("创建索引(Sqlite)", self.sub_create_index_colname_sqlite, icon2),
        ]

        create_polygon_submenu = [
            ("创建点图层", self.sub_draw_point, icon2),
            ("创建线图层", self.sub_draw_mutiline, icon2),
            ("创建面图层", self.sub_draw_polygon, icon2),
            ("自定义点、线、面图层=>(逗号,分号)或WKT格式", self.sub_custom_draw_polygon, icon2),
            ("创建扇区图层", self.sub_create_secotr_geometry, icon2),
            ("创建热力图", self.sub_create_hotmap, icon2),
            ("创建自定义专题地图", self.sub_cyanlove_custom_thematic_maps, icon2),
            ("创建自定义栅格图", self.sub_cyanlove_custom_shange_maps, icon2),
        ]

        zoom_location_submenu = [
            ("坐标定位/地理搜索", self.sub_zoom_to_longitude_latitude, icon2),
            ("小区/基站搜索定位", self.sub_cell_nodeb_search, icon2),
            ("AOI定位", self.sub_aoi_draw, icon2),
            ("路线规划", self.sub_create_luxianguihua, icon2),
        ]

        wangluoyouhua_submenu = [
            ("邻区显示(Sqlite)", self.sub_show_shange_neigth, icon2),
            ("栅格显示(PostGreSQL)", self.sub_show_shange, icon2),
        ]

        updatelayer_submenu = [
            ("更改图层字段类型", self.sub_updatecolumnattribute, icon2),
            ("修正几何图形", self.sub_qgis_fixgeometries, icon2),
        ]

        diliwenxi_submenu = [
            ("缓冲区分析", self.sub_buffer_meters, icon2),
            ("面积计算", self.sub_calc_area, icon2),
            ("相交面积计算", self.sub_calc_intersects_area, icon2),
            ("图层合并", self.sub_qgis_mergevectorlayers, icon2),
            ("关系计算_包含", self.sub_calc_contain_point_in_geometry, icon2),
            ("关系计算_相交", self.sub_calc_intersects_geometry, icon2),
            ("关系计算_合并", self.sub_qgis_dissolve, icon2),
            ("关系计算_多条件合并", self.sub_qgis_aggregate, icon2),
            ("关系计算_凸包", self.sub_qgis_convexhull, icon2),
        ]

        shiyong_submenu = [
            ("使用方法", self.sub_showusermethod, icon2),
        ]

        # 添加菜单项和子菜单
        self._add_menu_actions("数据配置", db_submenu)
        self._add_menu_actions("数据导出", export_submenu)
        self._add_menu_actions("数据入库", import_submenu)

        # 添加分隔符
        separator1 = QAction("1.", parent=self.menu)
        separator1.setSeparator(True)
        self.menu.addAction(separator1)

        self._add_menu_actions("创建图层", create_polygon_submenu)
        self._add_menu_actions("定位/搜索", zoom_location_submenu)
        self._add_menu_actions("图形处理分析", diliwenxi_submenu)
        self._add_menu_actions("图层处理", updatelayer_submenu)
        self._add_menu_actions("网络优化", wangluoyouhua_submenu)
        self._add_menu_actions("使用说明", shiyong_submenu)

        # 添加分隔符
        separator2 = QAction("2.", parent=self.menu)
        separator2.setSeparator(True)
        self.menu.addAction(separator2)

        # 添加工具栏
        self._add_toolbar_actions(icon_paths['icon1'], "坐标定位/地理搜索", self.sub_zoom_to_longitude_latitude)
        self._add_toolbar_actions(icon_paths['icon5'], "小区/基站搜索定位", self.sub_cell_nodeb_search)
        self._add_toolbar_actions(icon_paths['icon3'], "邻区显示", self.sub_show_shange_neigth)
        self._add_toolbar_actions(icon_paths['icon2'], "栅格显示(PostGreSQL)", self.sub_show_shange)
        self._add_toolbar_actions(icon_paths['icon4'], "AOI定位", self.sub_aoi_draw)

    def _add_toolbar_actions(self, icon_path: str, text: str, method: Callable) -> None:
        """
        添加工具栏按钮

        Args:
            icon_path: 图标路径
            text: 按钮文本
            method: 回调方法
        """
        icon = QIcon(icon_path)
        action = QAction(icon, text, parent=self.iface.mainWindow())
        action.triggered.connect(method)  # type: ignore[reportUnknownMemberType]
        action.setEnabled(True)
        self.toolbar.addAction(action)
        self.actions.append(action)

    def _add_menu_actions(self, menu_name: str, submenu_items: list) -> None:
        """
        添加菜单项及其子菜单

        Args:
            menu_name: 菜单名称
            submenu_items: 子菜单项列表
        """
        action = QAction(QCoreApplication.translate("cyanlove", menu_name), parent=self.iface.mainWindow())
        self.menu.addAction(action)
        self.actions.append(action)

        submenu = self._create_submenu(menu_name, submenu_items)
        action.setMenu(submenu)

    def _create_submenu(self, submenu_name: str, actions_list: list) -> QMenu:
        """
        创建子菜单

        Args:
            submenu_name: 子菜单名称
            actions_list: 动作列表

        Returns:
            子菜单对象
        """
        submenu = QMenu(QCoreApplication.translate("cyanlove", submenu_name), parent=self.iface.mainWindow())
        for action_name, method, icon_path in actions_list:
            self._add_submenu_action(submenu, action_name, method, icon_path)
        return submenu

    def _add_submenu_action(self, submenu: QMenu, action_name: str, method: Callable, icon_path: str) -> None:
        """
        添加子菜单项

        Args:
            submenu: 子菜单对象
            action_name: 动作名称
            method: 回调方法
            icon_path: 图标路径
        """
        action = QAction(QCoreApplication.translate("cyanlove", action_name), parent=self.iface.mainWindow())
        action.triggered.connect(method)  # type: ignore[reportUnknownMemberType]
        action.setIcon(QIcon(icon_path))
        submenu.addAction(action)

    def _set_center(self, dockwidget: Any) -> None:
        """将DockWidget居中显示"""
        self.iface.addDockWidget(Qt.BottomDockWidgetArea, dockwidget)

        dock_width = dockwidget.size().width()
        dock_height = dockwidget.size().height()

        main_window_rect = self.iface.mainWindow().geometry()
        center_x = (main_window_rect.width() - dock_width) // 2
        center_y = (main_window_rect.height() - dock_height) // 2

        dockwidget.setGeometry(center_x, center_y, dock_width, dock_height)
        dockwidget.setFloating(True)
        dockwidget.show()
        dockwidget.raise_()

    def _set_right_bottom(self, dockwidget: Any, widthset: int = 10, heightset: int = 80) -> None:
        """将DockWidget设置在右下角"""
        self.iface.addDockWidget(Qt.BottomDockWidgetArea, dockwidget)

        dock_width = dockwidget.size().width()
        dock_height = dockwidget.size().height()

        main_window_rect = self.iface.mainWindow().geometry()
        dock_x = main_window_rect.width() - dock_width - widthset
        dock_y = main_window_rect.height() - dock_height - heightset

        dockwidget.setGeometry(dock_x, dock_y, dock_width, dock_height)
        dockwidget.setFloating(True)
        dockwidget.show()
        dockwidget.raise_()

    # ==================== 功能方法 ====================

    def sub_show_shange_neigth(self) -> None:
        """邻区显示"""
        widget = self._get_dockwidget('show_shange_neigth', cyanloveDockWidget)
        self._set_right_bottom(widget)

    def sub_show_shange(self) -> None:
        """栅格显示"""
        widget = self._get_dockwidget('show_shange', cyanlove_sg_search)
        self._set_right_bottom(widget)

    def sub_cell_nodeb_search(self) -> None:
        """小区/基站信息搜索"""
        widget = self._get_dockwidget('cell_nodeb_search', cyanlove_cell_nodeb_search)
        self._set_right_bottom(widget)

    def sub_export_wkt_tocsv(self) -> None:
        """导出WKT格式边界集"""
        widget = self._get_dockwidget('export_wkt', cyanlove_exportwkt)
        self._set_center(widget)

    def sub_sqlite(self) -> None:
        """Sqlite数据库配置"""
        widget = self._get_dockwidget('sqlite', cyanlove_sqliteset)
        self.iface.addDockWidget(Qt.AllDockWidgetAreas, widget)
        widget.show()

    def sub_postgresql(self) -> None:
        """PostGreSQL数据库配置"""
        widget = self._get_dockwidget('postgresql', cyanlove_postgresqlset)
        self.iface.addDockWidget(Qt.AllDockWidgetAreas, widget)
        widget.show()

    def sub_import_cell_neigth_file_tosqlite(self) -> None:
        """导入小区和邻区表到sqlite数据库"""
        widget = self._get_dockwidget('import_cell_neight', cyanlove_import_cell_neight_tosqlite)
        self._set_center(widget)

    def sub_import_csv_excel_tosqlite(self) -> None:
        """导入csv/excel到sqlite数据库"""
        widget = self._get_dockwidget('import_csv_excel', cyanlove_import_csv_excel_sqlite)
        self._set_center(widget)

    def sub_draw_polygon(self) -> None:
        """选择csv/excel文件绘制多边形面"""
        widget = self._get_dockwidget('draw_polygon', cyanlove_import_geometry)
        self._set_center(widget)

    def sub_draw_mutiline(self) -> None:
        """选择csv/excel文件绘制多条线"""
        widget = self._get_dockwidget('draw_mutiline', cyanlove_import_create_mutiline)
        self._set_center(widget)

    def sub_custom_draw_polygon(self) -> None:
        """输入经纬度集绘制点、线、面"""
        widget = self._get_dockwidget('custom_draw', cyanlove_customdraw)
        self.iface.addDockWidget(Qt.RightDockWidgetArea, widget)
        widget.show()

    def sub_zoom_to_longitude_latitude(self) -> None:
        """坐标定位"""
        widget = self._get_dockwidget('zoom_to_ll', cyanlove_zoom_to_longitude_latitude)
        self.iface.addDockWidget(Qt.LeftDockWidgetArea, widget)
        widget.show()

    def sub_draw_point(self) -> None:
        """选择点文件，创建点图层"""
        widget = self._get_dockwidget('draw_point', cyanlove_createpoint)
        self._set_center(widget)

    def sub_export_attribute(self) -> None:
        """导出图层属性表"""
        widget = self._get_dockwidget('export_attribute', cyanlove_export_sheetattribute)
        self.iface.addDockWidget(Qt.AllDockWidgetAreas, widget)
        self._set_center(widget)

    def sub_tencent_keyset(self) -> None:
        """腾讯key值设置"""
        widget = self._get_dockwidget('tencent_keyset', cyanlove_tencent_keyset)
        self.iface.addDockWidget(Qt.AllDockWidgetAreas, widget)
        widget.show()

    def sub_export_tab_kml_file(self) -> None:
        """导出mapinfo TAB或者KML文件"""
        widget = self._get_dockwidget('export_tab_kml', cyanlove_export_tab_kml)
        self.iface.addDockWidget(Qt.AllDockWidgetAreas, widget)
        self._set_center(widget)

    def sub_buffer_meters(self) -> None:
        """实现米的缓冲"""
        widget = self._get_dockwidget('buffer', cyanlove_buffer)
        self.iface.addDockWidget(Qt.AllDockWidgetAreas, widget)
        self._set_center(widget)

    def sub_import_layerattribute_tosqlite(self) -> None:
        """实现图层数据入库"""
        widget = self._get_dockwidget('import_layer', cyanlove_import_layerattribute_tosqlite)
        self._set_center(widget)

    def sub_calc_area(self) -> None:
        """面积计算"""
        widget = self._get_dockwidget('calc_area', cyanlove_calc_area)
        self._set_center(widget)

    def sub_calc_intersects_area(self) -> None:
        """相交面积计算"""
        widget = self._get_dockwidget('calc_intersects_area', cyanlove_calc_intersects_area)
        self._set_center(widget)

    def sub_calc_intersects_geometry(self) -> None:
        """相交计算"""
        widget = self._get_dockwidget('calc_intersects_geometry', cyanlove_calc_intersects_geometry)
        self._set_center(widget)

    def sub_calc_contain_point_in_geometry(self) -> None:
        """点是否在边界内计算"""
        widget = self._get_dockwidget('calc_contain_point', cyanlove_calc_contain_point_in_geometry)
        self._set_center(widget)

    def sub_create_index_colname_sqlite(self) -> None:
        """创建数据库索引"""
        widget = self._get_dockwidget('create_index', cyanlove_sqlite_create_index)
        self.iface.addDockWidget(Qt.AllDockWidgetAreas, widget)
        widget.show()

    def sub_create_secotr_geometry(self) -> None:
        """创建扇区图"""
        widget = self._get_dockwidget('create_sector', cyanlove_import_create_sector_geometry)
        self.iface.addDockWidget(Qt.DockWidgetArea_Mask, widget)
        widget.show()

    def sub_cyanlove_custom_shange_maps(self) -> None:
        """创建自定义栅格图"""
        widget = self._get_dockwidget('create_shange', cyanlove_import_create_shange_geometry)
        self.iface.addDockWidget(Qt.DockWidgetArea_Mask, widget)
        widget.show()

    def sub_aoi_draw(self) -> None:
        """AOI绘制"""
        widget = self._get_dockwidget('aoi_draw', cyanlove_aoi_draw)
        self._set_right_bottom(widget)

    def sub_create_hotmap(self) -> None:
        """创建热力图"""
        widget = self._get_dockwidget('create_hotmap', cyanlove_create_hotmap)
        self._set_right_bottom(widget)

    def sub_cyanlove_custom_thematic_maps(self) -> None:
        """自定义专题地图"""
        widget = self._get_dockwidget('thematic_maps', cyanlove_custom_thematic_maps)
        self._set_right_bottom(widget)

    def sub_export_centroid(self) -> None:
        """导出中心点"""
        widget = self._get_dockwidget('export_centroid', cyanlove_export_centroid_geometry)
        self._set_center(widget)

    def sub_create_luxianguihua(self) -> None:
        """路线规划"""
        widget = self._get_dockwidget('create_luxianguihua', cyanlove_create_luxianguihua)
        self._set_right_bottom(widget)

    def sub_calc_min_distince(self) -> None:
        """要素之间最短线"""
        widget = self._get_dockwidget('calc_min_distance', cyanlove_create_luxianguihua)
        self._set_right_bottom(widget)

    def sub_updatecolumnattribute(self) -> None:
        """更改图层字段类型"""
        widget = self._get_dockwidget('update_column', cyanlove_updatecolumnattribute_layer)
        self._set_center(widget)

    # ==================== 静态处理方法 ====================

    @staticmethod
    def sub_qgis_aggregate() -> None:
        """相交合并计算"""
        processing.execAlgorithmDialog('qgis:aggregate')  # type: ignore[reportUnknownMemberType]

    @staticmethod
    def sub_qgis_dissolve() -> None:
        """合并计算"""
        processing.execAlgorithmDialog('qgis:dissolve')  # type: ignore[reportUnknownMemberType]

    @staticmethod
    def sub_qgis_mergevectorlayers() -> None:
        """图层合并"""
        processing.execAlgorithmDialog('qgis:mergevectorlayers')  # type: ignore[reportUnknownMemberType]

    @staticmethod
    def sub_qgis_convexhull() -> None:
        """凸包计算"""
        processing.execAlgorithmDialog('qgis:convexhull')  # type: ignore[reportUnknownMemberType]

    @staticmethod
    def sub_qgis_fixgeometries() -> None:
        """修正几何图形"""
        processing.execAlgorithmDialog('qgis:fixgeometries')  # type: ignore[reportUnknownMemberType]

    @staticmethod
    def sub_analysis2() -> None:
        """显示提示信息"""
        msg_box = QMessageBox(parent=None)
        msg_box.setWindowTitle("提示")
        msg_box.setText("功能还没写，后续补充！")
        msg_box.setIcon(QMessageBox.Information)
        msg_box.setStandardButtons(QMessageBox.Ok)
        msg_box.exec_()

    def sub_showusermethod(self) -> None:
        url = "https://shenshaojun.oss-cn-hangzhou.aliyuncs.com/QGIS_Project_ssj/QGISGongJu_UseingMethod.html"
        webbrowser.open(url)

    def unload(self) -> None:
        """卸载插件，清理资源"""
        # 清除菜单
        if self.menu is not None:
            self.iface.mainWindow().menuBar().removeAction(self.menu.menuAction())
            self.menu.deleteLater()
            self.menu = None

        # 清除工具栏
        if self.toolbar is not None:
            self.iface.mainWindow().removeToolBar(self.toolbar)

        # 清除所有动作
        for action in self.actions:
            action.setEnabled(False)
            # 尝试从菜单中移除
            if self.menu is not None:
                self.menu.removeAction(action)

        self.actions.clear()
        self._dockwidgets.clear()