"""Export management module for SecInterp main dialog.

This module handles exporting preview data to various file formats
(PNG, PDF, SVG) and orchestrating data exports (SHP, CSV) via ExportService.
"""

from __future__ import annotations

from pathlib import Path
from typing import TYPE_CHECKING, Any, Optional

from qgis.core import QgsMapSettings, QgsProject, QgsRectangle, QgsSettings
from qgis.PyQt.QtCore import QSize
from qgis.PyQt.QtGui import QColor
from qgis.PyQt.QtWidgets import QFileDialog

from sec_interp.core.performance_metrics import MetricsCollector, PerformanceTimer
from sec_interp.core.services.export_service import ExportService
from sec_interp.exporters import get_exporter
from sec_interp.logger_config import get_logger

from .main_dialog_config import DialogConfig, DialogDefaults


if TYPE_CHECKING:
    from .main_dialog import SecInterpDialog

logger = get_logger(__name__)


class ExportManager:
    """Manages all export operations for the dialog.

    This class handles exporting preview data to various file formats
    (PNG, PDF, SVG) and orchestrating data exports (SHP, CSV) via ExportService.
    """

    def __init__(self, dialog: sec_interp.gui.main_dialog.SecInterpDialog):
        """Initialize export manager with reference to parent dialog.

        Args:
            dialog: The :class:`sec_interp.gui.main_dialog.SecInterpDialog` instance
        """
        self.dialog = dialog
        self.metrics = MetricsCollector()
        self.export_service = ExportService(self.dialog.plugin_instance.controller)

    def export_preview(self) -> bool:
        """Export the current preview to a file.

        Returns:
            True if export successful, False otherwise
        """
        self.metrics.clear()

        try:
            with PerformanceTimer("Total Preview Export Time", self.metrics):
                if not self.dialog.current_canvas:
                    self.dialog.messagebar.pushMessage(
                        "Export Error",
                        "No preview available to export. Generate a preview first.",
                        level=2,
                    )
                    return False

                canvas = self.dialog.current_canvas
                layers = canvas.layers()
                if not layers:
                    self.dialog.messagebar.pushMessage(
                        "Export Error", "No layers to export.", level=2
                    )
                    return False

                # Format selection
                settings = QgsSettings()
                last_dir = settings.value("SecInterp/lastExportDir", "", type=str)
                default_path = (
                    str(Path(last_dir) / "preview.png") if last_dir else "preview.png"
                )

                file_filter = (
                    "PNG Image (*.png);;"
                    "JPEG Image (*.jpg *.jpeg);;"
                    "PDF Document (*.pdf);;"
                    "SVG Vector (*.svg)"
                )

                output_path, _selected_filter = QFileDialog.getSaveFileName(
                    self.dialog, "Export Preview", default_path, file_filter
                )

                if not output_path:
                    return False

                output_path = Path(output_path)
                settings.setValue("SecInterp/lastExportDir", str(output_path.parent))

                # Determine dimensions and DPI
                ext = output_path.suffix.lower()
                width = self.dialog.preview_widget.canvas.width()
                height = self.dialog.preview_widget.canvas.height()
                dpi = 96

                if ext in [".png", ".jpg", ".jpeg"]:
                    width *= 3
                    height *= 3
                    dpi = 300

                # Prepare settings
                export_params = {
                    "width": width,
                    "height": height,
                    "dpi": dpi,
                    "background_color": QColor(255, 255, 255),
                    "legend_renderer": getattr(
                        self.dialog.plugin_instance, "preview_renderer", None
                    ),
                    "title": "Section Interpretation Preview",
                    "description": "Generated by SecInterp QGIS Plugin",
                    "extent": canvas.extent(),
                }

                map_settings = self.export_service.get_map_settings(
                    layers,
                    export_params["extent"],
                    self.dialog.preview_widget.canvas.size(),
                    export_params["background_color"],
                )

                # Special size override for rasters
                if ext in [".png", ".jpg", ".jpeg"]:
                    map_settings.setOutputSize(QSize(width, height))

                # Execute export
                exporter = get_exporter(ext, export_params)
                success = exporter.export(output_path, map_settings)

                if success:
                    self.dialog.messagebar.pushMessage(
                        "Success", f"Preview exported to {output_path.name}", level=3
                    )
                else:
                    self.dialog.messagebar.pushMessage(
                        "Error",
                        f"Failed to export preview to {output_path.name}",
                        level=1,
                    )

                if DialogConfig.LOG_DETAILED_METRICS:
                    logger.info(f"Preview Performance: {self.metrics.get_summary()}")

                return success

        except Exception as e:
            logger.error(f"Preview export failed: {e}", exc_info=True)
            self.dialog.messagebar.pushMessage("Error", str(e), level=1)
            return False

    def export_data(self) -> bool:
        """Orchestrate full data export (SHP/CSV) to the selected folder.

        Returns:
            True if successful, False otherwise
        """
        try:
            # 1. Validate inputs via dialog
            inputs = self.dialog.plugin_instance._get_and_validate_inputs()
            if not inputs:
                return False

            output_folder = Path(inputs["output_path"])

            # 2. Generate data via controller
            self.dialog.preview_widget.results_text.setPlainText(
                "✓ Generating data for export..."
            )
            profile_data, geol_data, struct_data, drillhole_data, _ = (
                self.dialog.plugin_instance.controller.generate_profile_data(inputs)
            )

            if not profile_data:
                self.dialog.messagebar.pushMessage(
                    "Error", "No profile data generated.", level=1
                )
                return False

            # 3. Export via service
            result_msg = self.export_service.export_data(
                output_folder,
                inputs,
                profile_data,
                geol_data,
                struct_data,
                drillhole_data,
            )

            self.dialog.preview_widget.results_text.setPlainText("\n".join(result_msg))
        except Exception as e:
            logger.error(f"Data export failed: {e}", exc_info=True)
            self.dialog.messagebar.pushMessage("Export Error", str(e), level=1)
            return False
        else:
            return True
