"""
/***************************************************************************
 Gruhanaksha
                                 A QGIS plugin
 Svamitva
 Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/
                              -------------------
        begin                : 2025-07-15
        copyright            : (C) 2025 by Surveyor Stories
        email                : surveyorstories@gmail.com
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
"""

__author__ = 'Surveyor Stories'
__date__ = '2025-07-15'
__copyright__ = '(C) 2025 by Surveyor Stories'

# This will get replaced with a git SHA1 when you do a git archive

__revision__ = '$Format:%H$'


from qgis.core import QgsProject

import os.path


import os
import sys
import inspect
from qgis.utils import iface
from qgis.PyQt.QtWidgets import QAction, QMenu, QLabel
from .autosaveandbackup import BackupPlugin
from qgis.PyQt.QtGui import QIcon


from qgis.core import QgsApplication
from .Gruhanaksha_provider import SvamitvaPPMProvider

from .master import MasterWidget
from .tools import ToolWidget
from .advanced_line import activate_tool, ProfessionalLineTool
from .atlas_export import show_atlas_export_dialog
from .addon_functions import asksaveProject
from .presentation import PresentationDialog


cmd_folder = os.path.split(inspect.getfile(inspect.currentframe()))[0]

if cmd_folder not in sys.path:
    sys.path.insert(0, cmd_folder)

master = MasterWidget()
qgis_main_window = iface.mainWindow()


class GruhanakshaPlugin(object):

    def __init__(self, iface):
        self.provider = None
        self.iface = iface
        self.canvas = iface.mapCanvas()
        self.tools = ToolWidget()
        self.backup_plugin = None
        self.backup_widget_instance = None
        self.current_tool = None
        self.ppm_dialog = None
        # self.tools.setParent(iface.mainWindow(), Qt.WindowType.Window)

        # Initialize GUI elements to None to avoid 'defined outside __init__' warnings
        self.toolbar = None
        self.action = None
        self.dropdown_button = None
        self.action_master = None
        self.action_advanced_line = None
        self.action_tools = None
        self.dropdown_menu = None
        self.action_atlasexport = None
        self.action_backup = None
        self.action_presentation = None
        self.action_topology_checker = None
        self.backup_timer_label = None

    def initProcessing(self):
        """Init Processing provider for QGIS >= 3.8."""
        self.provider = SvamitvaPPMProvider()
        QgsApplication.processingRegistry().addProvider(self.provider)

    def initGui(self):
        self.initProcessing()

        # Create the toolbar
        self.toolbar = self.iface.addToolBar('Gruhanaksha Toolbar')
        self.toolbar.setObjectName('Gruhanaksha Toolbar')

        # Define action with icon and label
        # Make sure this file exists
        icon_path = os.path.join(os.path.join(cmd_folder, 'images/ppm.svg'))
        icon = QIcon(icon_path)
        icon_advancedicon = os.path.join(os.path.join(
            cmd_folder, 'images/advanced_line.svg'))
        icon = QIcon(icon_path)
        self.action = QAction(icon, "PPM Generation", self.iface.mainWindow())
        self.dropdown_button = QAction(
            QIcon(icon), "Maps", self.iface.mainWindow())
        self.action.triggered.connect(self.run_svamitva_algorithm)
        self.dropdown_button.triggered.connect(self.run_svamitva_algorithm)

        # self.toolbar.addAction(self.action)
        self.iface.addPluginToMenu("&Gruhanaksha", self.action)
        # master panel
        self.action_master = QAction(QIcon(icon_path), 'Master Data',
                                     self.iface.mainWindow())
        self.action_master.triggered.connect(self.master_data)
        self.iface.addPluginToMenu(
            u"&Gruhanaksha", self.action_master)
        # advanced line
        self.action_advanced_line = QAction(QIcon(icon_advancedicon), 'Advanced Line',
                                            self.iface.mainWindow())

        # Define tools with icon and label
        # Make sure this file exists
        icon_path = os.path.join(os.path.join(cmd_folder, 'images/ppm.svg'))
        topo = os.path.join(os.path.join(cmd_folder, 'images/topo.svg'))

        self.action_tools = QAction(
            QIcon(topo), "Tools", self.iface.mainWindow())

        self.dropdown_button = QAction(
            QIcon(icon), "PPMs", self.iface.mainWindow())
        self.action_tools.triggered.connect(self.show_tools)
        self.dropdown_button.triggered.connect(self.run_svamitva_algorithm)

        # Create a dropdown menu

        self.dropdown_menu = QMenu("Maps Menu")
        # Add actions to the dropdown menu
        self.dropdown_menu.addAction(self.action_master)
        self.dropdown_menu.addAction(self.action)

        # Create a button in the toolbar to display the dropdown menu with an icon
        self.dropdown_button.setMenu(self.dropdown_menu)

        icon_atlasexport = os.path.join(
            os.path.join(cmd_folder, 'images/export.svg'))
        self.action_atlasexport = QAction(QIcon(icon_atlasexport), 'Atlas Export',
                                          self.iface.mainWindow())
        self.action_atlasexport.triggered.connect(self.show_atlasexport)

        self.iface.addPluginToMenu("&Gruhanaksha", self.action_atlasexport)

        icon_backup = os.path.join(
            os.path.join(cmd_folder, 'images/export.svg'))
        self.action_backup = QAction(QIcon(icon_backup), 'Backup',
                                     self.iface.mainWindow())
        self.action_backup.triggered.connect(self.show_backup_widget)

        self.iface.addPluginToMenu("&Gruhanaksha", self.action_backup)

        # Presentation action
        icon_presentation = os.path.join(os.path.join(cmd_folder, 'images/export.svg'))
        self.action_presentation = QAction(QIcon(icon_presentation), 'Presentation', self.iface.mainWindow())
        self.action_presentation.triggered.connect(self.show_presentation)
        # self.iface.addPluginToMenu("&Gruhanaksha", self.action_presentation)

        # Topology Checker action
        self.action_topology_checker = QAction(QIcon(topo), 'Topology Checker', self.iface.mainWindow())
        self.action_topology_checker.triggered.connect(self.show_topology_checker)
        self.iface.addPluginToMenu("&Gruhanaksha", self.action_topology_checker)

        # Adding icons to the toolbar
        self.toolbar.addAction(self.action_tools)
        self.toolbar.addAction(self.dropdown_button)
        self.toolbar.addAction(self.action_advanced_line)
        self.toolbar.addAction(self.action_atlasexport)
        # self.toolbar.addAction(self.action_presentation)
        # self.toolbar.addAction(self.action_backup)

        self.backup_timer_label = QLabel("")
        self.backup_timer_label.setVisible(False)
        self.toolbar.addWidget(self.backup_timer_label)

        # self.iface.registerMainWindowAction(
        #     self.action_advanced_line, "Alt + A")

        # Set up checkable behavior for advanced line tool
        self.setup_checkable_tool_action(
            self.action_advanced_line, ProfessionalLineTool, activate_tool)

    def unload(self):
        """Remove plugin from GUI and unregister provider."""

        # CRITICAL: Deactivate any active map tools first
        # This prevents tools from staying active after plugin unload
        if hasattr(self, 'canvas') and self.canvas:
            current_tool = self.canvas.mapTool()
            if current_tool:
                # Check if the current tool belongs to this plugin
                # by checking if it's from our module
                tool_module = type(current_tool).__module__
                if tool_module and tool_module.startswith(__name__.split('.')[0]):
                    # Unset the tool to revert to default pan tool
                    self.canvas.unsetMapTool(current_tool)

        # Disconnect map tool signal if connected
        if hasattr(self, 'canvas') and self.canvas:
            try:
                self.canvas.mapToolSet.disconnect()
            except Exception:  # nosec B110
                pass

        # Close any open widgets/dialogs
        if hasattr(self, 'tools') and self.tools:
            try:
                self.tools.close()
            except Exception:  # nosec B110
                pass

        if hasattr(self, 'backup_widget_instance') and self.backup_widget_instance:
            try:
                self.backup_widget_instance.close()
            except Exception:  # nosec B110
                pass

        # Close master widget
        try:
            if master and master.isVisible():
                master.close()
        except Exception:  # nosec B110
            pass

        # Unregister processing provider safely
        if hasattr(self, 'provider') and self.provider:
            try:
                QgsApplication.processingRegistry().removeProvider(self.provider)
            except RuntimeError:
                # This can happen on QGIS shutdown if the provider is already deleted
                pass

        # Clean up all actions from menus
        if hasattr(self, 'action'):
            self.iface.removePluginMenu("&Gruhanaksha", self.action)
        if hasattr(self, 'action_master'):
            self.iface.removePluginMenu(u"&Gruhanaksha", self.action_master)
        if hasattr(self, 'action_atlasexport'):
            self.iface.removePluginMenu(
                "&Gruhanaksha", self.action_atlasexport)
        if hasattr(self, 'action_backup'):
            self.iface.removePluginMenu("&Gruhanaksha", self.action_backup)
        if hasattr(self, 'action_presentation'):
            self.iface.removePluginMenu("&Gruhanaksha", self.action_presentation)
        if hasattr(self, 'action_topology_checker'):
            self.iface.removePluginMenu("&Gruhanaksha", self.action_topology_checker)

        # Unregister all main window actions
        for action_name in ['action', 'action_master', 'action_advanced_line',
                            'action_tools', 'dropdown_button', 'action_atlasexport',
                            'action_backup', 'action_presentation', 'action_topology_checker']:
            if hasattr(self, action_name):
                try:
                    self.iface.unregisterMainWindowAction(
                        getattr(self, action_name))
                except Exception:  # nosec B110
                    pass

        # Clean up toolbar
        if hasattr(self, 'toolbar'):
            try:
                self.iface.mainWindow().removeToolBar(self.toolbar)
            except Exception:  # nosec B110
                pass
            del self.toolbar

        # Clean up backup plugin
        if hasattr(self, 'backup_plugin') and self.backup_plugin:
            try:
                self.backup_plugin.unload()  # Add cleanup method if exists
            except Exception:  # nosec B110
                pass
            self.backup_plugin = None

        # Set references to None to help garbage collection
        self.backup_widget_instance = None
        self.tools = None
        self.canvas = None
        self.provider = None

    def run_svamitva_algorithm(self):
        """Trigger custom logic or Processing algorithm"""
        if not self.ppm_dialog:
            from .ppm_dialog import PPMDialog
            self.ppm_dialog = PPMDialog(self.iface.mainWindow())
        self.ppm_dialog.show()
        self.ppm_dialog.raise_()
        self.ppm_dialog.activateWindow()

    def master_data(self):
        if QgsProject.instance().fileName():
            master.show()
        else:
            asksaveProject()

    def show_tools(self):
        if QgsProject.instance().fileName():
            self.tools.show()
        else:
            asksaveProject()

    def show_atlasexport(self):
        if QgsProject.instance().fileName():
            show_atlas_export_dialog()
        else:
            asksaveProject()

    def show_backup_widget(self):
        if QgsProject.instance().fileName():
            if not self.backup_plugin:
                self.backup_plugin = BackupPlugin(self.iface)
                # self.backup_widget_instance = self.backup_plugin.widget
                # self.backup_widget_instance.timerUpdated.connect(
                #     self.update_backup_timer)
                # self.backup_widget_instance.hideTimer.connect(
                #     self.hide_backup_timer)
            self.backup_plugin.show()
        else:
            asksaveProject()

    def show_presentation(self):
        if QgsProject.instance().fileName():
            dlg = PresentationDialog(self.iface.mainWindow())
            dlg.show()
            dlg.raise_()
            dlg.activateWindow()
        else:
            asksaveProject()

    def show_topology_checker(self):
        if QgsProject.instance().fileName():
            from .topology_checker import TopologyCheckerDialog
            dlg = TopologyCheckerDialog(iface=self.iface)
            dlg.show()
            dlg.raise_()
            dlg.activateWindow()
        else:
            asksaveProject()

    def setup_checkable_tool_action(self, action, tool_class, activate_function):
        """
        Set up a checkable action for a map tool with proper toggle behavior.

        Args:
            action: The QAction to make checkable
            tool_class: The class of the tool (e.g., ProfessionalLineTool)
            activate_function: Function to activate the tool
        """
        action.setCheckable(True)

        # Create a handler function for the action
        def toggle_tool():
            if action.isChecked():
                # Activate the tool
                tool = activate_function()
                if tool:
                    self.current_tool = self.canvas.mapTool()
                else:
                    action.setChecked(False)
            else:
                # Deactivate the tool - revert to default pan tool
                if self.canvas:
                    current_tool = self.canvas.mapTool()
                    if current_tool and isinstance(current_tool, tool_class):
                        self.canvas.unsetMapTool(current_tool)
                self.current_tool = None

        # Connect the action to the toggle handler
        action.triggered.connect(toggle_tool)

        # Monitor when map tool changes to update checkbox state
        def on_map_tool_changed(new_tool):
            """Update action checked state when map tool changes."""
            try:
                if self.canvas and action:
                    # Check if the new tool is an instance of our tool class
                    if isinstance(new_tool, tool_class):
                        action.setChecked(True)
                    else:
                        # If switched to a different tool, uncheck our action
                        action.setChecked(False)
            except (AttributeError, RuntimeError):
                # Canvas or action might be None during plugin unload
                pass

        # Connect to the map tool change signal
        if self.canvas:
            self.canvas.mapToolSet.connect(on_map_tool_changed)

    # def update_backup_timer(self, text):
    #     self.backup_timer_label.setText(text)
    #     self.backup_timer_label.setVisible(True)

    # def hide_backup_timer(self):
    #     self.backup_timer_label.setVisible(False)
