# tabs/sandbox_tab.py
import subprocess
import tempfile
import os
import threading
import asyncio
from PyQt6.QtWidgets import (
    QWidget, QVBoxLayout, QHBoxLayout, QLabel, 
    QLineEdit, QPushButton, QTableWidget, QTableWidgetItem, \
    QHeaderView, QMessageBox, QFormLayout, QDialog, QTextEdit, QRadioButton, QButtonGroup
)
from PyQt6.QtCore import pyqtSignal, pyqtSlot, Qt
import edge_tts
import database
from tts_utils import parse_text_for_edgetts, get_configured_tts_rate


class TextEditorDialog(QDialog):
    """A pop-up modal containing a large text field workspace for copy-pasting extra text blocks or drafting HTML content."""
    def __init__(self, title, initial_text="", parent=None):
        super().__init__(parent)
        self.setWindowTitle(title)
        self.resize(650, 450)
        layout = QVBoxLayout(self)
        
        info_label = QLabel("Edit text or raw HTML below (supports tables, lists, and inline styles):")
        info_label.setStyleSheet("color: #7F8C8D; font-size: 12px;")
        layout.addWidget(info_label)
        
        self.editor = QTextEdit()
        self.editor.setPlainText(initial_text)
        # Monospaced font for clean HTML readability
        self.editor.setStyleSheet("font-family: monospace; font-size: 13px; background-color: #2C3E50; color: #ECF0F1; padding: 8px;")
        layout.addWidget(self.editor)
        
        btn_layout = QHBoxLayout()
        self.btn_save = QPushButton("Save / Apply")
        self.btn_save.setStyleSheet("background-color: #27AE60; color: white; font-weight: bold; padding: 6px 14px;")
        self.btn_save.clicked.connect(self.accept)
        
        self.btn_cancel = QPushButton("Cancel")
        self.btn_cancel.setStyleSheet("padding: 6px 14px;")
        self.btn_cancel.clicked.connect(self.reject)
        
        btn_layout.addStretch()
        btn_layout.addWidget(self.btn_cancel)
        btn_layout.addWidget(self.btn_save)
        layout.addLayout(btn_layout)

    def get_text(self):
        return self.editor.toPlainText().strip()


class SandboxTab(QWidget):
    data_mutated = pyqtSignal()

    def __init__(self, parent=None):
        super().__init__(parent)
        self.selected_translation_id = None
        
        # Local item memory caching for instant search lookups
        self.cached_records = []
        self.current_notes_content = ""
        self.current_anki_notes_content = ""
        
        main_layout = QVBoxLayout(self)
        main_layout.setContentsMargins(30, 20, 30, 20)
        main_layout.setSpacing(15)
        
        # --- SECTION 1: FORM INPUT CRADLE ---
        form_container = QWidget()
        form_layout = QFormLayout(form_container)
        form_layout.setLabelAlignment(Qt.AlignmentFlag.AlignRight)
        form_layout.setSpacing(10)
        
        # --- English Input Row ---
        english_widget = QWidget()
        english_layout = QHBoxLayout(english_widget)
        english_layout.setContentsMargins(0, 0, 0, 0)
        english_layout.setSpacing(8)

        self.txt_english = QLineEdit()
        self.txt_english.setPlaceholderText("Enter English phrase (filters grid real-time)...")
        self.txt_english.setStyleSheet("padding: 6px; font-size: 14px;")
        self.txt_english.textChanged.connect(self.apply_live_grid_filter)
        
        self.btn_edit_english = QPushButton("✏️ Edit English Block")
        self.btn_edit_english.setStyleSheet("padding: 6px 12px; font-weight: bold; background-color: #34495E; color: white; border-radius: 4px;")
        self.btn_edit_english.clicked.connect(self.open_english_editor)
        
        english_layout.addWidget(self.txt_english, stretch=1)
        english_layout.addWidget(self.btn_edit_english, stretch=0)
        
        # --- Spanish Input Row ---
        spanish_widget = QWidget()
        spanish_layout = QHBoxLayout(spanish_widget)
        spanish_layout.setContentsMargins(0, 0, 0, 0)
        spanish_layout.setSpacing(8)

        self.txt_spanish = QLineEdit()
        self.txt_spanish.setPlaceholderText("Enter Spanish phrase (filters grid real-time)...")
        self.txt_spanish.setStyleSheet("padding: 6px; font-size: 14px;")
        self.txt_spanish.textChanged.connect(self.apply_live_grid_filter)
        
        self.btn_edit_spanish = QPushButton("✏️ Edit Spanish Block")
        self.btn_edit_spanish.setStyleSheet("padding: 6px 12px; font-weight: bold; background-color: #34495E; color: white; border-radius: 4px;")
        self.btn_edit_spanish.clicked.connect(self.open_spanish_editor)
        
        spanish_layout.addWidget(self.txt_spanish, stretch=1)
        spanish_layout.addWidget(self.btn_edit_spanish, stretch=0)
        
        self.txt_context = QLineEdit()
        self.txt_context.setPlaceholderText("Context e.g., Camino 2027 (filters grid real-time)...")
        self.txt_context.setStyleSheet("padding: 6px; font-size: 14px;")
        self.txt_context.textChanged.connect(self.apply_live_grid_filter)
        
        self.txt_tags = QLineEdit()
        self.txt_tags.setPlaceholderText("Comma separated tags (filters grid real-time)...")
        self.txt_tags.setStyleSheet("padding: 6px; font-size: 14px;")
        self.txt_tags.textChanged.connect(self.apply_live_grid_filter)
        
        # Modal Editor Row Buttons for Extended Notes
        editor_buttons_layout = QHBoxLayout()
        self.btn_edit_notes = QPushButton("📝 Edit Notes Block")
        self.btn_edit_notes.clicked.connect(self.open_notes_editor)
        
        self.btn_edit_anki_notes = QPushButton("🗂️ Edit Anki Notes Block")
        self.btn_edit_anki_notes.clicked.connect(self.open_anki_notes_editor)
        
        editor_buttons_layout.addWidget(self.btn_edit_notes)
        editor_buttons_layout.addWidget(self.btn_edit_anki_notes)
        
        # Add container widgets to QFormLayout rows
        form_layout.addRow(QLabel("<b>English Phrase:</b>"), english_widget)
        form_layout.addRow(QLabel("<b>Spanish Translation:</b>"), spanish_widget)
        form_layout.addRow(QLabel("<b>Source Context:</b>"), self.txt_context)
        form_layout.addRow(QLabel("<b>Tags:</b>"), self.txt_tags)
        form_layout.addRow(QLabel("<b>Extended Data Fields:</b>"), editor_buttons_layout)
        
        main_layout.addWidget(form_container)
        
        # --- INLINE AUDIO CONTROL + GENDER SELECTION PANEL ---
        audio_panel = QHBoxLayout()
        audio_panel.setSpacing(15)
        
        self.btn_test_en = QPushButton("🔊 Test English Voice")
        self.btn_test_en.clicked.connect(self.audition_english)
        
        self.btn_test_es = QPushButton("🔊 Test Spanish Voice")
        self.btn_test_es.clicked.connect(self.audition_spanish)
        
        gender_label = QLabel("<b>Speaker Gender:</b>")
        self.rb_female = QRadioButton("Female")
        self.rb_male = QRadioButton("Male")
        self.rb_female.setChecked(True)
        
        self.gender_group = QButtonGroup(self)
        self.gender_group.addButton(self.rb_female)
        self.gender_group.addButton(self.rb_male)
        
        audio_panel.addWidget(self.btn_test_en)
        audio_panel.addWidget(self.btn_test_es)
        audio_panel.addSpacing(20)
        audio_panel.addWidget(gender_label)
        audio_panel.addWidget(self.rb_female)
        audio_panel.addWidget(self.rb_male)
        audio_panel.addStretch()
        
        main_layout.addLayout(audio_panel)
        
        # --- ACTION CONTROL BAR ---
        actions_layout = QHBoxLayout()
        self.btn_save_record = QPushButton("📥 Save Transaction")
        self.btn_save_record.clicked.connect(self.commit_form_entry)
        self.btn_save_record.setStyleSheet("background-color: #27AE60; color: white; font-weight: bold; padding: 8px 16px;")
        
        self.btn_clear_form = QPushButton("🧹 Reset Fields")
        self.btn_clear_form.clicked.connect(self.clear_form_fields)
        
        self.btn_delete_record = QPushButton("🗑️ Delete Selected")
        self.btn_delete_record.clicked.connect(self.remove_target_record)
        self.btn_delete_record.setStyleSheet("background-color: #C0392B; color: white;")
        
        actions_layout.addWidget(self.btn_save_record)
        actions_layout.addWidget(self.btn_clear_form)
        actions_layout.addWidget(self.btn_delete_record)
        actions_layout.addStretch()
        main_layout.addLayout(actions_layout)
        
        # --- VIEWPORT GRID TABLE ---
        self.table = QTableWidget()
        self.table.setColumnCount(6)
        self.table.setHorizontalHeaderLabels(["ID", "English", "Spanish", "Context", "Tags", "Gender"])
        self.table.setSelectionBehavior(QTableWidget.SelectionBehavior.SelectRows)
        self.table.setEditTriggers(QTableWidget.EditTrigger.NoEditTriggers)
        self.table.cellClicked.connect(self.populate_form_from_grid)
        
        header = self.table.horizontalHeader()
        header.setSectionResizeMode(0, QHeaderView.ResizeMode.ResizeToContents)
        header.setSectionResizeMode(1, QHeaderView.ResizeMode.Stretch)
        header.setSectionResizeMode(2, QHeaderView.ResizeMode.Stretch)
        
        main_layout.addWidget(self.table)
        self.reload_table_display()

    @pyqtSlot()
    def open_english_editor(self):
        dlg = TextEditorDialog("Edit English Phrase / HTML Block", self.txt_english.text(), self)
        if dlg.exec():
            self.txt_english.setText(dlg.get_text())

    @pyqtSlot()
    def open_spanish_editor(self):
        dlg = TextEditorDialog("Edit Spanish Translation / HTML Block", self.txt_spanish.text(), self)
        if dlg.exec():
            self.txt_spanish.setText(dlg.get_text())

    @pyqtSlot()
    def open_notes_editor(self):
        dlg = TextEditorDialog("Edit Grammar / Core Notes Block", self.current_notes_content, self)
        if dlg.exec():
            self.current_notes_content = dlg.get_text()

    @pyqtSlot()
    def open_anki_notes_editor(self):
        dlg = TextEditorDialog("Edit Anki Specialized Meta Field", self.current_anki_notes_content, self)
        if dlg.exec():
            self.current_anki_notes_content = dlg.get_text()

    def clear_form_fields(self):
        self.txt_english.blockSignals(True)
        self.txt_spanish.blockSignals(True)
        self.txt_context.blockSignals(True)
        self.txt_tags.blockSignals(True)

        self.selected_translation_id = None
        self.txt_english.clear()
        self.txt_spanish.clear()
        self.txt_context.clear()
        self.txt_tags.clear()
        self.current_notes_content = ""
        self.current_anki_notes_content = ""
        self.rb_female.setChecked(True)

        self.txt_english.blockSignals(False)
        self.txt_spanish.blockSignals(False)
        self.txt_context.blockSignals(False)
        self.txt_tags.blockSignals(False)
        
        self.apply_live_grid_filter()

    @pyqtSlot()
    def commit_form_entry(self):
        en_t = self.txt_english.text().strip()
        es_t = self.txt_spanish.text().strip()
        ctx_t = self.txt_context.text().strip()
        tag_t = self.txt_tags.text().strip()
        gender_t = "Male" if self.rb_male.isChecked() else "Female"

        if not en_t or not es_t:
            QMessageBox.warning(self, "Validation Alert", "English and Spanish phrase properties cannot remain blank.")
            return

        if self.selected_translation_id is None:
            database.insert_translation_record(es_t, en_t, ctx_t, tag_t, self.current_notes_content, gender_t, self.current_anki_notes_content)
        else:
            database.update_translation_record(self.selected_translation_id, es_t, en_t, ctx_t, tag_t, self.current_notes_content, gender_t, self.current_anki_notes_content)
        
        self.clear_form_fields()
        self.reload_table_display()
        self.data_mutated.emit()

    @pyqtSlot()
    def remove_target_record(self):
        if self.selected_translation_id is None:
            QMessageBox.warning(self, "Selection Missing", "Please select a row from the grid viewport before attempting deletion.")
            return

        confirm = QMessageBox.question(
            self, 
            "Confirm Deletion", 
            "Are you sure you want to permanently delete this translation record?",
            QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No
        )
        
        if confirm == QMessageBox.StandardButton.Yes:
            database.delete_translation_record(self.selected_translation_id)
            self.clear_form_fields()
            self.reload_table_display()
            self.data_mutated.emit()

    def populate_form_from_grid(self, row, col):
        self.selected_translation_id = int(self.table.item(row, 0).text())
        record = database.get_translation_by_id(self.selected_translation_id)
        
        if record:
            self.txt_english.blockSignals(True)
            self.txt_spanish.blockSignals(True)
            self.txt_context.blockSignals(True)
            self.txt_tags.blockSignals(True)

            self.txt_english.setText(record["en_text"])
            self.txt_spanish.setText(record["es_text"])
            self.txt_context.setText(record.get("source_context", ""))
            self.txt_tags.setText(record.get("tags", ""))
            self.current_notes_content = record.get("notes", "")
            self.current_anki_notes_content = record.get("anki_notes", "")
            
            if record.get("gender") == "Male":
                self.rb_male.setChecked(True)
            else:
                self.rb_female.setChecked(True)

            self.txt_english.blockSignals(False)
            self.txt_spanish.blockSignals(False)
            self.txt_context.blockSignals(False)
            self.txt_tags.blockSignals(False)

    def reload_table_display(self):
        self.cached_records = database.get_all_translations_explicit()
        self.apply_live_grid_filter()

    @pyqtSlot()
    def apply_live_grid_filter(self):
        filter_en = self.txt_english.text().lower().strip()
        filter_es = self.txt_spanish.text().lower().strip()
        filter_ctx = self.txt_context.text().lower().strip()
        filter_tags = self.txt_tags.text().lower().strip()

        self.table.setRowCount(0)
        visible_row_idx = 0

        for r in self.cached_records:
            match_en = filter_en in (r.get("en_text") or "").lower()
            match_es = filter_es in (r.get("es_text") or "").lower()
            match_ctx = filter_ctx in (r.get("source_context") or "").lower()
            match_tags = filter_tags in (r.get("tags") or "").lower()

            if match_en and match_es and match_ctx and match_tags:
                self.table.insertRow(visible_row_idx)
                self.table.setItem(visible_row_idx, 0, QTableWidgetItem(str(r["translation_id"])))
                self.table.setItem(visible_row_idx, 1, QTableWidgetItem(r["en_text"]))
                self.table.setItem(visible_row_idx, 2, QTableWidgetItem(r["es_text"]))
                self.table.setItem(visible_row_idx, 3, QTableWidgetItem(r.get("source_context", "")))
                self.table.setItem(visible_row_idx, 4, QTableWidgetItem(r.get("tags", "")))
                self.table.setItem(visible_row_idx, 5, QTableWidgetItem(r.get("gender", "Female")))
                visible_row_idx += 1

    def _async_edge_speech_worker(self, text, voice, rate_modifier):
        """Background thread worker to download neural audio and play it without freezing the UI."""
        async def stream_audio():
            temp_file = os.path.join(tempfile.gettempdir(), "sandbox_audition.mp3")
            try:
                communicate = edge_tts.Communicate(text=text, voice=voice, rate=rate_modifier)
                await communicate.save(temp_file)
                if os.path.exists(temp_file):
                    subprocess.run(["afplay", temp_file])
            except Exception as e:
                print(f"Sandbox Audition Error: {e}")

        asyncio.run(stream_audio())

    @pyqtSlot()
    def audition_english(self):
        raw_txt = self.txt_english.text().strip()
        spoken_text = parse_text_for_edgetts(raw_txt)
        
        if not spoken_text.strip():
            return
            
        settings = database.load_all_settings() or {}
        rate_string = get_configured_tts_rate(settings)
            
        threading.Thread(
            target=self._async_edge_speech_worker, 
            args=(spoken_text, "en-US-EmmaNeural", rate_string), 
            daemon=True
        ).start()

    @pyqtSlot()
    def audition_spanish(self):
        raw_txt = self.txt_spanish.text().strip()
        spoken_text = parse_text_for_edgetts(raw_txt)
        
        if not spoken_text.strip():
            return
            
        voice = "es-ES-AlvaroNeural" if self.rb_male.isChecked() else "es-ES-ElviraNeural"
        settings = database.load_all_settings() or {}
        rate_string = get_configured_tts_rate(settings)

        threading.Thread(
            target=self._async_edge_speech_worker, 
            args=(spoken_text, voice, rate_string), 
            daemon=True
        ).start()