# -*- coding: utf-8 -*-
"""
RapidAPI Authentication Module for Zornade Italian Parcel Downloader
Native QGIS/Qt integration with dark mode support.

Version 1.5.2 - Improved Readability Design
- Increased window size to 720x600 pixels for better text visibility
- Enhanced spacing and margins throughout the interface
- Larger, more readable fonts (11pt for most content, 14pt for title)
- Improved button sizing and layout
- Better image scaling for visual guide
- More comfortable form inputs and labels
- Optimized for better user experience and readability
"""

import base64
import json
from typing import Optional, Dict, Tuple
from datetime import datetime
import os

from qgis.PyQt.QtCore import QObject, QSettings, Qt
from qgis.PyQt.QtWidgets import (
    QDialog, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, 
    QLineEdit, QMessageBox, QApplication, QGroupBox, QCheckBox,
    QProgressBar, QFormLayout, QSpacerItem, QSizePolicy, QFrame,
    QScrollArea, QWidget, QTextEdit, QDialogButtonBox, QGridLayout
)
from qgis.PyQt.QtGui import QDesktopServices, QFont, QPalette, QPixmap
from qgis.PyQt.QtCore import QUrl
import requests


class RapidAPIAuthenticator(QObject):
    """Simple credential storage and validation."""
    
    SETTINGS_GROUP = "ZornadeParcelDownloader"
    
    def __init__(self, parent=None):
        super().__init__(parent)
        self.settings = QSettings()
        
    def get_saved_credentials(self) -> Optional[Dict[str, str]]:
        """Retrieve saved credentials."""
        try:
            # Use the settings group prefix
            self.settings.beginGroup(self.SETTINGS_GROUP)
            
            encrypted_key = self.settings.value("rapidapi_key_enc")
            encrypted_token = self.settings.value("bearer_token_enc")
            
            self.settings.endGroup()
            
            if not encrypted_key or not encrypted_token:
                return None
                
            decrypted_key = self._decrypt(encrypted_key)
            decrypted_token = self._decrypt(encrypted_token)
            
            if not decrypted_key or not decrypted_token:
                return None
            
            # Get additional metadata
            self.settings.beginGroup(self.SETTINGS_GROUP)
            subscription_plan = self.settings.value("subscription_plan", "Saved")
            last_validated = self.settings.value("last_validated", "")
            is_working = self.settings.value("is_working", True, type=bool)
            self.settings.endGroup()
                
            return {
                'rapidapi_key': decrypted_key,
                'bearer_token': decrypted_token,
                'subscription_plan': subscription_plan,
                'auto_retrieved': True,
                'last_validated': last_validated,
                'is_working': is_working
            }
            
        except Exception as e:
            print(f"Error retrieving credentials: {e}")
            return None
    
    def save_credentials(self, credentials: Dict[str, str]) -> bool:
        """Save credentials securely."""
        try:
            if not credentials.get('rapidapi_key') or not credentials.get('bearer_token'):
                return False
                
            encrypted_key = self._encrypt(credentials['rapidapi_key'])
            encrypted_token = self._encrypt(credentials['bearer_token'])
            
            if not encrypted_key or not encrypted_token:
                return False
            
            # Use settings group for organization
            self.settings.beginGroup(self.SETTINGS_GROUP)
            
            self.settings.setValue("rapidapi_key_enc", encrypted_key)
            self.settings.setValue("bearer_token_enc", encrypted_token)
            self.settings.setValue("subscription_plan", credentials.get('subscription_plan', 'Manual'))
            self.settings.setValue("last_validated", datetime.now().strftime("%Y-%m-%d %H:%M"))
            self.settings.setValue("is_working", True)
            
            self.settings.endGroup()
            
            # Force sync to ensure data is written
            self.settings.sync()
            
            return True
            
        except Exception as e:
            print(f"Error saving credentials: {e}")
            return False
    
    def clear_credentials(self) -> bool:
        """Clear all saved credentials."""
        try:
            self.settings.beginGroup(self.SETTINGS_GROUP)
            
            keys = ['rapidapi_key_enc', 'bearer_token_enc', 'subscription_plan', 'last_validated', 'is_working', 'last_status_code', 'last_response_time']
            for key in keys:
                self.settings.remove(key)
            
            self.settings.endGroup()
            self.settings.sync()
            
            return True
        except Exception as e:
            print(f"Error clearing credentials: {e}")
            return False
    
    def update_credential_status(self, is_working: bool, validation_details: Dict = None):
        """Update credential working status based on API responses."""
        try:
            self.settings.beginGroup(self.SETTINGS_GROUP)
            
            # Update the working status
            self.settings.setValue("is_working", is_working)
            self.settings.setValue("last_validated", datetime.now().strftime("%Y-%m-%d %H:%M"))
            
            # Optionally store additional validation details
            if validation_details:
                self.settings.setValue("last_status_code", validation_details.get('status_code', 0))
                self.settings.setValue("last_response_time", validation_details.get('response_time', 0.0))
            
            self.settings.endGroup()
            
            # Sync settings to ensure they're saved
            self.settings.sync()
            
        except Exception as e:
            print(f"Error updating credential status: {e}")
    
    def validate_credentials(self, api_key: str, bearer_token: str) -> Tuple[bool, str]:
        """Validate credentials with API call."""
        if not api_key or not bearer_token:
            return False, "Both API key and bearer token are required"
            
        try:
            headers = {
                "X-RapidAPI-Key": api_key.strip(),
                "X-RapidAPI-Host": "enriched-cadastral-parcels-for-italy.p.rapidapi.com",
                "Authorization": f"Bearer {bearer_token.strip()}",
                "Content-Type": "application/json"
            }
            
            test_payload = {
                "queryType": "bbox", 
                "params": [11.0, 45.0, 11.005, 45.005]
            }
            
            response = requests.post(
                "https://enriched-cadastral-parcels-for-italy.p.rapidapi.com/functions/v1/get-parcels",
                headers=headers,
                json=test_payload,
                timeout=15
            )
            
            # Create validation details
            validation_details = {
                'status_code': response.status_code,
                'response_time': response.elapsed.total_seconds() if hasattr(response, 'elapsed') else 0.0
            }
            
            if response.status_code == 200:
                try:
                    data = response.json()
                    if data.get('success'):
                        count = len(data.get('data', []))
                        # Update status to working
                        self.update_credential_status(True, validation_details)
                        return True, f"Valid! Found {count} test parcels"
                    else:
                        # Update status to not working
                        self.update_credential_status(False, validation_details)
                        return False, f"API Error: {data.get('message', 'Unknown error')}"
                except:
                    self.update_credential_status(False, validation_details)
                    return False, "Invalid response from API"
            elif response.status_code == 401:
                self.update_credential_status(False, validation_details)
                return False, "Invalid credentials"
            elif response.status_code == 403:
                self.update_credential_status(False, validation_details)
                return False, "Access forbidden - check subscription"
            elif response.status_code == 429:
                # Rate limited but credentials might be valid
                self.update_credential_status(True, validation_details)
                return False, "Rate limited (credentials may be valid)"
            else:
                self.update_credential_status(False, validation_details)
                return False, f"HTTP {response.status_code}"
                
        except requests.exceptions.Timeout:
            return False, "Request timeout"
        except requests.exceptions.ConnectionError:
            return False, "Connection error"
        except Exception as e:
            return False, f"Error: {str(e)[:50]}"
    
    def _encrypt(self, text: str) -> str:
        """Simple encryption."""
        try:
            encoded = base64.b64encode(text.encode('utf-8')).decode('ascii')
            return f"ZRN_{encoded}_END"
        except:
            return ""
    
    def _decrypt(self, encrypted_text: str) -> str:
        """Simple decryption."""
        try:
            if encrypted_text.startswith("ZRN_") and encrypted_text.endswith("_END"):
                encoded = encrypted_text[4:-4]
                return base64.b64decode(encoded.encode('ascii')).decode('utf-8')
            return ""
        except:
            return ""


class SmartAuthDialog(QDialog):
    """Native QGIS-style credential management dialog with responsive design and scrolling."""
    
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("API Credentials Setup")
        self.setModal(True)
        
        # Set comfortable size with better readability
        # Increased size for better text visibility and less cramped layout
        FIXED_WIDTH = 720
        FIXED_HEIGHT = 600
        MIN_WIDTH = 650
        MIN_HEIGHT = 500
        MAX_WIDTH = 800
        MAX_HEIGHT = 700
        
        # Set fixed size to prevent oversizing
        self.resize(FIXED_WIDTH, FIXED_HEIGHT)
        
        # Set strict size constraints
        self.setMinimumSize(MIN_WIDTH, MIN_HEIGHT)
        self.setMaximumSize(MAX_WIDTH, MAX_HEIGHT)
        
        # Make dialog non-resizable to maintain predictable layout
        self.setFixedSize(FIXED_WIDTH, FIXED_HEIGHT)
        
        self.credentials = None
        self.authenticator = RapidAPIAuthenticator()
        
        self.setup_ui()
        self.load_existing_credentials()

    def setup_ui(self):
        """Setup responsive UI with better spacing and readable text."""
        # Main layout for the dialog
        main_layout = QVBoxLayout()
        main_layout.setContentsMargins(10, 10, 10, 10)  # More comfortable margins
        main_layout.setSpacing(10)  # Better spacing between elements
        
        # Readable title label
        title_label = QLabel("Zornade API Credentials")
        title_font = QFont()
        title_font.setPointSize(14)  # Larger title
        title_font.setBold(True)
        title_label.setFont(title_font)
        title_label.setAlignment(Qt.AlignCenter)
        title_label.setMaximumHeight(35)  # Adequate height
        main_layout.addWidget(title_label)
        
        # Create scroll area for the main content
        scroll_area = QScrollArea()
        scroll_area.setWidgetResizable(True)
        scroll_area.setFrameShape(QFrame.NoFrame)
        scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        
        # Content widget that goes inside the scroll area
        content_widget = QWidget()
        content_layout = QVBoxLayout(content_widget)
        content_layout.setContentsMargins(10, 10, 10, 10)  # Comfortable margins
        content_layout.setSpacing(12)  # Better spacing between sections
        
        # Add all content sections to the scrollable area
        self.status_group = self.create_status_section()
        content_layout.addWidget(self.status_group)
        
        guide_group = self.create_guide_section()
        content_layout.addWidget(guide_group)
        
        form_group = self.create_credentials_form()
        content_layout.addWidget(form_group)
        
        validation_group = self.create_validation_section()
        content_layout.addWidget(validation_group)
        
        help_group = self.create_help_section()
        content_layout.addWidget(help_group)
        
        # Add stretch to push content to top
        content_layout.addStretch()
        
        # Set the content widget to the scroll area
        scroll_area.setWidget(content_widget)
        
        # Add scroll area to main layout (takes most space)
        main_layout.addWidget(scroll_area, 1)  # stretch factor = 1
        
        # Button area with better spacing - always visible at bottom
        button_frame = QFrame()
        button_frame.setFrameShape(QFrame.StyledPanel)
        button_frame.setMaximumHeight(75)  # Slightly larger for better buttons
        button_frame.setMinimumHeight(75)  # Fixed height
        
        button_layout = QVBoxLayout(button_frame)
        button_layout.setContentsMargins(10, 8, 10, 8)  # Better margins
        
        # Standard dialog buttons in horizontal layout
        button_box = QDialogButtonBox()
        
        # Test button
        self.test_btn = QPushButton("Test Credentials")  # More descriptive text
        self.test_btn.setEnabled(False)
        self.test_btn.setMinimumHeight(35)  # Larger buttons
        button_box.addButton(self.test_btn, QDialogButtonBox.ActionRole)
        
        # Save button
        self.save_btn = QPushButton("Save & Use")
        self.save_btn.setEnabled(False)
        self.save_btn.setMinimumHeight(35)
        button_box.addButton(self.save_btn, QDialogButtonBox.ActionRole)
        
        # Clear button
        self.clear_btn = QPushButton("Clear Saved")
        self.clear_btn.setMinimumHeight(35)
        button_box.addButton(self.clear_btn, QDialogButtonBox.ResetRole)
        
        # Standard buttons
        button_box.addButton(QDialogButtonBox.Cancel)
        self.use_btn = button_box.addButton("Use Credentials", QDialogButtonBox.AcceptRole)
        self.use_btn.setEnabled(False)
        
        # Connect signals
        self.test_btn.clicked.connect(self.test_credentials)
        self.save_btn.clicked.connect(self.save_and_use)
        self.clear_btn.clicked.connect(self.clear_credentials)
        button_box.accepted.connect(self.accept_credentials)
        button_box.rejected.connect(self.reject)
        
        button_layout.addWidget(button_box)
        
        # Add button frame to main layout (fixed at bottom)
        main_layout.addWidget(button_frame)
        
        self.setLayout(main_layout)

    def create_status_section(self) -> QGroupBox:
        """Create readable status section."""
        group = QGroupBox("Current Status")
        layout = QVBoxLayout()
        layout.setSpacing(8)  # Better spacing
        
        self.status_label = QLabel("Loading status...")
        self.status_label.setWordWrap(True)
        self.status_label.setMinimumHeight(45)  # More height for readability
        self.status_label.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken)
        self.status_label.setMargin(10)  # More comfortable margin
        self.status_label.setStyleSheet("font-size: 11pt; padding: 5px;")  # Larger, readable font
        
        layout.addWidget(self.status_label)
        group.setLayout(layout)
        group.setMaximumHeight(90)  # Increased height
        return group
        
    def create_guide_section(self) -> QGroupBox:
        """Create readable setup guide section."""
        group = QGroupBox("Setup Guide")
        layout = QVBoxLayout()
        layout.setSpacing(10)  # Better spacing
        
        # More readable instructions
        instructions = QLabel("""<b>Quick Setup Steps:</b><br>
1. Click 'Open API Page' below → Subscribe to a plan<br>
2. Click any endpoint (e.g., 'get-parcels') to open test interface<br>
3. Copy credentials from cURL example as shown in image below""")
        instructions.setWordWrap(True)
        instructions.setMargin(8)  # Comfortable margin
        instructions.setStyleSheet("font-size: 11pt; line-height: 1.4;")  # Larger, readable font
        instructions.setMaximumHeight(80)  # More height for text
        layout.addWidget(instructions)
        
        # Visual guide image with better scaling
        howto_label = QLabel()
        howto_label.setAlignment(Qt.AlignCenter)
        
        # Load the howto.png image
        plugin_dir = os.path.dirname(__file__)
        howto_path = os.path.join(plugin_dir, 'howto.png')
        
        if os.path.exists(howto_path):
            pixmap = QPixmap(howto_path)
            if not pixmap.isNull():
                # Better scaling for readability
                max_width = 600  # Larger image
                max_height = 200  # More height for image
                
                # Calculate scaling to fit space
                width_scale = max_width / pixmap.width()
                height_scale = max_height / pixmap.height()
                scale_factor = min(width_scale, height_scale, 0.8)  # Allow larger scaling
                
                # Apply scaling
                scaled_width = int(pixmap.width() * scale_factor)
                scaled_height = int(pixmap.height() * scale_factor)
                scaled_pixmap = pixmap.scaled(scaled_width, scaled_height, Qt.KeepAspectRatio, Qt.SmoothTransformation)
                
                howto_label.setPixmap(scaled_pixmap)
                howto_label.setStyleSheet("""
                    QLabel {
                        border: 1px solid #ddd;
                        border-radius: 4px;
                        background-color: white;
                        padding: 8px;
                        margin: 8px 0px;
                    }
                """)
                howto_label.setMaximumHeight(max_height + 20)  # More space for image
                
        layout.addWidget(howto_label)
        
        # API page button with better size
        self.api_btn = QPushButton("Open API Page")
        self.api_btn.clicked.connect(self.open_api_page)
        self.api_btn.setMinimumHeight(40)  # Larger button
        self.api_btn.setStyleSheet("font-size: 11pt; padding: 5px 15px;")  # Better button styling
        layout.addWidget(self.api_btn)
        
        group.setLayout(layout)
        group.setMaximumHeight(350)  # More space for the section
        return group
        
    def create_credentials_form(self) -> QGroupBox:
        """Create readable credentials form."""
        group = QGroupBox("Enter Your Credentials")
        layout = QFormLayout()
        layout.setVerticalSpacing(10)  # Better spacing
        layout.setFieldGrowthPolicy(QFormLayout.ExpandingFieldsGrow)
        
        # Readable API Key section
        api_help = QLabel("X-RapidAPI-Key from cURL example:")
        api_help.setStyleSheet("color: gray; font-size: 11pt; font-weight: bold;")  # Larger, bold label
        
        self.api_key_input = QLineEdit()
        self.api_key_input.setPlaceholderText("e.g., 1234567890abcdef1234567890abcdef...")
        self.api_key_input.setEchoMode(QLineEdit.Password)
        self.api_key_input.textChanged.connect(self.on_input_changed)
        self.api_key_input.setMinimumHeight(30)  # Larger input field
        self.api_key_input.setStyleSheet("font-size: 11pt; padding: 5px;")  # Better input styling
        
        # Show/hide toggle for API key
        self.show_api_key = QCheckBox("Show key")
        self.show_api_key.toggled.connect(self.toggle_api_key_visibility)
        self.show_api_key.setStyleSheet("font-size: 11pt;")
        
        api_layout = QHBoxLayout()
        api_layout.addWidget(self.api_key_input, 1)
        api_layout.addWidget(self.show_api_key)
        
        layout.addRow(api_help)
        layout.addRow(api_layout)
        
        # Add some spacing
        layout.addRow(QLabel(""))  # Spacer
        
        # Readable Bearer Token section
        bearer_help = QLabel("Authorization Bearer token (without 'Bearer' prefix):")
        bearer_help.setStyleSheet("color: gray; font-size: 11pt; font-weight: bold;")
        
        self.bearer_input = QLineEdit()
        self.bearer_input.setPlaceholderText("e.g., eyJ0b2tlbiI6InRoaXNfaXNfYV90b2tlbiJ9...")
        self.bearer_input.setEchoMode(QLineEdit.Password)
        self.bearer_input.textChanged.connect(self.on_input_changed)
        self.bearer_input.setMinimumHeight(30)  # Larger input field
        self.bearer_input.setStyleSheet("font-size: 11pt; padding: 5px;")
        
        # Show/hide toggle for bearer token
        self.show_bearer = QCheckBox("Show token")
        self.show_bearer.toggled.connect(self.toggle_bearer_visibility)
        self.show_bearer.setStyleSheet("font-size: 11pt;")
        
        bearer_layout = QHBoxLayout()
        bearer_layout.addWidget(self.bearer_input, 1)
        bearer_layout.addWidget(self.show_bearer)
        
        layout.addRow(bearer_help)
        layout.addRow(bearer_layout)
        
        group.setLayout(layout)
        group.setMaximumHeight(160)  # More height for readability
        return group
        self.api_key_input.setEchoMode(QLineEdit.Password)
        self.api_key_input.textChanged.connect(self.on_input_changed)
        
        self.show_api_key = QCheckBox("Show API Key")
        self.show_api_key.toggled.connect(self.toggle_api_key_visibility)
        
        api_key_layout.addWidget(api_help)
        api_key_layout.addWidget(self.api_key_input)
        api_key_layout.addWidget(self.show_api_key)
        
        layout.addRow("RapidAPI Key:", api_key_layout)
        
        # Bearer Token section
        bearer_layout = QVBoxLayout()
        
        bearer_help = QLabel("From the cURL example: Copy the value after 'Bearer ' in the Authorization header")
        bearer_help.setStyleSheet("color: gray; font-size: 10pt;")
        bearer_help.setWordWrap(True)  # Allow text wrapping for narrow windows
        
        self.bearer_input = QLineEdit()
        self.bearer_input.setPlaceholderText("e.g., eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...")
        self.bearer_input.setEchoMode(QLineEdit.Password)
        self.bearer_input.textChanged.connect(self.on_input_changed)
        
        self.show_bearer = QCheckBox("Show Bearer Token")
        self.show_bearer.toggled.connect(self.toggle_bearer_visibility)
        
        bearer_layout.addWidget(bearer_help)
        bearer_layout.addWidget(self.bearer_input)
        bearer_layout.addWidget(self.show_bearer)
        
        layout.addRow("Bearer Token:", bearer_layout)
        
        group.setLayout(layout)
        return group
        
    def create_validation_section(self) -> QGroupBox:
        """Create readable validation section."""
        group = QGroupBox("Credential Validation")
        layout = QVBoxLayout()
        layout.setSpacing(8)  # Better spacing
        
        self.validation_label = QLabel("Enter both credentials above and click 'Test Credentials' to verify")
        self.validation_label.setWordWrap(True)
        self.validation_label.setMinimumHeight(40)  # More height
        self.validation_label.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken)
        self.validation_label.setMargin(10)  # Comfortable margin
        self.validation_label.setStyleSheet("font-size: 11pt; padding: 5px;")  # Larger font
        
        self.progress_bar = QProgressBar()
        self.progress_bar.setVisible(False)
        self.progress_bar.setMinimumHeight(25)  # Larger progress bar
        
        layout.addWidget(self.validation_label)
        layout.addWidget(self.progress_bar)
        
        group.setLayout(layout)
        group.setMaximumHeight(110)  # More height
        return group
        
    def create_help_section(self) -> QGroupBox:
        """Create readable help section."""
        group = QGroupBox("Common Issues & Troubleshooting")
        layout = QVBoxLayout()
        layout.setSpacing(8)  # Better spacing
        
        # More readable help text
        help_text = QLabel("""<b>Common issues and solutions:</b><br><br>
<b>• 401 Unauthorized Error:</b> Wrong credentials - double-check the cURL example<br>
<b>• 403 Forbidden Error:</b> No active subscription - make sure you subscribed to a plan<br>
<b>• Connection Error:</b> Check your internet connection<br>
<b>• Rate Limited Error:</b> API limits reached (credentials are likely valid, try again later)""")
        help_text.setWordWrap(True)
        help_text.setMargin(10)  # Comfortable margin
        help_text.setStyleSheet("font-size: 11pt; line-height: 1.3; padding: 8px;")  # Larger, readable font
        help_text.setMaximumHeight(120)  # More height for text
        
        layout.addWidget(help_text)
        
        group.setLayout(layout)
        group.setMaximumHeight(150)  # More overall height
        return group

    def load_existing_credentials(self):
        """Load existing credentials with native display."""
        saved_creds = self.authenticator.get_saved_credentials()
        
        if saved_creds:
            masked_key = f"{saved_creds['rapidapi_key'][:8]}...{saved_creds['rapidapi_key'][-4:]}"
            
            status_text = (
                f"✓ Found saved credentials: {masked_key}\n"
                f"Last validated: {saved_creds.get('last_validated', 'Unknown')}\n"
                f"Status: {'✓ Working' if saved_creds.get('is_working', True) else '⚠ Issues detected'}"
            )
            
            self.status_label.setText(status_text)
            
            # Load credentials into form fields for editing
            self.api_key_input.setText(saved_creds['rapidapi_key'])
            self.bearer_input.setText(saved_creds['bearer_token'])
            
            # Enable relevant buttons
            self.use_btn.setEnabled(True)
            self.clear_btn.setEnabled(True)
            self.test_btn.setEnabled(True)
            
            # If credentials are working, also enable save button
            if saved_creds.get('is_working', True):
                self.save_btn.setEnabled(True)
        else:
            self.status_label.setText("No saved credentials found\nPlease follow the setup guide below to get started")
            self.clear_btn.setEnabled(False)

    def open_api_page(self):
        """Open API page in browser."""
        QDesktopServices.openUrl(QUrl("https://rapidapi.com/abigdatacompany-abigdatacompany-default/api/enriched-cadastral-parcels-for-italy"))

    def on_input_changed(self):
        """Handle input changes."""
        has_both = bool(self.api_key_input.text().strip() and self.bearer_input.text().strip())
        self.test_btn.setEnabled(has_both)
        
        api_key = self.api_key_input.text().strip()
        bearer_token = self.bearer_input.text().strip()
        
        if api_key and len(api_key) < 20:
            self.validation_label.setText("API key seems too short (should be 30+ characters)")
        elif bearer_token and len(bearer_token) < 10:
            self.validation_label.setText("Bearer token seems too short")
        elif has_both:
            self.validation_label.setText("Both credentials entered - click 'Test' to verify")
        else:
            self.validation_label.setText("Enter both credentials above and click 'Test' to verify")

    def toggle_api_key_visibility(self, checked):
        """Toggle API key visibility."""
        self.api_key_input.setEchoMode(QLineEdit.Normal if checked else QLineEdit.Password)
        
    def toggle_bearer_visibility(self, checked):
        """Toggle bearer token visibility."""
        self.bearer_input.setEchoMode(QLineEdit.Normal if checked else QLineEdit.Password)

    def test_credentials(self):
        """Test credentials with native UI feedback."""
        api_key = self.api_key_input.text().strip()
        bearer_token = self.bearer_input.text().strip()
        
        if not api_key or not bearer_token:
            self.validation_label.setText("Please enter both credentials")
            return
        
        self.progress_bar.setVisible(True)
        self.progress_bar.setRange(0, 0)
        self.test_btn.setText("Testing...")
        self.test_btn.setEnabled(False)
        
        QApplication.processEvents()
        
        is_valid, message = self.authenticator.validate_credentials(api_key, bearer_token)
        
        self.progress_bar.setVisible(False)
        self.test_btn.setText("Test Credentials")
        self.test_btn.setEnabled(True)
        
        if is_valid:
            self.validation_label.setText(f"✓ {message} - Credentials are working!")
            # Use system palette for success color
            palette = self.validation_label.palette()
            palette.setColor(QPalette.WindowText, palette.color(QPalette.Dark))
            self.validation_label.setPalette(palette)
            self.save_btn.setEnabled(True)
            self.use_btn.setEnabled(True)
        else:
            self.validation_label.setText(f"✗ {message}")
            # Use system palette for error color
            palette = self.validation_label.palette()
            palette.setColor(QPalette.WindowText, palette.color(QPalette.BrightText))
            self.validation_label.setPalette(palette)
            self.save_btn.setEnabled(False)

    def save_and_use(self):
        """Save credentials and use them."""
        api_key = self.api_key_input.text().strip()
        bearer_token = self.bearer_input.text().strip()
        
        if not api_key or not bearer_token:
            QMessageBox.warning(self, "Missing Data", "Please enter both API key and bearer token.")
            return
        
        credentials = {
            'rapidapi_key': api_key,
            'bearer_token': bearer_token,
            'subscription_plan': 'Manual Entry'
        }
        
        if self.authenticator.save_credentials(credentials):
            QMessageBox.information(self, "Success", "Credentials saved successfully!\nYou can now use the plugin to download parcels.")
            self.credentials = credentials  # Set for immediate use
            self.load_existing_credentials()  # Refresh the display
            self.accept()  # Close dialog with acceptance
        else:
            QMessageBox.critical(self, "Error", "Failed to save credentials. Please try again.")

    def clear_credentials(self):
        """Clear saved credentials with confirmation."""
        reply = QMessageBox.question(
            self, "Clear Credentials", 
            "Are you sure you want to clear all saved credentials?\nYou'll need to enter them again next time.",
            QMessageBox.Yes | QMessageBox.No
        )
        
        if reply == QMessageBox.Yes:
            if self.authenticator.clear_credentials():
                QMessageBox.information(self, "Cleared", "Credentials cleared successfully.")
                self.api_key_input.clear()
                self.bearer_input.clear()
                self.validation_label.setText("Enter both credentials above and click 'Test' to verify")
                # Reset to default system palette
                self.validation_label.setPalette(self.palette())
                self.save_btn.setEnabled(False)
                self.use_btn.setEnabled(False)
                self.load_existing_credentials()

    def accept_credentials(self):
        """Accept with current credentials."""
        api_key = self.api_key_input.text().strip()
        bearer_token = self.bearer_input.text().strip()
        
        if not api_key or not bearer_token:
            QMessageBox.warning(self, "Missing Credentials", "Please enter both credentials before continuing.")
            return
        
        self.credentials = {
            'rapidapi_key': api_key,
            'bearer_token': bearer_token,
            'subscription_plan': 'Manual Entry',
            'auto_retrieved': True
        }
        
        self.accept()

    def get_credentials(self) -> Optional[Dict[str, str]]:
        """Get credentials."""
        return self.credentials


# Backward compatibility aliases
BrowserAuthDialog = SmartAuthDialog
CredentialExtractionDialog = SmartAuthDialog
