"""
Диалог "Параметры" — настройка внешних инструментов (LibreOffice, Tesseract)
и глобальных параметров сканирования, которые неудобно размещать на основной
панели (бывают нужны реже, чем основные настройки поиска).

Кнопки «Определить» рядом с полями путей вызывают автопоиск исполняемых
файлов в PATH и стандартных каталогах установки, и подставляют найденный
путь в поле (или сообщают, что программа не найдена).
"""
from __future__ import annotations

from PySide6.QtWidgets import (
    QDialog, QDialogButtonBox, QFormLayout, QGroupBox, QHBoxLayout,
    QLabel, QLineEdit, QPushButton, QSpinBox, QVBoxLayout, QMessageBox,
)

from app.settings_store import load_settings, save_settings, autodetect_external_programs


class SettingsDialog(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("Параметры DSP Scanner")
        self.resize(620, 460)

        s = load_settings()

        layout = QVBoxLayout(self)

        # --- Внешние программы ---
        ext_box = QGroupBox("Внешние программы")
        ext_layout = QFormLayout(ext_box)

        # LibreOffice
        self.libreoffice_path = QLineEdit(s.libreoffice_path or "")
        self.libreoffice_path.setPlaceholderText("не задан — будет использована эвристика OLE2")
        lo_btn = QPushButton("Выбрать…")
        lo_btn.clicked.connect(lambda: self._browse(self.libreoffice_path))
        lo_auto = QPushButton("Определить")
        lo_auto.setToolTip("Найти soffice в PATH или стандартном каталоге установки")
        lo_auto.clicked.connect(self._autodetect_libreoffice)
        lo_row = QHBoxLayout()
        lo_row.addWidget(self.libreoffice_path, 1)
        lo_row.addWidget(lo_btn)
        lo_row.addWidget(lo_auto)
        ext_layout.addRow("LibreOffice (soffice):", lo_row)
        ext_layout.addRow(QLabel("Используется для точного чтения легаси .doc"))

        # Tesseract
        self.tesseract_path = QLineEdit(s.tesseract_path or "")
        self.tesseract_path.setPlaceholderText("не задан — OCR будет недоступен")
        ts_btn = QPushButton("Выбрать…")
        ts_btn.clicked.connect(lambda: self._browse(self.tesseract_path))
        ts_auto = QPushButton("Определить")
        ts_auto.setToolTip("Найти tesseract в PATH")
        ts_auto.clicked.connect(self._autodetect_tesseract)
        ts_row = QHBoxLayout()
        ts_row.addWidget(self.tesseract_path, 1)
        ts_row.addWidget(ts_btn)
        ts_row.addWidget(ts_auto)
        ext_layout.addRow("Tesseract OCR:", ts_row)
        ext_layout.addRow(QLabel("Используется для распознавания сканированных PDF"))

        # Кнопка "Определить всё"
        detect_all_btn = QPushButton("Определить все автоматически")
        detect_all_btn.clicked.connect(self._autodetect_all)
        ext_layout.addRow("", detect_all_btn)

        layout.addWidget(ext_box)

        # --- Производительность ---
        perf_box = QGroupBox("Производительность")
        perf_layout = QFormLayout(perf_box)

        self.max_workers = QSpinBox()
        self.max_workers.setRange(1, 128)
        self.max_workers.setValue(s.max_workers)
        self.max_workers.setToolTip("Число потоков параллельной обработки файлов (1–128)")
        perf_layout.addRow("Число потоков обработки:", self.max_workers)

        self.per_file_timeout = QSpinBox()
        self.per_file_timeout.setRange(10, 600)
        self.per_file_timeout.setValue(s.per_file_timeout)
        self.per_file_timeout.setSuffix(" с")
        perf_layout.addRow("Таймаут на один файл:", self.per_file_timeout)
        perf_layout.addRow(QLabel("Защита от зависания на повреждённых файлах"))

        self.max_matches = QSpinBox()
        self.max_matches.setRange(1, 500)
        self.max_matches.setValue(s.max_matches_per_word)
        perf_layout.addRow("Макс. совпадений на слово/файл:", self.max_matches)

        layout.addWidget(perf_box)

        # --- Безопасность ---
        sec_box = QGroupBox("Безопасное удаление")
        sec_layout = QFormLayout(sec_box)
        self.secure_passes = QSpinBox()
        self.secure_passes.setRange(1, 7)
        self.secure_passes.setValue(s.secure_passes)
        sec_layout.addRow("Число проходов перезаписи:", self.secure_passes)
        sec_layout.addRow(QLabel("Рекомендуется 3 прохода (DoD 5220.22-M)"))
        layout.addWidget(sec_box)

        # --- Кнопки ---
        buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        buttons.accepted.connect(self._accept)
        buttons.rejected.connect(self.reject)
        layout.addWidget(buttons)

    # ------------------------------------------------------------------ #
    def _browse(self, line_edit: QLineEdit) -> None:
        from PySide6.QtWidgets import QFileDialog
        path, _ = QFileDialog.getOpenFileName(self, "Выберите исполняемый файл")
        if path:
            line_edit.setText(path)

    def _autodetect_libreoffice(self) -> None:
        lo, _ = autodetect_external_programs()
        if lo:
            self.libreoffice_path.setText(lo)
            QMessageBox.information(self, "LibreOffice найден", f"Найден путь:\n{lo}")
        else:
            QMessageBox.warning(
                self, "LibreOffice не найден",
                "Не удалось найти soffice в PATH или стандартных каталогах.\n"
                "Установите LibreOffice или укажите путь к soffice вручную.",
            )

    def _autodetect_tesseract(self) -> None:
        _, ts = autodetect_external_programs()
        if ts:
            self.tesseract_path.setText(ts)
            QMessageBox.information(self, "Tesseract найден", f"Найден путь:\n{ts}")
        else:
            QMessageBox.warning(
                self, "Tesseract не найден",
                "Не удалось найти tesseract в PATH.\n"
                "Установите Tesseract OCR или укажите путь к исполняемому файлу вручную.\n\n"
                "Скачать: https://github.com/tesseract-ocr/tesseract",
            )

    def _autodetect_all(self) -> None:
        lo, ts = autodetect_external_programs()
        found = []
        if lo:
            self.libreoffice_path.setText(lo)
            found.append(f"LibreOffice: {lo}")
        if ts:
            self.tesseract_path.setText(ts)
            found.append(f"Tesseract: {ts}")
        if found:
            QMessageBox.information(
                self, "Автоопределение завершено",
                "Найдено:\n\n" + "\n".join(found),
            )
        else:
            QMessageBox.warning(
                self, "Автоопределение завершено",
                "Ни LibreOffice, ни Tesseract не найдены в системе.\n"
                "Установите их или укажите пути вручную.",
            )

    def _accept(self) -> None:
        s = load_settings()
        s.libreoffice_path = self.libreoffice_path.text().strip() or None
        s.tesseract_path = self.tesseract_path.text().strip() or None
        s.max_workers = self.max_workers.value()
        s.per_file_timeout = self.per_file_timeout.value()
        s.max_matches_per_word = self.max_matches.value()
        s.secure_passes = self.secure_passes.value()
        save_settings(s)
        self.accept()
