"""
Settings-related dialogs for YTSage application.
Contains dialogs for configuring download settings and auto-update preferences.
"""

import threading
import time
from datetime import datetime

import requests
from packaging import version as version_parser
from PySide6.QtCore import Qt, QTimer
from PySide6.QtWidgets import (
    QButtonGroup,
    QCheckBox,
    QComboBox,
    QDialog,
    QDialogButtonBox,
    QFileDialog,
    QGroupBox,
    QHBoxLayout,
    QLabel,
    QLineEdit,
    QMessageBox,
    QPushButton,
    QRadioButton,
    QVBoxLayout,
)

from ...core.ytsage_utils import (
    check_and_update_ytdlp_auto,
    get_auto_update_settings,
    get_ytdlp_version,
    update_auto_update_settings,
)
from ...utils.ytsage_logger import logger
from ...utils.ytsage_localization import _


class DownloadSettingsDialog(QDialog):
    def __init__(self, current_path, current_limit, current_unit_index, parent=None) -> None:
        super().__init__(parent)
        self.setWindowTitle(_("settings.title"))
        self.setMinimumWidth(450)
        self.setMinimumHeight(400)
        self.current_path = current_path
        self.current_limit = current_limit if current_limit is not None else ""
        self.current_unit_index = current_unit_index

        # Apply main app styling
        self.setStyleSheet(
            """
            QDialog {
                background-color: #15181b;
                color: #ffffff;
            }
            QWidget {
                background-color: #15181b;
                color: #ffffff;
            }
            QLabel {
                color: #ffffff;
            }
            QGroupBox {
                color: #ffffff;
                border: 2px solid #1b2021;
                border-radius: 4px;
                margin-top: 10px;
                padding-top: 10px;
                font-weight: bold;
                background-color: #15181b;
            }
            QGroupBox::title {
                subcontrol-origin: margin;
                left: 10px;
                padding: 0 5px 0 5px;
                color: #ffffff;
            }
            QLineEdit {
                padding: 8px;
                border: 2px solid #1b2021;
                border-radius: 4px;
                background-color: #1b2021;
                color: #ffffff;
                selection-background-color: #c90000;
                selection-color: #ffffff;
            }
            QPushButton {
                padding: 8px 15px;
                background-color: #c90000;
                border: none;
                border-radius: 4px;
                color: white;
                font-weight: bold;
                min-height: 20px;
            }
            QPushButton:hover {
                background-color: #a50000;
            }
            QPushButton:pressed {
                background-color: #800000;
            }
            QPushButton:disabled {
                background-color: #666666;
                color: #999999;
            }
            QCheckBox {
                spacing: 5px;
                color: #ffffff;
            }
            QCheckBox::indicator {
                width: 18px;
                height: 18px;
                border-radius: 9px;
            }
            QCheckBox::indicator:unchecked {
                border: 2px solid #666666;
                background: #15181b;
            }
            QCheckBox::indicator:checked {
                border: 2px solid #c90000;
                background: #c90000;
            }
            QRadioButton {
                spacing: 5px;
                color: #ffffff;
            }
            QRadioButton::indicator {
                width: 18px;
                height: 18px;
                border-radius: 9px;
            }
            QRadioButton::indicator:unchecked {
                border: 2px solid #666666;
                background: #15181b;
            }
            QRadioButton::indicator:checked {
                border: 2px solid #c90000;
                background: #c90000;
            }
            QComboBox {
                padding: 5px;
                border: 2px solid #1b2021;
                border-radius: 4px;
                background-color: #1b2021;
                color: #ffffff;
                min-height: 20px;
            }
            QComboBox::drop-down {
                border: none;
                width: 20px;
            }
            QComboBox QAbstractItemView {
                border: 2px solid #1b2021;
                border-radius: 4px;
                background-color: #15181b;
                color: #ffffff;
                selection-background-color: #c90000;
                selection-color: #ffffff;
            }
        """
        )

        layout = QVBoxLayout(self)

        # --- Download Path Section ---
        path_group_box = QGroupBox(_("settings.download_path"))
        path_layout = QVBoxLayout()

        self.path_display = QLabel(str(self.current_path))
        self.path_display.setWordWrap(True)
        self.path_display.setStyleSheet(
            "QLabel { color: #ffffff; padding: 5px; border: 1px solid #1b2021; border-radius: 4px; background-color: #1b2021; }"
        )
        path_layout.addWidget(self.path_display)

                
        browse_button = QPushButton(_("settings.browse"))
        browse_button.clicked.connect(self.browse_new_path)
        path_layout.addWidget(browse_button)

        path_group_box.setLayout(path_layout)
        layout.addWidget(path_group_box)

        # --- Speed Limit Section ---
        speed_group_box = QGroupBox(_("settings.speed_limit"))
        speed_layout = QHBoxLayout()

        self.speed_limit_input = QLineEdit(str(self.current_limit))
        self.speed_limit_input.setPlaceholderText(_("settings.speed_limit_placeholder"))
        speed_layout.addWidget(self.speed_limit_input)

        self.speed_limit_unit = QComboBox()
        self.speed_limit_unit.addItems(["KB/s", "MB/s"])
        self.speed_limit_unit.setCurrentIndex(self.current_unit_index)
        speed_layout.addWidget(self.speed_limit_unit)

        speed_group_box.setLayout(speed_layout)
        layout.addWidget(speed_group_box)

        # --- Auto-Update yt-dlp Section ---
        auto_update_group_box = QGroupBox(_("settings.auto_update_ytdlp"))
        auto_update_layout = QVBoxLayout()

        # Load current auto-update settings
        auto_settings = get_auto_update_settings()

        # Enable/Disable auto-update checkbox
        self.auto_update_enabled = QCheckBox(_("settings.enable_auto_updates"))
        self.auto_update_enabled.setChecked(auto_settings["enabled"])
        auto_update_layout.addWidget(self.auto_update_enabled)

        # Frequency options
        frequency_label = QLabel(_("settings.update_frequency"))
        frequency_label.setStyleSheet("color: #ffffff; margin-top: 10px;")
        auto_update_layout.addWidget(frequency_label)

        self.startup_radio = QRadioButton(_("settings.check_startup"))
        self.daily_radio = QRadioButton(_("settings.check_daily"))
        self.weekly_radio = QRadioButton(_("settings.check_weekly"))

        # Set current selection based on saved settings
        current_frequency = auto_settings["frequency"]
        if current_frequency == "startup":
            self.startup_radio.setChecked(True)
        elif current_frequency == "daily":
            self.daily_radio.setChecked(True)
        else:  # weekly
            self.weekly_radio.setChecked(True)

        auto_update_layout.addWidget(self.startup_radio)
        auto_update_layout.addWidget(self.daily_radio)
        auto_update_layout.addWidget(self.weekly_radio)

        # Test update button
        test_update_layout = QHBoxLayout()
        test_update_button = QPushButton(_("settings.check_updates_now"))
        test_update_button.clicked.connect(self.test_update_check)
        test_update_layout.addWidget(test_update_button)
        test_update_layout.addStretch()
        auto_update_layout.addLayout(test_update_layout)

        auto_update_group_box.setLayout(auto_update_layout)
        layout.addWidget(auto_update_group_box)

        # Dialog buttons (OK/Cancel)
        button_box = QDialogButtonBox()
        ok_button = button_box.addButton(_("buttons.ok"), QDialogButtonBox.ButtonRole.AcceptRole)
        cancel_button = button_box.addButton(_("buttons.cancel"), QDialogButtonBox.ButtonRole.RejectRole)
        button_box.accepted.connect(self.accept)
        button_box.rejected.connect(self.reject)
        layout.addWidget(button_box)

    def browse_new_path(self) -> None:
        new_path = QFileDialog.getExistingDirectory(self, _("dialogs.select_folder"), str(self.current_path))
        if new_path:
            self.current_path = new_path
            self.path_display.setText(self.current_path)

    def get_selected_path(self) -> str:
        """Returns the confirmed path after the dialog is accepted."""
        return self.current_path

    def get_selected_speed_limit(self) -> str | None:
        """Returns the entered speed limit value (as string or None)."""
        limit_str = self.speed_limit_input.text().strip()
        if not limit_str:
            return None
        try:
            float(limit_str)  # Check if convertible to float
            return limit_str
        except ValueError:
            logger.info("Invalid speed limit input in dialog")
            return None

    def get_selected_unit_index(self) -> int:
        """Returns the index of the selected speed limit unit."""
        return self.speed_limit_unit.currentIndex()

    def _create_styled_message_box(self, icon, title, text) -> QMessageBox:
        """Create a styled QMessageBox that matches the app theme."""
        msg_box = QMessageBox(self)
        msg_box.setIcon(icon)
        msg_box.setWindowTitle(title)
        msg_box.setText(text)
        msg_box.setWindowIcon(self.windowIcon())
        msg_box.setStyleSheet(
            """
            QMessageBox {
                background-color: #15181b;
                color: #ffffff;
            }
            QMessageBox QLabel {
                color: #ffffff;
            }
            QMessageBox QPushButton {
                padding: 8px 15px;
                background-color: #c90000;
                border: none;
                border-radius: 4px;
                color: white;
                font-weight: bold;
                min-width: 80px;
            }
            QMessageBox QPushButton:hover {
                background-color: #a50000;
            }
            QMessageBox QPushButton:pressed {
                background-color: #800000;
            }
        """
        )
        return msg_box

    def test_update_check(self) -> None:
        """Test the update check functionality."""
        try:
            # Get current version
            current_version = get_ytdlp_version()
            if "Error" in current_version:
                msg_box = self._create_styled_message_box(
                    QMessageBox.Icon.Warning,
                    _("settings.update_check_title"),
                    _("settings.could_not_determine_version"),
                )
                msg_box.exec()
                return

            # Get latest version from PyPI
            response = requests.get("https://pypi.org/pypi/yt-dlp/json", timeout=10)
            response.raise_for_status()
            latest_version = response.json()["info"]["version"]

            # Clean up version strings
            current_version = current_version.replace("_", ".")
            latest_version = latest_version.replace("_", ".")

            if version_parser.parse(latest_version) > version_parser.parse(current_version):
                msg_box = self._create_styled_message_box(
                    QMessageBox.Icon.Information,
                    _("settings.update_check_title"),
                    _("settings.update_available_dialog", current=current_version, latest=latest_version),
                )
                msg_box.exec()
            else:
                msg_box = self._create_styled_message_box(
                    QMessageBox.Icon.Information,
                    _("settings.update_check_title"),
                    _("settings.up_to_date_dialog", version=current_version),
                )
                msg_box.exec()
        except Exception as e:
            msg_box = self._create_styled_message_box(
                QMessageBox.Icon.Warning,
                _("settings.update_check_title"),
                _("settings.error_checking_updates", error=str(e)),
            )
            msg_box.exec()

    def get_auto_update_settings(self) -> tuple[bool, str]:
        """Returns the auto-update settings from the dialog."""
        enabled = self.auto_update_enabled.isChecked()

        if self.startup_radio.isChecked():
            frequency = "startup"
        elif self.daily_radio.isChecked():
            frequency = "daily"
        else:  # weekly_radio is checked
            frequency = "weekly"

        return enabled, frequency

    def accept(self) -> None:
        """Override accept to save auto-update settings."""
        try:
            # Save auto-update settings
            enabled, frequency = self.get_auto_update_settings()

            if update_auto_update_settings(enabled, frequency):
                QMessageBox.information(
                    self,
                    _("settings.settings_saved_title"),
                    _("settings.settings_saved_message"),
                )
            else:
                QMessageBox.warning(self, _("settings.error_title"), _("settings.failed_save_settings"))
        except Exception as e:
            QMessageBox.critical(self, _("settings.error_title"), _("settings.error_saving_settings", error=str(e)))

        # Call the parent accept method to close the dialog
        super().accept()


class AutoUpdateSettingsDialog(QDialog):
    def __init__(self, parent=None) -> None:
        super().__init__(parent)
        self.setWindowTitle(_("settings.auto_update_title"))
        self.setMinimumWidth(400)
        self.setMinimumHeight(300)

        # Set the window icon to match the main app
        if parent:
            self.setWindowIcon(parent.windowIcon())

        self.init_ui()
        self.load_current_settings()
        self.apply_styling()

    def init_ui(self) -> None:
        layout = QVBoxLayout(self)

        # Title
        title_label = QLabel(f"<h2>{_("settings.auto_update_header")}</h2>")
        title_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        layout.addWidget(title_label)

        # Description
        desc_label = QLabel(_("settings.auto_update_description"))
        desc_label.setWordWrap(True)
        desc_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        desc_label.setStyleSheet("color: #cccccc; margin: 10px; font-size: 11px;")
        layout.addWidget(desc_label)

        # Enable/Disable auto-update
        self.enable_checkbox = QCheckBox(_("settings.enable_auto_updates"))
        self.enable_checkbox.setChecked(True)  # Default enabled
        self.enable_checkbox.toggled.connect(self.on_enable_toggled)
        layout.addWidget(self.enable_checkbox)

        # Frequency options
        frequency_group = QGroupBox(_("settings.update_frequency_group"))
        frequency_layout = QVBoxLayout()

        self.frequency_group = QButtonGroup(self)

        self.startup_radio = QRadioButton(_("settings.check_startup"))
        self.daily_radio = QRadioButton(_("settings.check_daily"))
        self.weekly_radio = QRadioButton(_("settings.check_weekly"))

        self.daily_radio.setChecked(True)  # Default to daily

        self.frequency_group.addButton(self.startup_radio, 0)
        self.frequency_group.addButton(self.daily_radio, 1)
        self.frequency_group.addButton(self.weekly_radio, 2)

        frequency_layout.addWidget(self.startup_radio)
        frequency_layout.addWidget(self.daily_radio)
        frequency_layout.addWidget(self.weekly_radio)
        frequency_group.setLayout(frequency_layout)

        layout.addWidget(frequency_group)

        # Current status
        status_group = QGroupBox(_("settings.current_status"))
        status_layout = QVBoxLayout()

        self.current_version_label = QLabel(_("settings.current_version_label"))
        self.last_check_label = QLabel(_("settings.last_check_label"))
        self.next_check_label = QLabel(_("settings.next_check_label"))

        status_layout.addWidget(self.current_version_label)
        status_layout.addWidget(self.last_check_label)
        status_layout.addWidget(self.next_check_label)
        status_group.setLayout(status_layout)

        layout.addWidget(status_group)

        # Manual check button
        self.manual_check_btn = QPushButton(_("settings.manual_check_button"))
        self.manual_check_btn.clicked.connect(self.manual_check)
        layout.addWidget(self.manual_check_btn)

        # Buttons
        button_layout = QHBoxLayout()

        self.save_btn = QPushButton(_("settings.save_settings"))
        self.save_btn.clicked.connect(self.save_settings)

        self.cancel_btn = QPushButton(_("buttons.cancel"))
        self.cancel_btn.clicked.connect(self.reject)

        button_layout.addWidget(self.save_btn)
        button_layout.addWidget(self.cancel_btn)

        layout.addLayout(button_layout)

    def apply_styling(self) -> None:
        self.setStyleSheet(
            """
            QDialog {
                background-color: #15181b;
                color: #ffffff;
            }
            QLabel {
                color: #ffffff;
            }
            QGroupBox {
                color: #ffffff;
                border: 2px solid #1b2021;
                border-radius: 4px;
                margin-top: 10px;
                padding-top: 10px;
                font-weight: bold;
                background-color: #15181b;
            }
            QGroupBox::title {
                subcontrol-origin: margin;
                left: 10px;
                padding: 0 5px 0 5px;
                color: #ffffff;
            }
            QCheckBox, QRadioButton {
                color: #ffffff;
                spacing: 5px;
                margin: 5px;
            }
            QCheckBox::indicator, QRadioButton::indicator {
                width: 18px;
                height: 18px;
                border-radius: 9px;
            }
            QCheckBox::indicator:unchecked, QRadioButton::indicator:unchecked {
                border: 2px solid #666666;
                background: #15181b;
            }
            QCheckBox::indicator:checked, QRadioButton::indicator:checked {
                border: 2px solid #c90000;
                background: #c90000;
            }
            QPushButton {
                padding: 8px 15px;
                background-color: #c90000;
                border: none;
                border-radius: 4px;
                color: white;
                font-weight: bold;
                margin: 5px;
                min-width: 100px;
                min-height: 20px;
            }
            QPushButton:hover {
                background-color: #a50000;
            }
            QPushButton:pressed {
                background-color: #800000;
            }
            QPushButton:disabled {
                background-color: #666666;
                color: #999999;
            }
        """
        )

    def load_current_settings(self) -> None:
        """Load current auto-update settings from config."""
        try:
            settings = get_auto_update_settings()

            # Set checkbox
            self.enable_checkbox.setChecked(settings["enabled"])

            # Set frequency
            frequency = settings["frequency"]
            if frequency == "startup":
                self.startup_radio.setChecked(True)
            elif frequency == "weekly":
                self.weekly_radio.setChecked(True)
            else:  # daily
                self.daily_radio.setChecked(True)

            # Update status labels
            current_version = get_ytdlp_version()
            self.current_version_label.setText(f"Current yt-dlp version: {current_version}")

            last_check = settings["last_check"]
            if last_check > 0:
                last_check_time = datetime.fromtimestamp(last_check).strftime("%Y-%m-%d %H:%M:%S")
                self.last_check_label.setText(_("auto_update.last_check", time=last_check_time))
            else:
                self.last_check_label.setText(_("auto_update.last_check_never"))

            # Calculate next check time
            self.update_next_check_label()

            # Update UI state
            self.on_enable_toggled(settings["enabled"])

        except Exception as e:
            logger.exception(f"Error loading auto-update settings: {e}")

    def update_next_check_label(self) -> None:
        """Update the next check label based on current settings."""
        try:
            if not self.enable_checkbox.isChecked():
                self.next_check_label.setText(_("auto_update.next_check_disabled"))
                return

            settings = get_auto_update_settings()
            last_check = settings["last_check"]
            frequency = self.get_selected_frequency()

            if last_check == 0:
                self.next_check_label.setText(_("auto_update.next_check_startup"))
                return

            next_check_time = last_check
            if frequency == "startup":
                next_check_time += 3600  # 1 hour
            elif frequency == "daily":
                next_check_time += 86400  # 24 hours
            elif frequency == "weekly":
                next_check_time += 604800  # 7 days

            current_time = time.time()
            if next_check_time <= current_time:
                self.next_check_label.setText(_("auto_update.next_check_overdue"))
            else:
                next_check_datetime = datetime.fromtimestamp(next_check_time)
                self.next_check_label.setText(_("auto_update.next_check", time=next_check_datetime.strftime('%Y-%m-%d %H:%M:%S')))

        except Exception as e:
            self.next_check_label.setText(_("auto_update.next_check_error"))
            logger.exception(f"Error calculating next check time: {e}")

    def on_enable_toggled(self, enabled) -> None:
        """Handle enable/disable checkbox toggle."""
        # Enable/disable frequency options
        for i in range(self.frequency_group.buttons().__len__()):
            self.frequency_group.button(i).setEnabled(enabled)

        self.update_next_check_label()

    def get_selected_frequency(self) -> str:
        """Get the selected frequency setting."""
        if self.startup_radio.isChecked():
            return "startup"
        elif self.weekly_radio.isChecked():
            return "weekly"
        else:
            return "daily"

    def manual_check(self) -> None:
        """Perform a manual update check."""
        self.manual_check_btn.setEnabled(False)
        self.manual_check_btn.setText(_("auto_update.checking"))

        # Force an immediate update check
        def check_in_thread() -> None:
            try:
                result = check_and_update_ytdlp_auto()

                # Update UI in main thread
                QTimer.singleShot(0, lambda: self.manual_check_finished(result))
            except Exception as e:
                logger.exception(f"Error during manual check: {e}")
                QTimer.singleShot(0, lambda: self.manual_check_finished(False))

        # Run in separate thread to avoid blocking UI
        threading.Thread(target=check_in_thread, daemon=True).start()

    def _create_styled_message_box(self, icon, title, text) -> QMessageBox:
        """Create a styled QMessageBox that matches the app theme."""
        msg_box = QMessageBox(self)
        msg_box.setIcon(icon)
        msg_box.setWindowTitle(title)
        msg_box.setText(text)
        msg_box.setWindowIcon(self.windowIcon())
        msg_box.setStyleSheet(
            """
            QMessageBox {
                background-color: #15181b;
                color: #ffffff;
            }
            QMessageBox QLabel {
                color: #ffffff;
            }
            QMessageBox QPushButton {
                padding: 8px 15px;
                background-color: #c90000;
                border: none;
                border-radius: 4px;
                color: white;
                font-weight: bold;
                min-width: 80px;
            }
            QMessageBox QPushButton:hover {
                background-color: #a50000;
            }
            QMessageBox QPushButton:pressed {
                background-color: #800000;
            }
        """
        )
        return msg_box

    def manual_check_finished(self, success) -> None:
        """Handle completion of manual update check."""
        self.manual_check_btn.setEnabled(True)
        self.manual_check_btn.setText(_("auto_update.check_now"))

        if success:
            msg_box = self._create_styled_message_box(
                QMessageBox.Icon.Information,
                "Update Check",
                "✅ Update check completed successfully!\nCheck the console for details.",
            )
            msg_box.exec()
        else:
            msg_box = self._create_styled_message_box(
                QMessageBox.Icon.Warning,
                "Update Check",
                "❌ Update check failed.\nCheck the console for error details.",
            )
            msg_box.exec()

        # Refresh the current settings display
        self.load_current_settings()

    def save_settings(self) -> None:
        """Save the auto-update settings."""
        try:
            enabled = self.enable_checkbox.isChecked()
            frequency = self.get_selected_frequency()

            if update_auto_update_settings(enabled, frequency):
                msg_box = self._create_styled_message_box(
                    QMessageBox.Icon.Information,
                    _("settings.settings_saved_title"),
                    _("settings.settings_saved_successfully"),
                )
                msg_box.exec()
                self.accept()
            else:
                msg_box = self._create_styled_message_box(
                    QMessageBox.Icon.Warning,
                    _("settings.error_title"),
                    _("settings.failed_save_settings"),
                )
                msg_box.exec()
        except Exception as e:
            logger.exception(f"Error saving auto-update settings: {e}")
            msg_box = self._create_styled_message_box(QMessageBox.Icon.Critical, _("settings.error_title"), _("settings", "error_saving", error=str(e)))
            msg_box.exec()
