# -*- coding: utf-8 -*-
"""
/***************************************************************************
 CSVGeometryExportPlugin
                                 A QGIS plugin
 Export layers as CSV with custom geometry column names
                              -------------------
        begin                : 2025-07-13
        copyright            : (C) 2025 by Mirjan Ali Sha
        email                : mastools.help@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.                                   *
 *                                                                         *
 ***************************************************************************/
"""

import os
from qgis.PyQt.QtCore import QSettings, QTranslator, QCoreApplication, QObject, QEvent
from qgis.PyQt.QtGui import QIcon
from qgis.PyQt.QtWidgets import QAction, QMessageBox, QToolBar
from qgis.core import QgsLayerTree, QgsMapLayerType, QgsVectorLayer, QgsMessageLog, Qgis
from qgis.utils import iface
from .export_dialog import CSVGeometryExportDialog


class LayerTreeContextMenuManager(QObject):
    """Manages context menu additions to layer tree"""

    def __init__(self, parent=None):
        super().__init__(parent)
        self.view = iface.layerTreeView()
        self.menuProvider = self.view.menuProvider()
        self.providers = []
        self.patch()
        self.view.viewport().installEventFilter(self)

    def patch(self):
        """Patch the menu provider to add custom actions"""
        if not hasattr(self.menuProvider, "_original_createContextMenu"):
            self.menuProvider._original_createContextMenu = self.menuProvider.createContextMenu
        if not hasattr(self.menuProvider, "providers"):
            self.menuProvider.providers = []
        self.menuProvider.createContextMenu = self.createContextMenu

    def createContextMenu(self, event=None):
        """Create context menu with custom actions"""
        menu = self.menuProvider._original_createContextMenu()

        # Add our custom providers
        for provider in self.menuProvider.providers:
            try:
                provider(menu, event)
            except TypeError:
                provider(menu)
        return menu

    def addProvider(self, provider):
        """Add a context menu provider"""
        if callable(provider) and provider not in self.menuProvider.providers:
            self.providers.append(provider)
            self.menuProvider.providers.append(provider)

    def cleanup(self):
        """Remove event filter and providers on unload"""
        try:
            self.view.viewport().removeEventFilter(self)
        except Exception as e:
            QgsMessageLog.logMessage(f"Event filter cleanup warning: {str(e)}", "CSVGeometryExport", Qgis.MessageLevel.Warning)
            
        for provider in self.providers:
            if provider in self.menuProvider.providers:
                self.menuProvider.providers.remove(provider)
        
        self.providers = []

    def eventFilter(self, obj, event):
        """Filter context menu events"""
        if event.type() == QEvent.Type.ContextMenu:
            menu = self.menuProvider.createContextMenu(event)
            if menu:
                menu.exec(self.view.mapToGlobal(event.pos()))
                return True
        return False


class CSVGeometryExportPlugin:
    """QGIS Plugin Implementation."""

    def __init__(self, iface):
        """Constructor.

        :param iface: An interface instance that will be passed to this class
            which provides the hook by which you can manipulate the QGIS
            application at run time.
        :type iface: QgsInterface
        """
        # Save reference to the QGIS interface
        self.iface = iface

        # Initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)

        # Initialize locale
        locale = QSettings().value('locale/userLocale')[0:2]
        locale_path = os.path.join(
            self.plugin_dir,
            'i18n',
            'CSVGeometryExportPlugin_{}.qm'.format(locale))

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

        # UPDATED: Menu and toolbar identifiers following
        # clear_null_geometry.py pattern
        self.menu = self.tr(u'&MAS Vector Processing')
        self.toolbar = None
        self.actions = []
        self.context_menu_manager = None
        self.plugin_action = None

    def tr(self, message):
        """Get the translation for a string using Qt translation API."""
        return QCoreApplication.translate('CSVGeometryExportPlugin', message)

    def initGui(self):
        """Create the menu entries and toolbar icons inside the QGIS GUI."""

        # UPDATED: Check if the toolbar already exists; if not, create it
        # This follows the exact pattern from clear_null_geometry.py
        self.toolbar = self.iface.mainWindow().findChild(
            QToolBar, 'MASVectorProcessingToolbar')
        if self.toolbar is None:
            self.toolbar = self.iface.addToolBar(
                self.tr('MAS Vector Processing'))
            self.toolbar.setObjectName('MASVectorProcessingToolbar')

        # Create icon path
        icon_path = os.path.join(self.plugin_dir, 'icon.png')
        if not os.path.exists(icon_path):
            # Create a default icon if missing
            self.create_default_icon(icon_path)

        # Create main action
        self.plugin_action = QAction(
            QIcon(icon_path),
            self.tr(u'Export as CSV with Geometry'),
            self.iface.mainWindow()
        )
        self.plugin_action.triggered.connect(self.run)
        self.plugin_action.setStatusTip(
            self.tr(u'Export vector layer as CSV with custom geometry column'))
        self.plugin_action.setWhatsThis(
            self.tr(u'Export vector layer as CSV with custom geometry column'))
        self.plugin_action.setEnabled(True)

        # UPDATED: Add the action under the "MAS Vector Processing" entry of
        # the Vector menu
        self.iface.addPluginToVectorMenu(self.menu, self.plugin_action)

        # Add the action to the toolbar
        self.toolbar.addAction(self.plugin_action)

        # Store action
        self.actions.append(self.plugin_action)

        # Setup context menu
        self.setup_context_menu()

    def create_default_icon(self, icon_path):
        """Create a default icon if none exists with blue color #323FFF"""
        try:
            from qgis.PyQt.QtGui import QPixmap, QPainter, QColor, QFont, QPen, QBrush
            from qgis.PyQt.QtCore import Qt

            # Create 24x24 pixel icon
            pixmap = QPixmap(24, 24)
            pixmap.fill(Qt.GlobalColor.transparent)

            painter = QPainter(pixmap)
            painter.setRenderHint(QPainter.Antialiasing)

            # Use blue color #323FFF
            blue_color = QColor("#323FFF")

            # Draw background with blue color
            painter.setBrush(QBrush(blue_color))
            painter.setPen(QPen(blue_color, 1))
            painter.drawRoundedRect(2, 2, 20, 20, 3, 3)

            # Draw CSV text in white for good contrast
            painter.setPen(QPen(QColor(255, 255, 255)))
            painter.setFont(QFont("Arial", 7, QFont.Bold))
            painter.drawText(4, 15, "CSV")

            painter.end()
            pixmap.save(icon_path)

        except Exception as e:
            print(f"Warning: Could not create default icon: {e}")

    def setup_context_menu(self):
        """Setup context menu for layer tree"""
        try:
            self.context_menu_manager = LayerTreeContextMenuManager()
            self.context_menu_manager.addProvider(self.add_context_menu_action)
        except Exception as e:
            print(f"Warning: Could not setup context menu: {e}")

    def add_context_menu_action(self, menu, event=None):
        """Add context menu action to layer tree - positioned before Styles group"""
        try:
            current_node = self.iface.layerTreeView().currentNode()
            if QgsLayerTree.isLayer(current_node):
                layer = current_node.layer()
                if layer and layer.type() == QgsMapLayerType.VectorLayer:
                    # Create our custom action
                    csv_export_action = QAction(
                        'Export as CSV with Geometry', menu)
                    csv_export_action.triggered.connect(
                        lambda: self.run_context(layer))

                    # Find the position to insert - after Export group, before
                    # Styles
                    actions = menu.actions()
                    insert_position = len(actions)  # Default to end

                    # Look for Styles menu or action
                    for i, action in enumerate(actions):
                        action_text = action.text().lower()
                        # Look for "Styles" text or menu
                        if 'style' in action_text or action_text == 'styles':
                            insert_position = i
                            break
                        # Also check if it's a submenu with styles
                        if action.menu():
                            submenu_title = action.menu().title().lower()
                            if 'style' in submenu_title:
                                insert_position = i
                                break

                    # Insert our action at the found position
                    if insert_position < len(actions):
                        # Add separator before our action
                        separator = menu.insertSeparator(
                            actions[insert_position])
                        # Insert our action
                        menu.insertAction(separator, csv_export_action)
                        # Add separator after our action
                        menu.insertSeparator(actions[insert_position])
                    else:
                        # If no Styles found, add at the end with separator
                        menu.addSeparator()
                        menu.addAction(csv_export_action)

        except Exception as e:
            print(f"Warning: Could not add context menu action: {e}")

    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""
        # Remove actions from menu and toolbar
        for action in self.actions:
            self.iface.removePluginVectorMenu(self.menu, action)
            if self.toolbar:
                self.toolbar.removeAction(action)

        # Toolbar cleanup
        if self.toolbar:
            # Check if toolbar is empty and remove it if no other plugins are using it
            remaining_actions = [a for a in self.toolbar.actions() if not a.isSeparator()]
            if len(remaining_actions) == 0:
                self.iface.mainWindow().removeToolBar(self.toolbar)
            self.toolbar = None

        # Clear actions list
        self.actions = []

        # Clean up context menu manager
        if self.context_menu_manager:
            self.context_menu_manager.cleanup()
            self.context_menu_manager = None

    def run(self):
        """Run method that performs all the real work"""
        # Get the currently selected layer
        layer = self.iface.activeLayer()

        if not layer:
            iface.messageBar().pushMessage(
                "Warning",
                "No layer selected. Please select a vector layer first.",
                Qgis.MessageLevel.Warning,
                3
            )
            return

        if not isinstance(layer, QgsVectorLayer):
            iface.messageBar().pushMessage(
                "Warning",
                "Selected layer is not a vector layer. Please select a vector layer.",
                Qgis.MessageLevel.Warning,
                3
            )
            return

        # Check if layer has features
        if layer.featureCount() == 0:
            iface.messageBar().pushMessage(
                "Warning",
                "Selected layer has no features to export.",
                Qgis.MessageLevel.Warning,
                3
            )
            return

        self.run_dialog(layer)

    def run_context(self, layer):
        """Run method from context menu with specific layer"""
        if not layer or not isinstance(layer, QgsVectorLayer):
            iface.messageBar().pushMessage(
                "Error",
                "Invalid layer selected for export.",
                Qgis.MessageLevel.Critical,
                3
            )
            return

        self.run_dialog(layer)

    def run_dialog(self, layer):
        """Show the export dialog for the given layer"""
        try:
            # Create and show the export dialog
            dialog = CSVGeometryExportDialog(layer, self.iface.mainWindow())

            # Execute dialog
            result = dialog.exec()

            # Note: Success handling is now done within the dialog itself
            # to provide better user feedback with file location details

        except ImportError as e:
            QMessageBox.critical(
                self.iface.mainWindow(),
                "Plugin Error",
                f"Could not import export dialog module:\n{str(e)}\n\n"
                f"Please ensure all plugin files are properly installed."
            )
        except Exception as e:
            QMessageBox.critical(
                self.iface.mainWindow(),
                "Plugin Error",
                f"Error opening export dialog:\n{str(e)}\n\n"
                f"Please check the QGIS message log for more details."
            )

            # Also log to QGIS message log
            QgsMessageLog.logMessage(
                f"CSV Geometry Export Plugin Error: {str(e)}",
                "Plugins",
                Qgis.MessageLevel.Critical
            )
