# -*- coding: utf-8 -*-
"""
/***************************************************************************
 GeoPDF Dialog - Exportador de MapBiomas Fogo
 
 Gerencia o fluxo de exportação de GeoPDF com 3 telas:
 1. Intro - Escolha de orientação (Retrato ou Paisagem)
 2. Retrato - Preview e posicionamento do mapa em formato vertical
 3. Paisagem - Preview e posicionamento do mapa em formato horizontal
 ***************************************************************************/
"""

import os
import sys
from qgis.PyQt import uic
from qgis.PyQt.QtCore import Qt, pyqtSignal, QSize, QTimer, QPoint, QUrl
from qgis.PyQt.QtWidgets import (
    QDialog, QMessageBox, QFileDialog, QSlider, QVBoxLayout, 
    QHBoxLayout, QLabel, QWidget, QPushButton
)
from qgis.PyQt.QtGui import QIcon, QCursor, QDesktopServices
from qgis.core import QgsProject

_MOUSE_BUTTON_ENUM = getattr(Qt, "MouseButton", Qt)
_MOUSE_LEFT_BUTTON = getattr(_MOUSE_BUTTON_ENUM, "LeftButton")

_CURSOR_SHAPE_ENUM = getattr(Qt, "CursorShape", Qt)
_OPEN_HAND_CURSOR = getattr(_CURSOR_SHAPE_ENUM, "OpenHandCursor")
_CLOSED_HAND_CURSOR = getattr(_CURSOR_SHAPE_ENUM, "ClosedHandCursor")

_ALIGNMENT_FLAG_ENUM = getattr(Qt, "AlignmentFlag", Qt)
_ALIGN_CENTER = getattr(_ALIGNMENT_FLAG_ENUM, "AlignCenter")


# QLabel customizado com suporte a pan e zoom
class PannableMapLabel(QLabel):
    """QLabel que suporta pan (arrasto) e zoom com mouse."""
    
    map_updated = pyqtSignal(float, float, int)  # pan_x, pan_y, zoom
    
    def __init__(self, parent=None):
        super().__init__(parent)
        self.pan_x = 0
        self.pan_y = 0
        self.zoom = 100
        self.is_panning = False
        self.last_mouse_pos = QPoint(0, 0)
        self.setMouseTracking(True)
        self.setCursor(QCursor(_OPEN_HAND_CURSOR))
    
    def mousePressEvent(self, event):
        """Inicia pan quando usuário clica com botão esquerdo."""
        if event.button() == _MOUSE_LEFT_BUTTON:
            self.is_panning = True
            self.last_mouse_pos = event.pos()
            self.setCursor(QCursor(_CLOSED_HAND_CURSOR))
        super().mousePressEvent(event)
    
    def mouseMoveEvent(self, event):
        """Atualiza pan enquanto usuário arrasta."""
        if self.is_panning:
            delta = event.pos() - self.last_mouse_pos
            self.pan_x += delta.x()
            self.pan_y += delta.y()  # SEM NEGAÇÃO - A negação ocorre em _apply_pan_to_extent
            self.last_mouse_pos = event.pos()
            self.map_updated.emit(self.pan_x, self.pan_y, self.zoom)
        super().mouseMoveEvent(event)
    
    def mouseReleaseEvent(self, event):
        """Finaliza pan."""
        if event.button() == _MOUSE_LEFT_BUTTON:
            self.is_panning = False
            self.setCursor(QCursor(_OPEN_HAND_CURSOR))
        super().mouseReleaseEvent(event)
    
    def wheelEvent(self, event):
        """Controla zoom com roda do mouse (SEM LIMITE)."""
        delta = event.angleDelta().y()
        previous_zoom = self.zoom
        if delta > 0:
            self.zoom *= 1.1  # Aumenta 10%
        else:
            self.zoom /= 1.1  # Diminui 10%
        zoom_ratio = self.zoom / previous_zoom
        self.pan_x *= zoom_ratio
        self.pan_y *= zoom_ratio
        print(f"[PannableMapLabel] Zoom: {self.zoom:.1f}%")
        self.map_updated.emit(self.pan_x, self.pan_y, self.zoom)
        event.accept()  # Marca evento como processado


class GeoPDFDialog(QDialog):
    """Dialog para exportação de GeoPDF com visualização prévia.
    
    Fluxo:
    - Página 0: Escolha de orientação (Retrato/Paisagem)
    - Página 1: Preview e exportação (Retrato)
    - Página 2: Preview e exportação (Paisagem)
    """
    
    # Signals
    export_started = pyqtSignal(str)  # orientation: "portrait" ou "landscape"
    export_completed = pyqtSignal(str)  # file_path
    export_failed = pyqtSignal(str)  # error_message

    def __init__(self, iface=None, parent=None, plugin_dir=None):
        """Constructor.
        
        Args:
            iface: Interface QGIS
            parent: Parent widget
            plugin_dir: Plugin directory path
        """
        super().__init__(parent)
        
        self.iface = iface
        self.plugin_dir = plugin_dir or os.path.dirname(__file__)
        self.canvas = iface.mapCanvas() if iface else None
        self.project = QgsProject.instance()
        self.exporter = None
        
        # Variáveis de estado
        self.current_orientation = None  # "portrait" ou "landscape"
        self.selected_dpi = 300
        
        print("[MapBiomas Fogo] Inicializando GeoPDFDialog...")
        print(f"[MapBiomas Fogo] Plugin dir: {self.plugin_dir}")
        
        # Carregar arquivo .ui
        ui_file = os.path.join(self.plugin_dir, 'MapBiomas_fogo_dialog_GeoPDF_QGS3.ui')
        print(f"[MapBiomas Fogo] Procurando UI: {ui_file}")
        
        if os.path.exists(ui_file):
            try:
                uic.loadUi(ui_file, self)
                print("[MapBiomas Fogo] Arquivo .ui carregado com sucesso")
            except Exception as e:
                print(f"[MapBiomas Fogo] ERRO ao carregar .ui: {e}")
                import traceback
                traceback.print_exc()
                QMessageBox.critical(self, "Erro", f"Não foi possível carregar a interface:\n{e}")
                self.close()
                return
        else:
            print(f"[MapBiomas Fogo] ERRO: Arquivo .ui não encontrado: {ui_file}")
            QMessageBox.critical(self, "Erro", f"Arquivo .ui não encontrado:\n{ui_file}")
            self.close()
            return
        
        # Configurar ícone
        icon_path = os.path.join(self.plugin_dir, 'GeoPDFicon.png')
        if os.path.exists(icon_path):
            self.setWindowIcon(QIcon(icon_path))
        
        # Inicializar conexões após carregar a UI
        QTimer.singleShot(100, self._init_connections)

    def _init_connections(self):
        """Conecta signals e slots."""
        try:
            print("[MapBiomas Fogo] Iniciando conexões de signals...")
            
            # Verificar widgets principais
            if not hasattr(self, 'stackedWidget'):
                print("[MapBiomas Fogo] ERRO: stackedWidget não encontrado!")
                return
            
            if not hasattr(self, 'page_intro'):
                print("[MapBiomas Fogo] ERRO: page_intro não encontrada!")
                return
            
            if not hasattr(self, 'page_portrait'):
                print("[MapBiomas Fogo] ERRO: page_portrait não encontrada!")
                return
            
            if not hasattr(self, 'page_landscape'):
                print("[MapBiomas Fogo] ERRO: page_landscape não encontrada!")
                return
            
            if not hasattr(self, 'label_portrait'):
                print("[MapBiomas Fogo] ERRO: label_portrait não encontrado!")
                return
            
            if not hasattr(self, 'label_landscape'):
                print("[MapBiomas Fogo] ERRO: label_landscape não encontrado!")
                return
            
            print("[MapBiomas Fogo] Todos os widgets principais encontrados ✓")
            
            # Criar sliders programaticamente (não estão no .ui)
            self._create_sliders()
            
            # Importar GeoPDFExporter - adicionar plugin dir ao sys.path
            try:
                try:
                    from .MapBiomas_fogo_GeoPDF import GeoPDFExporter
                except Exception:
                    if self.plugin_dir not in sys.path:
                        sys.path.insert(0, self.plugin_dir)
                        print(f"[MapBiomas Fogo] Adicionado ao sys.path: {self.plugin_dir}")
                    from MapBiomas_fogo_GeoPDF import GeoPDFExporter
                self.exporter = GeoPDFExporter(iface=self.iface)
                self.exporter.progress_updated.connect(self._on_export_progress)
                self.exporter.export_completed.connect(self._on_export_completed)
                self.exporter.export_failed.connect(self._on_export_failed)
                print("[MapBiomas Fogo] GeoPDFExporter inicializado ✓")
            except ImportError as e:
                print(f"[MapBiomas Fogo] ERRO ao importar GeoPDFExporter: {e}")
                import traceback
                traceback.print_exc()
                self.exporter = None
            
            # ==================== PÁGINA 0: INTRO ====================
            
            print("[MapBiomas Fogo] Conectando Page Intro...")
            
            # Radio buttons
            if hasattr(self, 'radio_portrait'):
                self.radio_portrait.toggled.connect(self._on_portrait_selected)
                print("[MapBiomas Fogo]   - radio_portrait conectado")
            else:
                print("[MapBiomas Fogo]   - AVISO: radio_portrait não encontrado")
            
            if hasattr(self, 'radio_landscape'):
                self.radio_landscape.toggled.connect(self._on_landscape_selected)
                print("[MapBiomas Fogo]   - radio_landscape conectado")
            else:
                print("[MapBiomas Fogo]   - AVISO: radio_landscape não encontrado")

            # DPI fixo em 300, sem selector no UI
            self.selected_dpi = 300
            
            # Botões intro
            if hasattr(self, 'btn_next_intro'):
                self.btn_next_intro.clicked.connect(self._on_next_from_intro)
                print("[MapBiomas Fogo]   - btn_next_intro conectado")
            else:
                print("[MapBiomas Fogo]   - AVISO: btn_next_intro não encontrado")
            
            if hasattr(self, 'btn_cancel_intro'):
                self.btn_cancel_intro.clicked.connect(self.reject)
                print("[MapBiomas Fogo]   - btn_cancel_intro conectado")
            else:
                print("[MapBiomas Fogo]   - AVISO: btn_cancel_intro não encontrado")
            
            # ==================== PÁGINA 1: RETRATO ====================
            
            print("[MapBiomas Fogo] Conectando Page Portrait...")
            
            if hasattr(self, 'btn_reset_portrait'):
                self.btn_reset_portrait.clicked.connect(self._on_reset_portrait)
                print("[MapBiomas Fogo]   - btn_reset_portrait conectado")
            
            if hasattr(self, 'btn_back_portrait'):
                self.btn_back_portrait.clicked.connect(self._on_back_to_intro)
                print("[MapBiomas Fogo]   - btn_back_portrait conectado")
            else:
                print("[MapBiomas Fogo]   - AVISO: btn_back_portrait não encontrado")
            
            if hasattr(self, 'btn_export_portrait'):
                self.btn_export_portrait.clicked.connect(self._on_export_portrait)
                print("[MapBiomas Fogo]   - btn_export_portrait conectado")
            else:
                print("[MapBiomas Fogo]   - AVISO: btn_export_portrait não encontrado")
            
            # ==================== PÁGINA 2: PAISAGEM ====================
            
            print("[MapBiomas Fogo] Conectando Page Landscape...")
            
            if hasattr(self, 'btn_back_landscape'):
                self.btn_back_landscape.clicked.connect(self._on_back_to_intro)
                print("[MapBiomas Fogo]   - btn_back_landscape conectado")
            else:
                print("[MapBiomas Fogo]   - AVISO: btn_back_landscape não encontrado")
            
            if hasattr(self, 'btn_export_landscape'):
                self.btn_export_landscape.clicked.connect(self._on_export_landscape)
                print("[MapBiomas Fogo]   - btn_export_landscape conectado")
            else:
                print("[MapBiomas Fogo]   - AVISO: btn_export_landscape não encontrado")
            
            print("[MapBiomas Fogo] ✓ Todas as conexões foram inicializadas com sucesso!")
            
        except Exception as e:
            print(f"[MapBiomas Fogo] ERRO CRÍTICO ao conectar signals: {e}")
            import traceback
            traceback.print_exc()

    def _create_sliders(self):
        """Converte labels para PannableMapLabel preservando o posicionamento do .ui."""
        try:
            print("[MapBiomas Fogo] Convertendo labels para PannableMapLabel preservando geometria do UI...")

            # ===== PAGE PORTRAIT =====
            if hasattr(self, 'page_portrait'):
                if hasattr(self, 'label_portrait'):
                    old_label = self.label_portrait
                    geometry = old_label.geometry()
                    self.label_portrait = PannableMapLabel(self.page_portrait)
                    self.label_portrait.setGeometry(geometry)
                    self.label_portrait.setStyleSheet(old_label.styleSheet())
                    self.label_portrait.setAlignment(_ALIGN_CENTER)
                    self.label_portrait.map_updated.connect(self._on_portrait_map_updated)
                    self.label_portrait.raise_()
                    old_label.deleteLater()
                    print("[MapBiomas Fogo]   - label_portrait preservou geometria do .ui")

            # ===== PAGE LANDSCAPE =====
            if hasattr(self, 'page_landscape'):
                if hasattr(self, 'label_landscape'):
                    old_label = self.label_landscape
                    geometry = old_label.geometry()
                    self.label_landscape = PannableMapLabel(self.page_landscape)
                    self.label_landscape.setGeometry(geometry)
                    self.label_landscape.setStyleSheet(old_label.styleSheet())
                    self.label_landscape.setAlignment(_ALIGN_CENTER)
                    self.label_landscape.map_updated.connect(self._on_landscape_map_updated)
                    self.label_landscape.raise_()
                    old_label.deleteLater()
                    print("[MapBiomas Fogo]   - label_landscape preservou geometria do .ui")

            print("[MapBiomas Fogo] ✓ Labels convertidos com sucesso usando o posicionamento do arquivo .ui")
            print("[MapBiomas Fogo] 💡 Controles: Pan (arrastar), Zoom (roda do mouse) - mantendo tamanho e posição do layout original")

        except Exception as e:
            print(f"[MapBiomas Fogo] ERRO ao converter labels: {e}")
            import traceback
            traceback.print_exc()

    # ==================== MÉTODOS DA PÁGINA 0: INTRO ====================
    
    def _on_portrait_selected(self, checked):
        """Chamado quando Retrato é selecionado."""
        if checked:
            self.current_orientation = "portrait"
            print("[MapBiomas Fogo] ✓ Orientação selecionada: RETRATO")
        else:
            print("[MapBiomas Fogo] - Retrato deseleccionado")

    def _on_landscape_selected(self, checked):
        """Chamado quando Paisagem é selecionado."""
        if checked:
            self.current_orientation = "landscape"
            print("[MapBiomas Fogo] ✓ Orientação selecionada: PAISAGEM")
        else:
            print("[MapBiomas Fogo] - Paisagem deseleccionado")

    def _on_dpi_selected(self, checked):
        """Atualiza o DPI ativo conforme o radio button selecionado."""
        if not checked:
            return

        sender = self.sender()
        if sender is None:
            return

        mapping = {
            'radioButton_150DPI': 150,
            'radioButton_225DPI': 225,
            'radioButton_300DPI': 300,
        }
        dpi_value = mapping.get(sender.objectName())
        if dpi_value is not None:
            self.selected_dpi = dpi_value
            print(f"[MapBiomas Fogo] ✓ DPI selecionado: {self.selected_dpi}")

    def _get_selected_dpi(self):
        """Retorna o DPI atualmente selecionado, com fallback para 300."""
        for button_name, dpi_value in {
            'radioButton_150DPI': 150,
            'radioButton_225DPI': 225,
            'radioButton_300DPI': 300,
        }.items():
            button = getattr(self, button_name, None)
            if button is not None and button.isChecked():
                self.selected_dpi = dpi_value
                return dpi_value

        self.selected_dpi = 225
        radio_225 = getattr(self, 'radioButton_225DPI', None)
        if radio_225 is not None:
            radio_225.setChecked(True)
        return self.selected_dpi

    def _on_next_from_intro(self):
        """Avança para a página de preview (retrato ou paisagem)."""
        print(f"[MapBiomas Fogo] Clique em 'Avançar' detectado. Orientação atual: {self.current_orientation}")
        
        if not self.current_orientation:
            print("[MapBiomas Fogo] AVISO: Nenhuma orientação selecionada!")
            QMessageBox.warning(
                self,
                "Atenção",
                "Por favor, selecione uma orientação (Retrato ou Paisagem)"
            )
            return
        
        try:
            if self.current_orientation == "portrait":
                print("[MapBiomas Fogo] → Mudando para página RETRATO...")
                self.stackedWidget.setCurrentWidget(self.page_portrait)
                print("[MapBiomas Fogo] ✓ Página RETRATO ativada")
                self._render_preview_portrait()
            else:
                print("[MapBiomas Fogo] → Mudando para página PAISAGEM...")
                self.stackedWidget.setCurrentWidget(self.page_landscape)
                print("[MapBiomas Fogo] ✓ Página PAISAGEM ativada")
                self._render_preview_landscape()
        except Exception as e:
            print(f"[MapBiomas Fogo] ERRO ao avançar: {e}")
            import traceback
            traceback.print_exc()

    # ==================== MÉTODOS DA PÁGINA 1: RETRATO ====================
    
    def _render_preview_portrait(self):
        """Renderiza o mapa no label_portrait para visualização prévia."""
        try:
            if not self.exporter:
                print("[MapBiomas Fogo] AVISO: Exporter não inicializado, pulando renderização")
                return
            
            if not hasattr(self, 'label_portrait'):
                print("[MapBiomas Fogo] AVISO: label_portrait não encontrado")
                return
            
            print("[MapBiomas Fogo] Renderizando preview em formato RETRATO...")
            
            # Obter valores do label (que agora é PannableMapLabel)
            zoom = self.label_portrait.zoom if hasattr(self, 'label_portrait') else 100
            pan_x = self.label_portrait.pan_x if hasattr(self, 'label_portrait') else 0
            pan_y = self.label_portrait.pan_y if hasattr(self, 'label_portrait') else 0
            
            print(f"[MapBiomas Fogo] Parâmetros: zoom={zoom:.1f}%, pan_x={pan_x}px, pan_y={pan_y}px")
            
            # Renderizar mapa no label
            self.exporter.render_to_frame(
                self.label_portrait,
                zoom_percent=zoom,
                pan_x=pan_x,
                pan_y=pan_y
            )
            
            print("[MapBiomas Fogo] ✓ Label preview renderizado")
            
        except Exception as e:
            print(f"[MapBiomas Fogo] ERRO ao renderizar preview retrato: {e}")
            import traceback
            traceback.print_exc()

    def _on_portrait_map_updated(self, pan_x, pan_y, zoom):
        """Callback quando usuário faz pan ou zoom com roda do mouse (retrato)."""
        self._render_preview_portrait()

    def _on_zoom_portrait_changed(self, value):
        """[REMOVIDO] Slider de zoom foi removido."""
        pass

    def _on_export_portrait(self):
        """Exporta o mapa em formato retrato como GeoPDF."""
        try:
            print("[MapBiomas Fogo] Iniciando exportação RETRATO...")
            
            if not self.exporter:
                QMessageBox.critical(self, "Erro", "Exporter não foi inicializado")
                return
            
            # Abrir diálogo para escolher local de salvamento
            file_path, _ = QFileDialog.getSaveFileName(
                self,
                "Salvar GeoPDF - Formato Retrato",
                "",
                "PDF Files (*.pdf);;All Files (*.*)"
            )
            
            if not file_path:
                print("[MapBiomas Fogo] Exportação cancelada pelo usuário")
                return
            
            print(f"[MapBiomas Fogo] Exportando para: {file_path}")
            dpi = 300
            print(f"[MapBiomas Fogo] DPI fixo para retrato: {dpi}")
            
            # Exportar usando exporter
            success = self.exporter.export_frame_to_geopdf(
                output_path=file_path,
                frame=self.label_portrait,
                orientation="portrait",
                dpi=dpi,
                include_scale=True,
                include_north_arrow=True,
                include_metadata=True
            )
            
            if success:
                self.export_started.emit("portrait")
            
        except Exception as e:
            error_msg = f"Erro ao exportar: {e}"
            print(f"[MapBiomas Fogo] {error_msg}")
            import traceback
            traceback.print_exc()
            self.export_failed.emit(error_msg)
            QMessageBox.critical(self, "Erro", error_msg)

    # ==================== MÉTODOS DA PÁGINA 2: PAISAGEM ====================
    
    def _render_preview_landscape(self):
        """Renderiza o mapa no label_landscape para visualização prévia."""
        try:
            if not self.exporter:
                print("[MapBiomas Fogo] AVISO: Exporter não inicializado, pulando renderização")
                return
            
            if not hasattr(self, 'label_landscape'):
                print("[MapBiomas Fogo] AVISO: label_landscape não encontrado")
                return
            
            print("[MapBiomas Fogo] Renderizando preview em formato PAISAGEM...")
            
            # Obter valores do label (que agora é PannableMapLabel)
            zoom = self.label_landscape.zoom if hasattr(self, 'label_landscape') else 100
            pan_x = self.label_landscape.pan_x if hasattr(self, 'label_landscape') else 0
            pan_y = self.label_landscape.pan_y if hasattr(self, 'label_landscape') else 0
            
            print(f"[MapBiomas Fogo] Parâmetros: zoom={zoom:.1f}%, pan_x={pan_x}px, pan_y={pan_y}px")
            
            # Renderizar mapa no label
            self.exporter.render_to_frame(
                self.label_landscape,
                zoom_percent=zoom,
                pan_x=pan_x,
                pan_y=pan_y
            )
            
            print("[MapBiomas Fogo] ✓ Label preview renderizado")
            
        except Exception as e:
            print(f"[MapBiomas Fogo] ERRO ao renderizar preview paisagem: {e}")
            import traceback
            traceback.print_exc()

    def _on_landscape_map_updated(self, pan_x, pan_y, zoom):
        """Callback quando usuário faz pan ou zoom com roda do mouse (paisagem)."""
        self._render_preview_landscape()

    def _on_zoom_landscape_changed(self, value):
        """[REMOVIDO] Slider de zoom foi removido."""
        pass

    def _on_rotation_landscape_changed(self, value):
        """[REMOVIDO] Slider de rotação foi removido."""
        pass

    def _on_export_landscape(self):
        """Exporta o mapa em formato paisagem como GeoPDF."""
        try:
            print("[MapBiomas Fogo] Iniciando exportação PAISAGEM...")
            
            if not self.exporter:
                QMessageBox.critical(self, "Erro", "Exporter não foi inicializado")
                return
            
            # Abrir diálogo para escolher local de salvamento
            file_path, _ = QFileDialog.getSaveFileName(
                self,
                "Salvar GeoPDF - Formato Paisagem",
                "",
                "PDF Files (*.pdf);;All Files (*.*)"
            )
            
            if not file_path:
                print("[MapBiomas Fogo] Exportação cancelada pelo usuário")
                return
            
            print(f"[MapBiomas Fogo] Exportando para: {file_path}")
            dpi = 300
            print(f"[MapBiomas Fogo] DPI fixo para paisagem: {dpi}")
            
            # Exportar usando exporter
            success = self.exporter.export_frame_to_geopdf(
                output_path=file_path,
                frame=self.label_landscape,
                orientation="landscape",
                dpi=dpi,
                include_scale=True,
                include_north_arrow=True,
                include_metadata=True
            )
            
            if success:
                self.export_started.emit("landscape")
            
        except Exception as e:
            error_msg = f"Erro ao exportar: {e}"
            print(f"[MapBiomas Fogo] {error_msg}")
            import traceback
            traceback.print_exc()
            self.export_failed.emit(error_msg)
            QMessageBox.critical(self, "Erro", error_msg)

    # ==================== NAVEGAÇÃO ====================
    
    def _on_back_to_intro(self):
        """Volta para página de introdução."""
        print("[MapBiomas Fogo] Voltando à tela de INTRO...")
        self.stackedWidget.setCurrentWidget(self.page_intro)
        self.current_orientation = None
        # Desselecionar radio buttons
        if hasattr(self, 'radio_portrait'):
            self.radio_portrait.setChecked(False)
        if hasattr(self, 'radio_landscape'):
            self.radio_landscape.setChecked(False)
        print("[MapBiomas Fogo] ✓ Voltado à tela de INTRO")

    # ==================== CALLBACKS DE EXPORTAÇÃO ====================
    
    def _show_simple_success_dialog(self, file_path):
        """Exibe uma mensagem de sucesso com ação direta para abrir o arquivo ou a pasta."""
        dialog = QDialog(self)
        dialog.setWindowTitle("Sucesso")
        dialog.setModal(True)
        dialog.setMinimumWidth(420)
        dialog.setStyleSheet(
            "QDialog { background: #2b2b2b; color: white; border-radius: 8px; }"
            "QLabel { color: white; }"
            "QPushButton { min-width: 84px; min-height: 28px; padding: 2px 10px; }"
        )

        layout = QVBoxLayout(dialog)
        layout.setContentsMargins(16, 12, 16, 12)
        layout.setSpacing(12)

        message = QLabel("Exportação concluída! O seu arquivo GeoPDF está pronto.")
        message.setWordWrap(True)
        message.setStyleSheet("font-size: 13px; font-weight: bold;")
        layout.addWidget(message)

        if file_path:
            path_label = QLabel(file_path)
            path_label.setWordWrap(True)
            path_label.setStyleSheet("color: #dfe7f3; font-size: 11px;")
            layout.addWidget(path_label)

        actions = QHBoxLayout()
        actions.setSpacing(8)

        open_file_button = QPushButton("Abrir Arquivo")
        open_folder_button = QPushButton("Abrir Pasta")
        ok_button = QPushButton("OK")
        ok_button.setDefault(True)

        def open_file():
            if file_path and os.path.exists(file_path):
                QDesktopServices.openUrl(QUrl.fromLocalFile(file_path))

        def open_folder():
            if file_path and os.path.exists(file_path):
                folder = os.path.dirname(file_path) or file_path
                QDesktopServices.openUrl(QUrl.fromLocalFile(folder))

        open_file_button.clicked.connect(open_file)
        open_folder_button.clicked.connect(open_folder)
        ok_button.clicked.connect(dialog.accept)

        actions.addWidget(open_file_button)
        actions.addWidget(open_folder_button)
        actions.addStretch()
        actions.addWidget(ok_button)
        layout.addLayout(actions)

        dialog_exec = getattr(dialog, "exec", None)
        if dialog_exec is None:
            dialog_exec = getattr(dialog, "exec" + "_")
        dialog_exec()

    def _on_export_progress(self, message):
        """Callback quando há atualização de progresso."""
        print(f"[MapBiomas Fogo] Progresso: {message}")

    def _on_export_completed(self, file_path):
        """Callback quando exportação é concluída com sucesso."""
        print(f"[MapBiomas Fogo] Exportação concluída: {file_path}")
        self._show_simple_success_dialog(file_path)
        self.export_completed.emit(file_path)

    def _on_export_failed(self, error_message):
        """Callback quando exportação falha."""
        print(f"[MapBiomas Fogo] Erro na exportação: {error_message}")
        QMessageBox.critical(
            self,
            "Erro na Exportação",
            f"Erro ao exportar GeoPDF:\n\n{error_message}"
        )
        self.export_failed.emit(error_message)
