"""Recordings screen — list MP3s, play, transcribe, summarize, rename, delete, favorite."""

from __future__ import annotations

import threading
import time
from pathlib import Path

from PySide6.QtCore import QObject, Qt, Signal, Slot
from PySide6.QtGui import QKeySequence, QShortcut
from PySide6.QtWidgets import (
    QAbstractItemView,
    QHBoxLayout,
    QHeaderView,
    QInputDialog,
    QLabel,
    QMenu,
    QMessageBox,
    QPushButton,
    QSplitter,
    QTableWidget,
    QTableWidgetItem,
    QVBoxLayout,
    QWidget,
)

from meeting_helper.gui.widgets.media_player import MediaPlayerWidget
from meeting_helper.gui.widgets.transcript_view import TranscriptView


class _Worker(QObject):
    """Background worker for transcription/summarization."""
    finished = Signal(str, str)  # (result_text, error)

    def __init__(self, task: str, path: Path, config):
        super().__init__()
        self.task = task
        self.path = path
        self.config = config

    def run(self):
        try:
            if self.task == "transcribe":
                from meeting_helper.ai.client import transcribe_audio_file
                result = transcribe_audio_file(str(self.path), self.config)
                self.finished.emit(result, "")
            elif self.task == "summarize":
                import asyncio
                from meeting_helper.ai.client import summarize_transcript
                result = asyncio.run(summarize_transcript(str(self.path), self.config))
                self.finished.emit(result, "")
        except Exception as exc:
            self.finished.emit("", str(exc))


def _format_duration(mp3: Path) -> str:
    try:
        import subprocess
        result = subprocess.run(
            ["ffprobe", "-v", "quiet", "-show_entries", "format=duration",
             "-of", "default=noprint_wrappers=1:nokey=1", str(mp3)],
            capture_output=True, text=True, timeout=3,
        )
        if result.returncode == 0:
            secs = float(result.stdout.strip())
            mins, s = divmod(int(secs), 60)
            hrs, mins = divmod(mins, 60)
            return f"{hrs}:{mins:02d}:{s:02d}" if hrs else f"{mins}:{s:02d}"
    except Exception:
        pass
    return "—"


def _clean_name(stem: str) -> str:
    """Strip timestamp prefix and return a readable name."""
    parts = stem.split("_", 2)
    if len(parts) >= 2 and len(parts[0]) == 10 and "-" in parts[0]:
        # YYYY-MM-DD_HH-MM-SS_Name → Name
        rest = "_".join(parts[2:]) if len(parts) > 2 else stem
        return rest.replace("_", " ") or stem
    return stem.replace("_", " ")


def _timestamp_prefix(stem: str) -> str:
    """Return the YYYY-MM-DD_HH-MM-SS_ prefix if present, else empty string."""
    parts = stem.split("_", 2)
    if len(parts) >= 2 and len(parts[0]) == 10 and "-" in parts[0]:
        return f"{parts[0]}_{parts[1]}_"
    return ""


class RecordingsScreen(QWidget):
    """Browse recordings, play audio, transcribe, summarize, rename, delete, favorite."""

    def __init__(self, parent=None):
        super().__init__(parent)
        self._recordings_dir: Path | None = None
        self._current_mp3: Path | None = None
        self._config = None       # AppConfig — for transcription/summarization
        self._raw_config = None   # Config — for favorites/rename
        self._mp3s: list[Path] = []
        self._active_worker = None
        self._setup_ui()

    def _setup_ui(self):
        layout = QVBoxLayout(self)
        layout.setContentsMargins(30, 30, 30, 30)
        layout.setSpacing(15)

        # Header
        header_row = QHBoxLayout()
        header = QLabel("Recordings")
        header.setStyleSheet("font-size: 22px; font-weight: 600; color: #ffffff;")
        header_row.addWidget(header)
        header_row.addStretch()

        refresh_btn = QPushButton("Refresh")
        refresh_btn.setStyleSheet("background-color: #2a2a2a; color: #d4d4d4; min-width: 70px;")
        refresh_btn.clicked.connect(self.refresh)
        header_row.addWidget(refresh_btn)
        layout.addLayout(header_row)

        # Splitter: table on top, detail on bottom
        splitter = QSplitter(Qt.Vertical)

        # Table — columns: ★, Name, Duration, Date
        self._table = QTableWidget()
        self._table.setColumnCount(4)
        self._table.setHorizontalHeaderLabels(["★", "Name", "Duration", "Date"])
        self._table.setSelectionBehavior(QAbstractItemView.SelectRows)
        self._table.setSelectionMode(QAbstractItemView.SingleSelection)
        self._table.setAlternatingRowColors(False)
        self._table.setSortingEnabled(False)
        self._table.verticalHeader().setVisible(False)
        self._table.setEditTriggers(QAbstractItemView.NoEditTriggers)

        hdr = self._table.horizontalHeader()
        hdr.setSectionResizeMode(0, QHeaderView.Fixed)
        self._table.setColumnWidth(0, 36)
        hdr.setSectionResizeMode(1, QHeaderView.Stretch)
        hdr.setSectionResizeMode(2, QHeaderView.ResizeToContents)
        hdr.setSectionResizeMode(3, QHeaderView.ResizeToContents)

        self._table.currentCellChanged.connect(self._on_selection_changed)
        self._table.cellClicked.connect(self._on_cell_clicked)

        # Right-click context menu
        self._table.setContextMenuPolicy(Qt.CustomContextMenu)
        self._table.customContextMenuRequested.connect(self._show_context_menu)

        # Keyboard shortcuts
        QShortcut(QKeySequence(Qt.Key_Delete), self._table).activated.connect(self._delete_selected)
        QShortcut(QKeySequence(Qt.Key_Backspace), self._table).activated.connect(self._delete_selected)

        splitter.addWidget(self._table)

        # Detail panel
        detail = QWidget()
        detail_layout = QVBoxLayout(detail)
        detail_layout.setContentsMargins(0, 10, 0, 0)

        btn_row = QHBoxLayout()
        self._transcribe_btn = QPushButton("Transcribe")
        self._transcribe_btn.setEnabled(False)
        self._transcribe_btn.clicked.connect(self._do_transcribe)
        btn_row.addWidget(self._transcribe_btn)

        self._summarize_btn = QPushButton("Summarize")
        self._summarize_btn.setEnabled(False)
        self._summarize_btn.clicked.connect(self._do_summarize)
        btn_row.addWidget(self._summarize_btn)

        self._status_label = QLabel("")
        self._status_label.setStyleSheet("color: #808080; font-size: 12px;")
        btn_row.addWidget(self._status_label)
        btn_row.addStretch()
        detail_layout.addLayout(btn_row)

        self._player = MediaPlayerWidget()
        detail_layout.addWidget(self._player)

        self._transcript_view = TranscriptView()
        detail_layout.addWidget(self._transcript_view, 1)

        splitter.addWidget(detail)
        splitter.setSizes([300, 400])
        layout.addWidget(splitter, 1)

    def set_config(self, config, raw_config=None):
        self._config = config
        self._raw_config = raw_config  # Config object with favorites/rename support

    def set_recordings_dir(self, path: Path):
        self._recordings_dir = path
        self.refresh()

    def refresh(self):
        self._table.setRowCount(0)
        if not self._recordings_dir or not self._recordings_dir.is_dir():
            return

        self._mp3s = sorted(
            self._recordings_dir.glob("*.mp3"),
            key=lambda p: p.stat().st_mtime,
            reverse=True,
        )

        self._table.setRowCount(len(self._mp3s))
        for row, mp3 in enumerate(self._mp3s):
            is_fav = self._raw_config.is_favorite(mp3.name) if self._raw_config else False

            # Col 0: star
            star = QTableWidgetItem("★" if is_fav else "☆")
            star.setTextAlignment(Qt.AlignCenter)
            star.setForeground(Qt.yellow if is_fav else Qt.gray)
            star.setFlags(star.flags() & ~Qt.ItemIsEditable)
            self._table.setItem(row, 0, star)

            # Col 1: name
            has_transcript = mp3.with_suffix(".transcript.txt").exists()
            display = _clean_name(mp3.stem)
            name_item = QTableWidgetItem(display)
            name_item.setData(Qt.UserRole, str(mp3))
            name_item.setFlags(name_item.flags() & ~Qt.ItemIsEditable)
            if has_transcript:
                name_item.setForeground(Qt.green)
            self._table.setItem(row, 1, name_item)

            # Col 2: duration
            dur_item = QTableWidgetItem(_format_duration(mp3))
            dur_item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter)
            dur_item.setFlags(dur_item.flags() & ~Qt.ItemIsEditable)
            self._table.setItem(row, 2, dur_item)

            # Col 3: date
            mtime = mp3.stat().st_mtime
            date_item = QTableWidgetItem(time.strftime("%Y-%m-%d %H:%M", time.localtime(mtime)))
            date_item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter)
            date_item.setFlags(date_item.flags() & ~Qt.ItemIsEditable)
            self._table.setItem(row, 3, date_item)

    def _get_selected_mp3(self) -> Path | None:
        row = self._table.currentRow()
        if 0 <= row < len(self._mp3s):
            return self._mp3s[row]
        return None

    def _on_cell_clicked(self, row: int, col: int):
        if col == 0:
            self._toggle_favorite(row)

    def _on_selection_changed(self, row: int, col: int, prev_row: int, prev_col: int):
        if row < 0:
            return
        item = self._table.item(row, 1)
        if not item:
            return
        mp3_path = Path(item.data(Qt.UserRole))
        self._current_mp3 = mp3_path
        self._player.load(mp3_path)
        self._transcribe_btn.setEnabled(True)
        self._status_label.setText("")

        transcript_path = mp3_path.with_suffix(".transcript.txt")
        summary_path = mp3_path.with_suffix(".summary.txt")
        if summary_path.exists():
            self._transcript_view.load_file(summary_path)
            self._summarize_btn.setEnabled(False)
        elif transcript_path.exists():
            self._transcript_view.load_file(transcript_path)
            self._summarize_btn.setEnabled(True)
        else:
            live_path = mp3_path.with_suffix(".live.txt")
            if live_path.exists():
                self._transcript_view.load_file(live_path)
            else:
                self._transcript_view.clear()
            self._summarize_btn.setEnabled(False)

    def _show_context_menu(self, position):
        row = self._table.rowAt(position.y())
        if row < 0 or row >= len(self._mp3s):
            return
        self._table.selectRow(row)
        mp3 = self._mp3s[row]
        is_fav = self._raw_config.is_favorite(mp3.name) if self._raw_config else False

        menu = QMenu(self)

        has_transcript = mp3.with_suffix(".transcript.txt").exists()
        if not has_transcript:
            transcribe_action = menu.addAction("🎙 Transcribe")
            transcribe_action.triggered.connect(self._do_transcribe)
            menu.addSeparator()

        fav_action = menu.addAction("☆ Remove Favorite" if is_fav else "★ Add Favorite")
        fav_action.triggered.connect(lambda: self._toggle_favorite(row))

        rename_action = menu.addAction("✏ Rename")
        rename_action.triggered.connect(self._rename_selected)

        menu.addSeparator()

        delete_action = menu.addAction("✕ Delete")
        delete_action.triggered.connect(self._delete_selected)

        menu.exec_(self._table.viewport().mapToGlobal(position))

    def _toggle_favorite(self, row: int):
        if not self._raw_config or row < 0 or row >= len(self._mp3s):
            return
        mp3 = self._mp3s[row]
        if self._raw_config.is_favorite(mp3.name):
            self._raw_config.remove_favorite(mp3.name)
        else:
            self._raw_config.add_favorite(mp3.name)
        self.refresh()
        self._table.selectRow(row)

    def _rename_selected(self):
        mp3 = self._get_selected_mp3()
        if not mp3:
            return

        prefix = _timestamp_prefix(mp3.stem)
        current_name = _clean_name(mp3.stem)

        new_name, ok = QInputDialog.getText(
            self, "Rename Recording", "New name:", text=current_name
        )
        if not ok or not new_name.strip():
            return

        new_name = new_name.strip().replace(" ", "_")
        new_stem = f"{prefix}{new_name}" if prefix else new_name
        new_mp3 = mp3.parent / f"{new_stem}.mp3"

        if new_mp3.exists():
            QMessageBox.warning(self, "Rename Failed", "A file with that name already exists.")
            return

        try:
            # Rename MP3 and all associated files
            for suffix in (".mp3", ".transcript.txt", ".summary.txt", ".live.txt"):
                old = mp3.parent / f"{mp3.stem}{suffix}"
                if old.exists():
                    old.rename(mp3.parent / f"{new_stem}{suffix}")

            # Update favorite key if needed
            if self._raw_config and self._raw_config.is_favorite(mp3.name):
                self._raw_config.remove_favorite(mp3.name)
                self._raw_config.add_favorite(new_mp3.name)

            self._status_label.setText(f"Renamed to: {new_name}")
            self.refresh()
        except Exception as exc:
            QMessageBox.warning(self, "Rename Failed", str(exc))

    def _delete_selected(self):
        mp3 = self._get_selected_mp3()
        if not mp3:
            return

        name = _clean_name(mp3.stem)
        files = [f for f in [
            mp3,
            mp3.with_suffix(".transcript.txt"),
            mp3.with_suffix(".summary.txt"),
            mp3.with_suffix(".live.txt"),
        ] if f.exists()]

        reply = QMessageBox.question(
            self, "Delete Recording",
            f"Delete '{name}'?\n\nThis will permanently remove {len(files)} file(s).",
            QMessageBox.Yes | QMessageBox.No,
        )
        if reply != QMessageBox.Yes:
            return

        try:
            for f in files:
                f.unlink()
            if self._config:
                if self._raw_config:
                    self._raw_config.remove_favorite(mp3.name)
            self._current_mp3 = None
            self._player.load(None)
            self._transcript_view.clear()
            self._transcribe_btn.setEnabled(False)
            self._summarize_btn.setEnabled(False)
            self._status_label.setText(f"Deleted: {name}")
            self.refresh()
        except Exception as exc:
            QMessageBox.warning(self, "Delete Failed", str(exc))

    def _do_transcribe(self):
        if not self._current_mp3 or not self._config:
            return
        self._transcribe_btn.setEnabled(False)
        self._summarize_btn.setEnabled(False)
        self._status_label.setText("Transcribing...")
        self._status_label.setStyleSheet("color: #dcdcaa; font-size: 12px;")
        worker = _Worker("transcribe", self._current_mp3, self._config)
        worker.finished.connect(self._on_transcribe_done)
        thread = threading.Thread(target=worker.run, daemon=True)
        thread.start()
        self._active_worker = worker

    @Slot(str, str)
    def _on_transcribe_done(self, result: str, error: str):
        if error:
            self._status_label.setText(f"Error: {error}")
            self._status_label.setStyleSheet("color: #f14c4c; font-size: 12px;")
            self._transcribe_btn.setEnabled(True)
        else:
            self._status_label.setText("Transcription complete")
            self._status_label.setStyleSheet("color: #4ec9b0; font-size: 12px;")
            self._transcript_view.set_title("Transcript")
            self._transcript_view.set_text(result)
            self._summarize_btn.setEnabled(True)
            self._transcribe_btn.setEnabled(True)
            self.refresh()

    def _do_summarize(self):
        if not self._current_mp3 or not self._config:
            return
        transcript_path = self._current_mp3.with_suffix(".transcript.txt")
        if not transcript_path.exists():
            live_path = self._current_mp3.with_suffix(".live.txt")
            if live_path.exists():
                transcript_path = live_path
            else:
                self._status_label.setText("No transcript to summarize")
                return
        self._summarize_btn.setEnabled(False)
        self._status_label.setText("Summarizing...")
        self._status_label.setStyleSheet("color: #dcdcaa; font-size: 12px;")
        worker = _Worker("summarize", transcript_path, self._config)
        worker.finished.connect(self._on_summarize_done)
        thread = threading.Thread(target=worker.run, daemon=True)
        thread.start()
        self._active_worker = worker

    @Slot(str, str)
    def _on_summarize_done(self, result: str, error: str):
        if error:
            self._status_label.setText(f"Error: {error}")
            self._status_label.setStyleSheet("color: #f14c4c; font-size: 12px;")
            self._summarize_btn.setEnabled(True)
        else:
            self._status_label.setText("Summary complete")
            self._status_label.setStyleSheet("color: #4ec9b0; font-size: 12px;")
            self._transcript_view.set_title("Summary")
            self._transcript_view.set_text(result)
