"""
Testing widget for sending test messages.
"""

from typing import Optional
from datetime import datetime
from PyQt5.QtWidgets import (
    QWidget,
    QVBoxLayout,
    QHBoxLayout,
    QFormLayout,
    QLineEdit,
    QPushButton,
    QComboBox,
    QTextEdit,
    QGroupBox,
    QListWidget,
    QListWidgetItem,
    QMessageBox,
    QSplitter,
    QFileDialog,
    QTabWidget,
    QCheckBox,
)
from PyQt5.QtCore import Qt, pyqtSignal, QThread, pyqtSlot

from ...services import get_logger
from ...services.db import get_session
from ...services.translation import _, get_translation_manager
from ...models import Account, Recipient, MessageTemplate
from ...core.telethon_client import TelegramClientManager
from ...core.spintax import SpintaxProcessor


class TestMessageWorker(QThread):
    """Worker thread for sending test messages."""

    finished = pyqtSignal(dict)  # result dict with success, message, details
    progress = pyqtSignal(str)  # progress message

    def __init__(
        self,
        account_id: int,
        recipient_identifier: str,
        message_text: str,
        media_path: Optional[str] = None,
        use_spintax: bool = False,
    ):
        super().__init__()
        self.account_id = account_id
        self.recipient_identifier = recipient_identifier
        self.message_text = message_text
        self.media_path = media_path
        self.use_spintax = use_spintax
        self.logger = get_logger()
        self.client_manager = TelegramClientManager()
        self.spintax_processor = SpintaxProcessor()

    def run(self):
        """Send test message."""
        import asyncio

        async def async_send():
            try:
                self.progress.emit("Connecting to Telegram...")

                # Get account from database
                with get_session() as session:
                    account = session.get(Account, self.account_id)
                    if not account:
                        self.finished.emit(
                            {
                                "success": False,
                                "message": "Account not found",
                                "details": f"Account ID {self.account_id} not found in database",
                            }
                        )
                        return

                    # Add account to client manager if not already added
                    if not self.client_manager.get_client(self.account_id):
                        self.progress.emit("Adding account to client manager...")
                        await self.client_manager.add_account(account)

                    # Process spintax if enabled
                    processed_message = self.message_text
                    if self.use_spintax and self.message_text:
                        try:
                            spintax_result = self.spintax_processor.process(self.message_text)
                            processed_message = spintax_result.text
                            self.logger.debug(f"Spintax processed: '{processed_message}'")
                        except Exception as e:
                            self.logger.warning(f"Error processing spintax: {e}")

                    # Send message
                    self.progress.emit("Sending message...")
                    result = await self.client_manager.send_message(
                        account_id=self.account_id,
                        peer=self.recipient_identifier,
                        text=processed_message,
                        media_path=self.media_path,
                    )

                    if result.get("success", False):
                        self.finished.emit(
                            {
                                "success": True,
                                "message": "Message sent successfully",
                                "details": (
                                    f"Sent to {self.recipient_identifier} at "
                                    f"{datetime.now().strftime('%H:%M:%S')}"
                                ),
                                "media_path": self.media_path,
                            }
                        )
                    else:
                        self.finished.emit(
                            {
                                "success": False,
                                "message": "Failed to send message",
                                "details": result.get("error", "Unknown error"),
                                "media_path": self.media_path,
                            }
                        )

            except Exception as e:
                self.logger.error(f"Error sending test message: {e}")
                self.finished.emit(
                    {
                        "success": False,
                        "message": "Error sending message",
                        "details": str(e),
                        "media_path": self.media_path,
                    }
                )
            finally:
                # Clean up
                try:
                    if self.client_manager.get_client(self.account_id):
                        await self.client_manager.remove_account(self.account_id)
                except Exception:
                    pass

        # Run the async function
        asyncio.run(async_send())


class TestingWidget(QWidget):
    """Widget for testing message sending."""

    def __init__(self, parent=None):
        super().__init__(parent)
        self.logger = get_logger()
        self.spintax_processor = SpintaxProcessor()
        self.translation_manager = get_translation_manager()
        self.recent_tests = []  # Store recent tests in memory

        # Connect language change signal
        self.translation_manager.language_changed.connect(self.on_language_changed)

        self.setup_ui()
        self.load_data()
        # Ensure translations are applied after UI setup
        self.update_ui_translations()

    def setup_ui(self):
        """Set up the UI."""
        layout = QVBoxLayout(self)

        # Create splitter for form and results
        splitter = QSplitter(Qt.Horizontal)
        layout.addWidget(splitter)

        # Left side - Test Form
        form_widget = QWidget()
        form_layout = QVBoxLayout(form_widget)

        # Test Form Group
        self.form_group = QGroupBox(_("testing.send_test_message"))
        form_group_layout = QFormLayout(self.form_group)

        # Account selection
        self.account_combo = QComboBox()
        self.account_combo.setPlaceholderText(_("testing.select_account"))
        form_group_layout.addRow(_("common.account") + ":", self.account_combo)

        # Recipient selection
        self.recipient_combo = QComboBox()
        self.recipient_combo.setPlaceholderText(_("testing.select_recipient"))
        form_group_layout.addRow(_("testing.recipient") + ":", self.recipient_combo)

        # Message template selection
        self.template_combo = QComboBox()
        self.template_combo.setPlaceholderText(_("testing.select_template_optional"))
        self.template_combo.currentTextChanged.connect(self.on_template_changed)
        form_group_layout.addRow(_("common.template") + ":", self.template_combo)

        # Message text
        self.message_edit = QTextEdit()
        self.message_edit.setPlaceholderText(_("testing.enter_message_text"))
        self.message_edit.setMaximumHeight(100)
        form_group_layout.addRow(_("common.message") + ":", self.message_edit)

        # Media section with tabs for file and URL
        media_widget = QWidget()
        media_layout = QVBoxLayout(media_widget)
        media_layout.setContentsMargins(0, 0, 0, 0)

        # Media tabs
        self.media_tabs = QTabWidget()
        self.media_tabs.setMaximumHeight(80)

        # File tab
        file_tab = QWidget()
        file_layout = QHBoxLayout(file_tab)
        file_layout.setContentsMargins(5, 5, 5, 5)

        self.media_file_edit = QLineEdit()
        self.media_file_edit.setPlaceholderText(_("testing.no_file_selected"))
        self.media_file_edit.setReadOnly(True)
        file_layout.addWidget(self.media_file_edit)

        self.choose_file_button = QPushButton(_("testing.choose_file"))
        self.choose_file_button.clicked.connect(self.choose_media_file)
        self.choose_file_button.setStyleSheet("""
            QPushButton {
                background-color: #2196F3;
                color: white;
                border: none;
                padding: 8px 12px;
                font-size: 12px;
                border-radius: 3px;
            }
            QPushButton:hover {
                background-color: #1976D2;
            }
        """)
        file_layout.addWidget(self.choose_file_button)

        self.media_tabs.addTab(file_tab, _("testing.file"))

        # URL tab
        url_tab = QWidget()
        url_layout = QHBoxLayout(url_tab)
        url_layout.setContentsMargins(5, 5, 5, 5)

        self.media_url_edit = QLineEdit()
        self.media_url_edit.setPlaceholderText(_("testing.paste_media_url"))
        url_layout.addWidget(self.media_url_edit)

        self.media_tabs.addTab(url_tab, _("testing.url"))

        media_layout.addWidget(self.media_tabs)
        form_group_layout.addRow(_("testing.media") + ":", media_widget)

        form_layout.addWidget(self.form_group)

        # Spintax checkbox
        self.spintax_checkbox = QCheckBox(_("testing.enable_spintax"))
        self.spintax_checkbox.setToolTip(_("testing.spintax_tooltip"))
        form_layout.addWidget(self.spintax_checkbox)

        # Send button
        self.send_button = QPushButton(_("testing.send_test_message"))
        self.send_button.clicked.connect(self.send_test_message)
        self.send_button.setStyleSheet("""
            QPushButton {
                background-color: #4CAF50;
                color: white;
                border: none;
                padding: 10px;
                font-size: 14px;
                font-weight: bold;
                border-radius: 5px;
            }
            QPushButton:hover {
                background-color: #45a049;
            }
            QPushButton:disabled {
                background-color: #cccccc;
                color: #666666;
            }
        """)
        form_layout.addWidget(self.send_button)

        form_layout.addStretch()
        splitter.addWidget(form_widget)

        # Right side - Recent Tests
        results_widget = QWidget()
        results_layout = QVBoxLayout(results_widget)

        # Recent Tests Group
        self.tests_group = QGroupBox(_("testing.recent_tests"))
        tests_layout = QVBoxLayout(self.tests_group)

        # Clear button
        clear_layout = QHBoxLayout()
        self.clear_button = QPushButton(_("testing.clear_tests"))
        self.clear_button.clicked.connect(self.clear_tests)
        self.clear_button.setStyleSheet("""
            QPushButton {
                background-color: #f44336;
                color: white;
                border: none;
                padding: 8px;
                font-size: 12px;
                border-radius: 3px;
            }
            QPushButton:hover {
                background-color: #da190b;
            }
        """)
        clear_layout.addWidget(self.clear_button)
        clear_layout.addStretch()
        tests_layout.addLayout(clear_layout)

        # Tests list
        self.tests_list = QListWidget()
        self.tests_list.setStyleSheet("""
            QListWidget {
                background-color: #1a1a1a;
                color: white;
                border: 1px solid #404040;
                border-radius: 5px;
                padding: 5px;
            }
            QListWidget::item {
                padding: 8px;
                border-bottom: 1px solid #333333;
            }
            QListWidget::item:selected {
                background-color: #0078d4;
            }
        """)
        tests_layout.addWidget(self.tests_list)

        results_layout.addWidget(self.tests_group)
        splitter.addWidget(results_widget)

        # Set splitter proportions
        splitter.setSizes([400, 300])

    def choose_media_file(self):
        """Open file dialog to choose media file."""
        # Telegram supported media file extensions
        supported_extensions = [
            "Images (*.jpg *.jpeg *.png *.gif *.bmp *.webp *.tiff *.ico)",
            "Videos (*.mp4 *.avi *.mov *.wmv *.flv *.webm *.mkv *.3gp *.m4v)",
            "Audio (*.mp3 *.wav *.ogg *.m4a *.aac *.flac *.wma)",
            "Documents (*.pdf *.doc *.docx *.txt *.rtf *.odt)",
            "All Files (*)",
        ]

        file_path, _selected_filter = QFileDialog.getOpenFileName(
            self, _("testing.choose_media_file"), "", ";;".join(supported_extensions)
        )

        if file_path:
            self.media_file_edit.setText(file_path)
            # Switch to file tab if not already there
            self.media_tabs.setCurrentIndex(0)
            self.logger.info(f"Selected media file: {file_path}")

    def validate_media_url(self, url: str) -> bool:
        """Validate if URL is a supported media URL."""
        if not url:
            return True  # Empty URL is valid (no media)

        # Basic URL validation
        if not (url.startswith("http://") or url.startswith("https://")):
            return False

        # Check for common media file extensions in URL
        media_extensions = [
            ".jpg",
            ".jpeg",
            ".png",
            ".gif",
            ".bmp",
            ".webp",
            ".tiff",
            ".ico",
            ".mp4",
            ".avi",
            ".mov",
            ".wmv",
            ".flv",
            ".webm",
            ".mkv",
            ".3gp",
            ".m4v",
            ".mp3",
            ".wav",
            ".ogg",
            ".m4a",
            ".aac",
            ".flac",
            ".wma",
            ".pdf",
            ".doc",
            ".docx",
            ".txt",
            ".rtf",
            ".odt",
        ]

        url_lower = url.lower()
        return any(ext in url_lower for ext in media_extensions)

    def load_data(self):
        """Load accounts, recipients, and templates."""
        try:
            with get_session() as session:
                # Load accounts
                accounts = session.query(Account).filter(Account.deleted_at.is_(None)).all()
                self.account_combo.clear()
                self.logger.info(f"Loading {len(accounts)} accounts for testing")
                for account in accounts:
                    status_icon = "🟢" if account.status == "ONLINE" else "🔴"
                    self.account_combo.addItem(f"{status_icon} {account.phone_number}", account.id)
                    self.logger.debug(f"Added account: {account.phone_number} (ID: {account.id})")

                # Load recipients
                recipients = session.query(Recipient).filter(Recipient.deleted_at.is_(None)).all()
                self.recipient_combo.clear()
                for recipient in recipients:
                    if recipient.recipient_type == "USER":
                        icon = "👤"
                        name = (
                            recipient.username
                            or recipient.first_name
                            or recipient.phone_number
                            or f"User {recipient.id}"
                        )
                    elif recipient.recipient_type == "GROUP":
                        icon = "👥"
                        name = (
                            recipient.group_title
                            or recipient.group_username
                            or f"Group {recipient.id}"
                        )
                    else:  # CHANNEL
                        icon = "📢"
                        name = (
                            recipient.group_title
                            or recipient.group_username
                            or f"Channel {recipient.id}"
                        )

                    identifier = recipient.get_identifier()
                    self.recipient_combo.addItem(f"{icon} {name} ({identifier})", identifier)

                # Load templates
                templates = (
                    session.query(MessageTemplate)
                    .filter(MessageTemplate.deleted_at.is_(None))
                    .all()
                )
                self.template_combo.clear()
                self.template_combo.addItem("None", None)
                for template in templates:
                    self.template_combo.addItem(template.name, template.id)

        except Exception as e:
            self.logger.error(f"Error loading data: {e}")
            QMessageBox.critical(self, "Error", f"Failed to load data: {e}")

    def on_template_changed(self, template_name):
        """Handle template selection change."""
        if template_name == "None":
            return

        try:
            template_id = self.template_combo.currentData()
            if not template_id:
                return

            with get_session() as session:
                template = session.get(MessageTemplate, template_id)
                if template:
                    # Use spintax text if available, otherwise use body
                    message_text = template.spintax_text or template.body
                    self.message_edit.setPlainText(message_text)

                    # Show template info
                    self.logger.info(f"Loaded template: {template.name}")

        except Exception as e:
            self.logger.error(f"Error loading template: {e}")

    def send_test_message(self):
        """Send test message."""
        try:
            # Validate inputs
            account_id = self.account_combo.currentData()
            recipient_identifier = self.recipient_combo.currentData()
            message_text = self.message_edit.toPlainText().strip()

            self.logger.debug(
                "Account ID: %s, Recipient: %s, Message: %s...",
                account_id,
                recipient_identifier,
                message_text[:50],
            )
            self.logger.debug(f"Account combo current index: {self.account_combo.currentIndex()}")
            self.logger.debug(f"Account combo count: {self.account_combo.count()}")

            # Check if account is selected by index instead of data
            if not account_id and self.account_combo.currentIndex() >= 0:
                # Try to get account ID from the current index
                account_id = self.account_combo.itemData(self.account_combo.currentIndex())
                self.logger.debug(f"Retrieved account ID from index: {account_id}")

            if not account_id:
                self.logger.warning("No account selected")
                QMessageBox.warning(
                    self, _("testing.validation_error"), _("testing.please_select_account")
                )
                return

            # Check if recipient is selected by index instead of data
            if not recipient_identifier and self.recipient_combo.currentIndex() >= 0:
                # Try to get recipient identifier from the current index
                recipient_identifier = self.recipient_combo.itemData(
                    self.recipient_combo.currentIndex()
                )
                self.logger.debug(
                    f"Retrieved recipient identifier from index: {recipient_identifier}"
                )

            if not recipient_identifier:
                QMessageBox.warning(
                    self, _("testing.validation_error"), _("testing.please_select_recipient")
                )
                return

            if not message_text:
                QMessageBox.warning(
                    self, _("testing.validation_error"), _("testing.please_enter_message")
                )
                return

            # Disable send button
            self.send_button.setEnabled(False)
            self.send_button.setText(_("testing.sending"))

            # Get media path from selected tab
            media_path = None
            if self.media_tabs.currentIndex() == 0:  # File tab
                media_path = self.media_file_edit.text().strip() or None
            else:  # URL tab
                media_url = self.media_url_edit.text().strip()
                if media_url:
                    if not self.validate_media_url(media_url):
                        QMessageBox.warning(
                            self,
                            "Invalid Media URL",
                            "Please enter a valid URL for a supported media file.\n\n"
                            "Supported formats:\n"
                            "• Images: JPG, PNG, GIF, WebP, etc.\n"
                            "• Videos: MP4, AVI, MOV, WebM, etc.\n"
                            "• Audio: MP3, WAV, OGG, M4A, etc.\n"
                            "• Documents: PDF, DOC, TXT, etc.",
                        )
                        return
                    media_path = media_url

            # Create and start worker
            use_spintax = self.spintax_checkbox.isChecked()
            self.worker = TestMessageWorker(
                account_id, recipient_identifier, message_text, media_path, use_spintax
            )
            self.worker.finished.connect(self.on_test_finished)
            self.worker.progress.connect(self.on_test_progress)
            self.worker.start()

        except Exception as e:
            self.logger.error(f"Error sending test message: {e}")
            QMessageBox.critical(self, "Error", f"Failed to send test message: {e}")
            self.send_button.setEnabled(True)
            self.send_button.setText("Send Test Message")

    @pyqtSlot(str)
    def on_test_progress(self, message):
        """Handle test progress updates."""
        self.logger.info(f"Test progress: {message}")

    @pyqtSlot(dict)
    def on_test_finished(self, result):
        """Handle test completion."""
        try:
            # Re-enable send button
            self.send_button.setEnabled(True)
            self.send_button.setText("Send Test Message")

            # Add to recent tests
            test_entry = {
                "timestamp": datetime.now(),
                "account": self.account_combo.currentText(),
                "recipient": self.recipient_combo.currentText(),
                "message": (
                    self.message_edit.toPlainText()[:50] + "..."
                    if len(self.message_edit.toPlainText()) > 50
                    else self.message_edit.toPlainText()
                ),
                "success": result["success"],
                "details": result["details"],
                "media_path": result.get("media_path", ""),
            }

            self.recent_tests.insert(0, test_entry)  # Add to beginning
            self.update_tests_list()

            # Show result message
            if result["success"]:
                QMessageBox.information(
                    self, "Success", f"Test message sent successfully!\n\n{result['details']}"
                )
            else:
                QMessageBox.warning(
                    self,
                    "Failed",
                    f"Test message failed!\n\n{result['message']}\n{result['details']}",
                )

        except Exception as e:
            self.logger.error(f"Error handling test completion: {e}")
        finally:
            # Clean up worker
            if hasattr(self, "worker"):
                self.worker.deleteLater()

    def update_tests_list(self):
        """Update the recent tests list."""
        self.tests_list.clear()

        for test in self.recent_tests[:20]:  # Show last 20 tests
            status_icon = "✅" if test["success"] else "❌"
            timestamp = test["timestamp"].strftime("%H:%M:%S")

            item_text = f"{status_icon} [{timestamp}] {test['account']} → {test['recipient']}"

            # Add media info if present
            if test.get("media_path"):
                if test["media_path"].startswith(("http://", "https://")):
                    item_text += " [URL]"
                else:
                    item_text += " [File]"

            if not test["success"]:
                item_text += f" - {test['details']}"

            item = QListWidgetItem(item_text)

            # Enhanced tooltip with media info
            tooltip = f"Message: {test['message']}\nDetails: {test['details']}"
            if test.get("media_path"):
                tooltip += f"\nMedia: {test['media_path']}"
            item.setToolTip(tooltip)

            # Color code based on success
            if test["success"]:
                item.setBackground(Qt.green)
            else:
                item.setBackground(Qt.red)

            self.tests_list.addItem(item)

    def clear_tests(self):
        """Clear recent tests."""
        reply = QMessageBox.question(
            self,
            _("testing.clear_tests"),
            _("testing.clear_tests_confirm"),
            QMessageBox.Yes | QMessageBox.No,
        )

        if reply == QMessageBox.Yes:
            self.recent_tests.clear()
            self.update_tests_list()
            self.logger.info("Recent tests cleared")

    def on_language_changed(self, language: str):
        """Handle language change."""
        self.logger.info(f"Language changed to: {language}")
        # Update UI elements with new translations
        self.update_ui_translations()

    def update_ui_translations(self):
        """Update UI elements with current translations."""
        try:
            # Update form group title
            if hasattr(self, "form_group"):
                self.form_group.setTitle(_("testing.send_test_message"))

            # Update labels
            if hasattr(self, "account_combo"):
                self.account_combo.setPlaceholderText(_("testing.select_account"))

            if hasattr(self, "recipient_combo"):
                self.recipient_combo.setPlaceholderText(_("testing.select_recipient"))

            if hasattr(self, "template_combo"):
                self.template_combo.setPlaceholderText(_("testing.select_template_optional"))

            if hasattr(self, "message_edit"):
                self.message_edit.setPlaceholderText(_("testing.enter_message_text"))

            if hasattr(self, "media_file_edit"):
                self.media_file_edit.setPlaceholderText(_("testing.no_file_selected"))

            if hasattr(self, "choose_file_button"):
                self.choose_file_button.setText(_("testing.choose_file"))

            if hasattr(self, "media_url_edit"):
                self.media_url_edit.setPlaceholderText(_("testing.paste_media_url"))

            if hasattr(self, "send_button"):
                self.send_button.setText(_("testing.send_test_message"))

            if hasattr(self, "tests_group"):
                self.tests_group.setTitle(_("testing.recent_tests"))

            if hasattr(self, "clear_button"):
                self.clear_button.setText(_("testing.clear_tests"))

            # Update media tabs
            if hasattr(self, "media_tabs"):
                try:
                    self.media_tabs.setTabText(0, _("testing.file"))
                    self.media_tabs.setTabText(1, _("testing.url"))
                except Exception as e:
                    self.logger.warning(f"Error updating media tabs: {e}")

            self.logger.info("UI translations updated successfully")

        except Exception as e:
            self.logger.error(f"Error updating UI translations: {e}")
