"""
settings_dialog.py — Indstillinger for LineDance Player.
Gemmes via QSettings og læses ved opstart.
"""

from PyQt6.QtWidgets import (
    QDialog, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit,
    QPushButton, QComboBox, QSpinBox, QCheckBox, QFrame,
    QTabWidget, QWidget, QFileDialog, QGroupBox, QFormLayout,
)
from PyQt6.QtCore import Qt, QSettings


SETTINGS_KEY_THEME        = "appearance/dark_theme"
SETTINGS_KEY_DEMO_SEC     = "playback/demo_seconds"
SETTINGS_KEY_DEMO_FADE    = "playback/demo_fade_seconds"
SETTINGS_KEY_VOLUME       = "playback/volume"
SETTINGS_KEY_MAIL_CLIENT  = "mail/client"
SETTINGS_KEY_MAIL_PATH    = "mail/custom_path"
SETTINGS_KEY_AUTO_LOGIN   = "online/auto_login"
SETTINGS_KEY_USERNAME     = "online/username"
SETTINGS_KEY_PASSWORD     = "online/password"
SETTINGS_KEY_SERVER_URL   = "online/server_url"
SETTINGS_KEY_LANGUAGE     = "appearance/language"
SETTINGS_KEY_BETWEEN_SEC  = "playback/between_seconds"
SETTINGS_KEY_WORKSHOP_MIN = "playback/workshop_minutes"
SETTINGS_KEY_MAIN_DEVICE  = "playback/audio_device_main"
SETTINGS_KEY_PREV_DEVICE  = "playback/audio_device_preview"
SETTINGS_KEY_AFTER_SONG   = "playback/after_song_mode"
SETTINGS_KEY_AFTER_DELAY  = "playback/after_song_delay"
SETTINGS_KEY_ACOUSTID     = "playback/acoustid_enabled"
SETTINGS_KEY_ACOUSTID_KEY = "playback/acoustid_api_key"


def load_settings() -> dict:
    s = QSettings("LineDance", "Player")
    return {
        "dark_theme":          s.value(SETTINGS_KEY_THEME,       True,  type=bool),
        "demo_seconds":        s.value(SETTINGS_KEY_DEMO_SEC,    10,    type=int),
        "demo_fade_seconds":   s.value(SETTINGS_KEY_DEMO_FADE,   5,     type=int),
        "volume":              s.value(SETTINGS_KEY_VOLUME,      78,    type=int),
        "mail_client":         s.value(SETTINGS_KEY_MAIL_CLIENT, "auto"),
        "mail_path":           s.value(SETTINGS_KEY_MAIL_PATH,   ""),
        "auto_login":          s.value(SETTINGS_KEY_AUTO_LOGIN,  False, type=bool),
        "username":            s.value(SETTINGS_KEY_USERNAME,    ""),
        "password":            s.value(SETTINGS_KEY_PASSWORD,    ""),
        "server_url":          s.value(SETTINGS_KEY_SERVER_URL,  "http://localhost:8000"),
        "language":            s.value(SETTINGS_KEY_LANGUAGE,    "da"),
        "between_seconds":     s.value(SETTINGS_KEY_BETWEEN_SEC,  60,  type=int),
        "workshop_minutes":    s.value(SETTINGS_KEY_WORKSHOP_MIN, 10,  type=int),
        "audio_device_main":   s.value(SETTINGS_KEY_MAIN_DEVICE, ""),
        "audio_device_preview":s.value(SETTINGS_KEY_PREV_DEVICE, ""),
        "after_song_mode":     s.value(SETTINGS_KEY_AFTER_SONG,  "manual"),
        "after_song_delay":    s.value(SETTINGS_KEY_AFTER_DELAY, 2, type=int),
        "acoustid_enabled":    s.value(SETTINGS_KEY_ACOUSTID,     False, type=bool),
        "acoustid_api_key":    s.value(SETTINGS_KEY_ACOUSTID_KEY, ""),
    }


def save_settings(values: dict):
    s = QSettings("LineDance", "Player")
    s.setValue(SETTINGS_KEY_THEME,       values.get("dark_theme",        True))
    s.setValue(SETTINGS_KEY_DEMO_SEC,    values.get("demo_seconds",      10))
    s.setValue(SETTINGS_KEY_DEMO_FADE,   values.get("demo_fade_seconds", 5))
    s.setValue(SETTINGS_KEY_VOLUME,      values.get("volume",            78))
    s.setValue(SETTINGS_KEY_MAIL_CLIENT, values.get("mail_client",       "auto"))
    s.setValue(SETTINGS_KEY_MAIL_PATH,   values.get("mail_path",         ""))
    s.setValue(SETTINGS_KEY_AUTO_LOGIN,  values.get("auto_login",        False))
    s.setValue(SETTINGS_KEY_USERNAME,    values.get("username",          ""))
    s.setValue(SETTINGS_KEY_PASSWORD,    values.get("password",          ""))
    s.setValue(SETTINGS_KEY_SERVER_URL,  values.get("server_url",        "http://localhost:8000"))
    s.setValue(SETTINGS_KEY_LANGUAGE,    values.get("language",          "da"))
    s.setValue(SETTINGS_KEY_BETWEEN_SEC, values.get("between_seconds",   60))
    s.setValue(SETTINGS_KEY_WORKSHOP_MIN,values.get("workshop_minutes",  10))
    s.setValue(SETTINGS_KEY_MAIN_DEVICE, values.get("audio_device_main", ""))
    s.setValue(SETTINGS_KEY_PREV_DEVICE, values.get("audio_device_preview", ""))
    s.setValue(SETTINGS_KEY_AFTER_SONG,  values.get("after_song_mode",  "manual"))
    s.setValue(SETTINGS_KEY_AFTER_DELAY, values.get("after_song_delay", 2))
    s.setValue(SETTINGS_KEY_ACOUSTID,     values.get("acoustid_enabled", False))
    s.setValue(SETTINGS_KEY_ACOUSTID_KEY, values.get("acoustid_api_key", ""))


class SettingsDialog(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("Indstillinger")
        self.setMinimumWidth(480)
        self.setModal(True)
        self._values = load_settings()
        self._build_ui()
        self._populate()

    def _build_ui(self):
        layout = QVBoxLayout(self)
        layout.setContentsMargins(16, 16, 16, 16)
        layout.setSpacing(12)

        tabs = QTabWidget()
        tabs.setStyleSheet("""
            QTabBar::tab {
                padding: 6px 14px;
                font-size: 13px;
                color: #9aa0b0;
                background: #1e2128;
                border: none;
                min-width: 80px;
            }
            QTabBar::tab:selected {
                color: #e0e4f0;
                background: #2a2d36;
                border-bottom: 2px solid #e8a020;
            }
            QTabBar::tab:hover {
                color: #e0e4f0;
                background: #252830;
            }
        """)
        tabs.addTab(self._build_appearance_tab(), "Udseende")
        tabs.addTab(self._build_playback_tab(),   "Afspilning")
        tabs.addTab(self._build_mail_tab(),        "Mail")
        tabs.addTab(self._build_online_tab(),      "Online")
        tabs.addTab(self._build_language_tab(),    "Sprog")
        layout.addWidget(tabs)

        # Knapper
        btn_row = QHBoxLayout()
        btn_row.addStretch()
        btn_cancel = QPushButton("Annuller")
        btn_cancel.clicked.connect(self.reject)
        btn_row.addWidget(btn_cancel)
        btn_save = QPushButton("💾  Gem indstillinger")
        btn_save.setObjectName("btn_play")
        btn_save.setDefault(True)
        btn_save.clicked.connect(self._save_and_close)
        btn_row.addWidget(btn_save)
        layout.addLayout(btn_row)

    # ── Fane: Udseende ────────────────────────────────────────────────────────

    def _build_appearance_tab(self) -> QWidget:
        tab = QWidget()
        layout = QVBoxLayout(tab)
        layout.setSpacing(12)

        grp = QGroupBox("Standard tema")
        grp_layout = QVBoxLayout(grp)

        self._chk_dark = QCheckBox("Start med mørkt tema")
        grp_layout.addWidget(self._chk_dark)

        note = QLabel("Du kan altid skifte tema mens programmet kører via topbar-knappen.")
        note.setObjectName("result_count")
        note.setWordWrap(True)
        grp_layout.addWidget(note)
        layout.addWidget(grp)
        layout.addStretch()
        return tab

    # ── Fane: Afspilning ──────────────────────────────────────────────────────

    def _build_playback_tab(self) -> QWidget:
        tab = QWidget()
        layout = QVBoxLayout(tab)
        layout.setSpacing(12)

        grp = QGroupBox("Forspil (▶ N SEK knappen)")
        grp_layout = QFormLayout(grp)

        self._spin_demo = QSpinBox()
        self._spin_demo.setRange(3, 60)
        self._spin_demo.setSuffix("  sekunder")
        self._spin_demo.setFixedWidth(140)
        grp_layout.addRow("Forspil-længde:", self._spin_demo)

        self._spin_fade = QSpinBox()
        self._spin_fade.setRange(0, 15)
        self._spin_fade.setSuffix("  sekunder  (0 = ingen fade)")
        self._spin_fade.setFixedWidth(220)
        self._spin_fade.setToolTip(
            "Fade-out tilføjes til forspillets længde.\n"
            "F.eks. 10 sek forspil + 5 sek fade = 15 sek total.\n"
            "Sæt til 0 for ingen fade."
        )
        grp_layout.addRow("Fade-ud:", self._spin_fade)

        note = QLabel(
            "Forspillet afspiller begyndelsen af sangen så arrangøren kan bekræfte\n"
            "at det er den rigtige sang og dans inden eventet starter.\n"
            "Fade-ud tilføjes oven i forspillets længde og fades logaritmisk."
        )
        note.setObjectName("result_count")
        note.setWordWrap(True)
        grp_layout.addRow(note)
        layout.addWidget(grp)

        grp2 = QGroupBox("Danseliste-tider (ℹ info-vinduet)")
        grp2_layout = QFormLayout(grp2)

        self._spin_between = QSpinBox()
        self._spin_between.setRange(0, 600)
        self._spin_between.setSuffix("  sekunder")
        self._spin_between.setFixedWidth(140)
        grp2_layout.addRow("Tid mellem musikstykker:", self._spin_between)

        self._spin_workshop = QSpinBox()
        self._spin_workshop.setRange(0, 120)
        self._spin_workshop.setSuffix("  minutter")
        self._spin_workshop.setFixedWidth(140)
        grp2_layout.addRow("Tid per workshop:", self._spin_workshop)

        layout.addWidget(grp2)

        # Reaktion når sang slutter
        from PyQt6.QtWidgets import QRadioButton, QButtonGroup
        grp3 = QGroupBox("Når en sang slutter")
        grp3_layout = QVBoxLayout(grp3)
        grp3_layout.setSpacing(8)

        self._radio_manual        = QRadioButton("Manuel — marker næste klar, vent på ▶")
        self._radio_auto_demo     = QRadioButton("Auto-demo — afspil demo af næste sang automatisk")
        self._radio_auto_play     = QRadioButton("Auto-play — start næste sang automatisk")
        self._radio_demo_then_play = QRadioButton("Auto-demo → auto-play — demo, pause, så spiller sangen automatisk")

        self._after_song_group = QButtonGroup(self)
        self._after_song_group.addButton(self._radio_manual,         0)
        self._after_song_group.addButton(self._radio_auto_demo,      1)
        self._after_song_group.addButton(self._radio_auto_play,      2)
        self._after_song_group.addButton(self._radio_demo_then_play, 3)

        grp3_layout.addWidget(self._radio_manual)
        grp3_layout.addWidget(self._radio_auto_demo)
        grp3_layout.addWidget(self._radio_auto_play)
        grp3_layout.addWidget(self._radio_demo_then_play)

        delay_row = QHBoxLayout()
        delay_row.addWidget(QLabel("    Pause før næste starter:"))
        self._spin_after_delay = QSpinBox()
        self._spin_after_delay.setRange(0, 30)
        self._spin_after_delay.setSuffix("  sekunder")
        self._spin_after_delay.setFixedWidth(160)
        self._spin_after_delay.setToolTip(
            "Bruges til auto-demo og auto-play.\n"
            "Antal sekunder der ventes inden næste sang starter."
        )
        delay_row.addWidget(self._spin_after_delay)
        delay_row.addStretch()
        grp3_layout.addLayout(delay_row)

        layout.addWidget(grp3)
        grp3 = QGroupBox("Lydenheder")
        grp3_layout = QFormLayout(grp3)

        from player.player import Player as _Player
        devices = _Player.get_audio_devices()
        device_items = [("Standard", "")] + [(d["name"], d["id"]) for d in devices]

        self._combo_main_device = QComboBox()
        self._combo_preview_device = QComboBox()
        for name, did in device_items:
            self._combo_main_device.addItem(name, did)
            self._combo_preview_device.addItem(name, did)

        grp3_layout.addRow("Hoved-afspiller (sal):", self._combo_main_device)
        grp3_layout.addRow("Preview (høretelefoner):", self._combo_preview_device)

        note3 = QLabel("Preview-afspilleren bruges til at lytte til sange i biblioteket\nudenom at afbryde den sang der spiller i salen.")
        note3.setObjectName("result_count")
        note3.setWordWrap(True)
        grp3_layout.addRow(note3)
        layout.addWidget(grp3)

        # AcoustID fingerprinting
        grp4 = QGroupBox("AcoustID fingerprinting (valgfri)")
        grp4_layout = QVBoxLayout(grp4)
        grp4_layout.setSpacing(6)

        self._chk_acoustid = QCheckBox("Kør AcoustID fingerprinting i baggrunden")
        self._chk_acoustid.setToolTip(
            "Analyserer sange uden MBID og slår dem op i AcoustID-databasen.\n"
            "Kræver fpcalc (Chromaprint) installeret.\n"
            "Startes automatisk 10 sekunder efter opstart."
        )
        grp4_layout.addWidget(self._chk_acoustid)

        key_row = QHBoxLayout()
        key_row.addWidget(QLabel("API-nøgle:"))
        self._acoustid_key = QLineEdit()
        self._acoustid_key.setPlaceholderText("Hent gratis på acoustid.org/api-key")
        key_row.addWidget(self._acoustid_key)
        grp4_layout.addLayout(key_row)

        note4 = QLabel(
            "fpcalc skal installeres separat:\n"
            "  Linux: sudo apt install libchromaprint-tools\n"
            "  Windows: download fra acoustid.org/chromaprint"
        )
        note4.setObjectName("result_count")
        note4.setWordWrap(True)
        grp4_layout.addWidget(note4)
        layout.addWidget(grp4)

        layout.addStretch()
        return tab

    # ── Fane: Mail ────────────────────────────────────────────────────────────

    def _build_mail_tab(self) -> QWidget:
        tab = QWidget()
        layout = QVBoxLayout(tab)
        layout.setSpacing(12)

        grp = QGroupBox("Mailklient")
        grp_layout = QFormLayout(grp)

        self._mail_combo = QComboBox()
        self._mail_combo.addItem("Auto-detekter (Thunderbird → Outlook → mailto:)", "auto")
        self._mail_combo.addItem("Thunderbird", "thunderbird")
        self._mail_combo.addItem("Outlook (Windows)", "outlook")
        self._mail_combo.addItem("Brugerdefineret sti", "custom")
        self._mail_combo.addItem("Kun mailto: (ingen vedhæftning)", "mailto")
        self._mail_combo.currentIndexChanged.connect(self._on_mail_combo_changed)
        grp_layout.addRow("Klient:", self._mail_combo)

        path_row = QHBoxLayout()
        self._mail_path = QLineEdit()
        self._mail_path.setPlaceholderText("/usr/bin/thunderbird  eller  C:\\...\\thunderbird.exe")
        path_row.addWidget(self._mail_path)
        btn_browse = QPushButton("...")
        btn_browse.setFixedWidth(32)
        btn_browse.clicked.connect(self._browse_mail_path)
        path_row.addWidget(btn_browse)
        self._mail_path_row_widget = QWidget()
        self._mail_path_row_widget.setLayout(path_row)
        grp_layout.addRow("Sti:", self._mail_path_row_widget)

        note = QLabel(
            "Med Thunderbird og Outlook åbnes et nyt compose-vindue med filen vedhæftet.\n"
            "mailto: åbner standard-mailprogrammet men uden automatisk vedhæftning."
        )
        note.setObjectName("result_count")
        note.setWordWrap(True)
        grp_layout.addRow(note)
        layout.addWidget(grp)
        layout.addStretch()
        return tab

    def _on_mail_combo_changed(self, idx: int):
        is_custom = self._mail_combo.currentData() == "custom"
        self._mail_path_row_widget.setVisible(is_custom)

    def _browse_mail_path(self):
        path, _ = QFileDialog.getOpenFileName(self, "Vælg mailklient")
        if path:
            self._mail_path.setText(path)

    # ── Fane: Online ──────────────────────────────────────────────────────────

    def _build_online_tab(self) -> QWidget:
        tab = QWidget()
        layout = QVBoxLayout(tab)
        layout.setSpacing(12)

        # Server URL
        grp_server = QGroupBox("Server")
        grp_server_layout = QFormLayout(grp_server)
        self._server_url = QLineEdit()
        self._server_url.setPlaceholderText("http://localhost:8000")
        grp_server_layout.addRow("API-adresse:", self._server_url)
        note_server = QLabel("Adressen på LineDance API-serveren.")
        note_server.setObjectName("result_count")
        grp_server_layout.addRow(note_server)
        layout.addWidget(grp_server)

        # Login
        grp = QGroupBox("Konto")
        grp_layout = QFormLayout(grp)

        btn_register = QPushButton("✚  Opret ny konto...")
        btn_register.clicked.connect(self._open_register)
        grp_layout.addRow(btn_register)

        self._chk_auto_login = QCheckBox("Log automatisk ind når programmet starter")
        self._chk_auto_login.stateChanged.connect(self._on_auto_login_changed)
        grp_layout.addRow(self._chk_auto_login)

        self._user_input = QLineEdit()
        self._user_input.setPlaceholderText("brugernavn eller e-mail")
        grp_layout.addRow("Brugernavn:", self._user_input)

        self._pass_input = QLineEdit()
        self._pass_input.setEchoMode(QLineEdit.EchoMode.Password)
        self._pass_input.setPlaceholderText("••••••••")
        grp_layout.addRow("Kodeord:", self._pass_input)

        note = QLabel(
            "⚠  Kodeordet gemmes lokalt på denne computer.\n"
            "Brug kun dette på en personlig maskine."
        )
        note.setObjectName("result_count")
        note.setWordWrap(True)
        grp_layout.addRow(note)
        layout.addWidget(grp)
        layout.addStretch()
        return tab

    def _open_register(self):
        from ui.register_dialog import RegisterDialog
        server_url = self._server_url.text().strip() or "http://localhost:8000"
        dlg = RegisterDialog(server_url=server_url, parent=self)
        dlg.exec()

    def _build_language_tab(self) -> QWidget:
        tab = QWidget()
        layout = QVBoxLayout(tab)
        layout.setSpacing(12)
        grp = QGroupBox("Sprog")
        grp_layout = QFormLayout(grp)
        self._lang_combo = QComboBox()
        self._lang_combo.addItem("Dansk", "da")
        self._lang_combo.addItem("English", "en")
        grp_layout.addRow("Programsprog:", self._lang_combo)
        note = QLabel("Sproget anvendes næste gang programmet startes.")
        note.setObjectName("result_count")
        note.setWordWrap(True)
        grp_layout.addRow(note)
        layout.addWidget(grp)
        layout.addStretch()
        return tab

    def _on_auto_login_changed(self, state: int):
        enabled = state == Qt.CheckState.Checked.value
        self._user_input.setEnabled(enabled)
        self._pass_input.setEnabled(enabled)

    # ── Populer fra gemte værdier ─────────────────────────────────────────────

    def _populate(self):
        v = self._values
        self._chk_dark.setChecked(v.get("dark_theme", True))
        self._spin_demo.setValue(v.get("demo_seconds", 10))
        self._spin_fade.setValue(v.get("demo_fade_seconds", 5))
        self._spin_between.setValue(v.get("between_seconds", 60))
        self._spin_workshop.setValue(v.get("workshop_minutes", 10))

        # Sprog
        lang = v.get("language", "da")
        for i in range(self._lang_combo.count()):
            if self._lang_combo.itemData(i) == lang:
                self._lang_combo.setCurrentIndex(i)
                break

        # Mail
        client = v.get("mail_client", "auto")
        for i in range(self._mail_combo.count()):
            if self._mail_combo.itemData(i) == client:
                self._mail_combo.setCurrentIndex(i)
                break
        self._mail_path.setText(v.get("mail_path", ""))
        self._on_mail_combo_changed(self._mail_combo.currentIndex())

        # Online
        auto = v.get("auto_login", False)
        self._chk_auto_login.setChecked(auto)
        self._user_input.setText(v.get("username", ""))
        self._pass_input.setText(v.get("password", ""))
        self._server_url.setText(v.get("server_url", "http://localhost:8000"))
        self._user_input.setEnabled(auto)
        self._pass_input.setEnabled(auto)

        # Lydenheder
        main_dev    = v.get("audio_device_main", "")
        preview_dev = v.get("audio_device_preview", "")
        for i in range(self._combo_main_device.count()):
            if self._combo_main_device.itemData(i) == main_dev:
                self._combo_main_device.setCurrentIndex(i)
                break
        for i in range(self._combo_preview_device.count()):
            if self._combo_preview_device.itemData(i) == preview_dev:
                self._combo_preview_device.setCurrentIndex(i)
                break

        # Reaktion når sang slutter
        mode = v.get("after_song_mode", "manual")
        if mode == "auto_demo":
            self._radio_auto_demo.setChecked(True)
        elif mode == "auto_play":
            self._radio_auto_play.setChecked(True)
        elif mode == "demo_then_play":
            self._radio_demo_then_play.setChecked(True)
        else:
            self._radio_manual.setChecked(True)
        self._spin_after_delay.setValue(v.get("after_song_delay", 2))
        self._chk_acoustid.setChecked(v.get("acoustid_enabled", False))
        self._acoustid_key.setText(v.get("acoustid_api_key", ""))

    # ── Gem ───────────────────────────────────────────────────────────────────

    def _save_and_close(self):
        values = {
            "dark_theme":          self._chk_dark.isChecked(),
            "demo_seconds":        self._spin_demo.value(),
            "demo_fade_seconds":   self._spin_fade.value(),
            "between_seconds":     self._spin_between.value(),
            "workshop_minutes":    self._spin_workshop.value(),
            "mail_client":         self._mail_combo.currentData(),
            "mail_path":           self._mail_path.text().strip(),
            "auto_login":          self._chk_auto_login.isChecked(),
            "username":            self._user_input.text().strip(),
            "password":            self._pass_input.text(),
            "server_url":          self._server_url.text().strip() or "http://localhost:8000",
            "language":            self._lang_combo.currentData(),
            "audio_device_main":   self._combo_main_device.currentData() or "",
            "audio_device_preview":self._combo_preview_device.currentData() or "",
            "after_song_mode":     (
                "auto_demo"      if self._radio_auto_demo.isChecked() else
                "auto_play"      if self._radio_auto_play.isChecked() else
                "demo_then_play" if self._radio_demo_then_play.isChecked() else
                "manual"
            ),
            "after_song_delay":    self._spin_after_delay.value(),
            "acoustid_enabled":    self._chk_acoustid.isChecked(),
            "acoustid_api_key":    self._acoustid_key.text().strip(),
        }
        save_settings(values)
        self._values = values
        self.accept()

    def get_values(self) -> dict:
        return self._values
