#!/usr/bin/env python3
"""
Configure Session Widget - vzug-e-hinge
========================================
Visual command sequence builder.
"""

from PyQt6.QtWidgets import (
    QWidget, QVBoxLayout, QHBoxLayout, QGroupBox, QLabel,
    QLineEdit, QPushButton, QListWidget, QListWidgetItem,
    QMessageBox, QSplitter, QFormLayout, QSpinBox, QComboBox, QCheckBox
)
from PyQt6.QtCore import Qt, pyqtSignal
import json

from database.init_database import DatabaseManager


class ConfigureSessionWidget(QWidget):
    """Visual command sequence builder."""
    
    profile_saved = pyqtSignal(int)
    profile_deleted = pyqtSignal(int)
    
    def __init__(self, db_manager: DatabaseManager):
        super().__init__()
        self.db_manager = db_manager
        self.db_conn = db_manager.get_connection()
        self.current_profile_id = None
        self.command_sequence = []  # List of {command_id, command_name, delay_ms}
        self._init_ui()
        self._load_profiles()
        self._load_uart_commands()
    
    def _init_ui(self):
        """Initialize UI."""
        layout = QVBoxLayout()
        
        title = QLabel("Configure Session Profiles")
        title.setStyleSheet("font-size: 16px; font-weight: bold;")
        layout.addWidget(title)
        
        splitter = QSplitter(Qt.Orientation.Horizontal)
        splitter.addWidget(self._create_list_panel())
        splitter.addWidget(self._create_editor_panel())
        splitter.setSizes([300, 700])
        
        layout.addWidget(splitter)
        self.setLayout(layout)
    
    def _create_list_panel(self):
        """Create profile list panel."""
        widget = QWidget()
        layout = QVBoxLayout()
        
        layout.addWidget(QLabel("Session Profiles:"))
        
        self.profile_list = QListWidget()
        self.profile_list.currentItemChanged.connect(self._on_profile_selected)
        layout.addWidget(self.profile_list)
        
        btn_layout = QHBoxLayout()
        self.btn_add = QPushButton("Add New")
        self.btn_add.clicked.connect(self._on_add_clicked)
        btn_layout.addWidget(self.btn_add)
        
        self.btn_delete = QPushButton("Delete")
        self.btn_delete.clicked.connect(self._on_delete_clicked)
        self.btn_delete.setEnabled(False)
        btn_layout.addWidget(self.btn_delete)
        
        layout.addLayout(btn_layout)
        widget.setLayout(layout)
        return widget
    
    def _create_editor_panel(self):
        """Create visual command builder."""
        widget = QWidget()
        layout = QVBoxLayout()
        
        # Profile name and description
        form = QFormLayout()
        self.name_input = QLineEdit()
        form.addRow("Profile Name:", self.name_input)
        self.desc_input = QLineEdit()
        form.addRow("Description:", self.desc_input)
        
        # Print RX checkbox
        self.print_rx_checkbox = QCheckBox("Print Command RX (disable packet detection & DB saving)")
        self.print_rx_checkbox.setToolTip(
            "Enable: Print raw RX buffer to data monitor, skip database saving\n"
            "Disable: Normal packet detection and database logging"
        )
        form.addRow("", self.print_rx_checkbox)
        
        layout.addLayout(form)
        
        # Add command section
        add_group = QGroupBox("Add Command")
        add_layout = QVBoxLayout()

        add_form = QFormLayout()

        # Command type selector
        self.cmd_type_combo = QComboBox()
        self.cmd_type_combo.addItem("UART", "uart")
        self.cmd_type_combo.addItem("I2C", "i2c")
        self.cmd_type_combo.currentIndexChanged.connect(self._on_command_type_changed)
        add_form.addRow("Command Type:", self.cmd_type_combo)

        # Command selector (will be populated based on type)
        self.cmd_combo = QComboBox()
        add_form.addRow("Command:", self.cmd_combo)

        self.delay_spin = QSpinBox()
        self.delay_spin.setRange(0, 60000)
        self.delay_spin.setValue(3000)
        self.delay_spin.setSuffix(" ms")
        add_form.addRow("Delay After:", self.delay_spin)

        add_layout.addLayout(add_form)

        btn_add_cmd = QPushButton("➕ Add to Sequence")
        btn_add_cmd.clicked.connect(self._on_add_command)
        add_layout.addWidget(btn_add_cmd)
        
        add_group.setLayout(add_layout)
        layout.addWidget(add_group)
        
        # Command sequence list
        seq_group = QGroupBox("Command Sequence")
        seq_layout = QVBoxLayout()
        
        self.sequence_list = QListWidget()
        seq_layout.addWidget(self.sequence_list)
        
        # Sequence controls
        seq_btn_layout = QHBoxLayout()
        
        self.btn_up = QPushButton("↑ Move Up")
        self.btn_up.clicked.connect(self._on_move_up)
        seq_btn_layout.addWidget(self.btn_up)
        
        self.btn_down = QPushButton("↓ Move Down")
        self.btn_down.clicked.connect(self._on_move_down)
        seq_btn_layout.addWidget(self.btn_down)
        
        self.btn_remove = QPushButton("✖ Remove")
        self.btn_remove.clicked.connect(self._on_remove_command)
        seq_btn_layout.addWidget(self.btn_remove)
        
        seq_layout.addLayout(seq_btn_layout)
        seq_group.setLayout(seq_layout)
        layout.addWidget(seq_group)
        
        # Save button
        btn_layout = QHBoxLayout()
        self.btn_save = QPushButton("Save Profile")
        self.btn_save.clicked.connect(self._on_save_clicked)
        self.btn_save.setEnabled(False)
        btn_layout.addWidget(self.btn_save)
        btn_layout.addStretch()
        
        layout.addLayout(btn_layout)
        widget.setLayout(layout)
        return widget
    
    def _on_command_type_changed(self):
        """Load commands when type changes."""
        cmd_type = self.cmd_type_combo.currentData()
        if cmd_type == "uart":
            self._load_uart_commands()
        else:
            self._load_i2c_commands()

    def _load_uart_commands(self):
        """Load UART commands into dropdown."""
        self.cmd_combo.clear()
        cursor = self.db_conn.execute(
            "SELECT command_id, command_name FROM uart_commands WHERE is_active=1 ORDER BY command_name"
        )
        for row in cursor.fetchall():
            self.cmd_combo.addItem(row[1], row[0])

    def _load_i2c_commands(self):
        """Load I2C commands into dropdown."""
        self.cmd_combo.clear()
        cursor = self.db_conn.execute(
            "SELECT command_id, command_name FROM i2c_commands WHERE is_active=1 ORDER BY command_name"
        )
        for row in cursor.fetchall():
            self.cmd_combo.addItem(row[1], row[0])
    
    def _load_profiles(self):
        """Load profiles from database."""
        self.profile_list.clear()
        cursor = self.db_conn.execute(
            "SELECT profile_id, profile_name FROM session_profiles ORDER BY profile_name"
        )
        for row in cursor.fetchall():
            item = QListWidgetItem(row[1])
            item.setData(Qt.ItemDataRole.UserRole, row[0])
            self.profile_list.addItem(item)
    
    def _load_profile_details(self, profile_id: int):
        """Load profile into editor."""
        cursor = self.db_conn.execute(
            "SELECT profile_name, description, command_sequence, print_command_rx FROM session_profiles WHERE profile_id = ?",
            (profile_id,)
        )
        row = cursor.fetchone()
        if row:
            self.name_input.setText(row[0] or "")
            self.desc_input.setText(row[1] or "")
            
            # Load print_command_rx checkbox
            print_rx = bool(row[3]) if len(row) > 3 and row[3] is not None else False
            self.print_rx_checkbox.setChecked(print_rx)
            
            # Parse JSON and populate sequence
            try:
                json_obj = json.loads(row[2] or "{}")
                self.command_sequence = []
                for cmd in json_obj.get("commands", []):
                    cmd_id = cmd["command_id"]
                    cmd_type = cmd.get("command_type", "uart")  # Default to uart for backwards compatibility

                    # Get command name from correct table based on type
                    if cmd_type == "i2c":
                        c = self.db_conn.execute(
                            "SELECT command_name FROM i2c_commands WHERE command_id = ?", (cmd_id,)
                        )
                    else:
                        c = self.db_conn.execute(
                            "SELECT command_name FROM uart_commands WHERE command_id = ?", (cmd_id,)
                        )

                    cmd_row = c.fetchone()
                    if cmd_row:
                        self.command_sequence.append({
                            "command_type": cmd_type,
                            "command_id": cmd_id,
                            "command_name": cmd_row[0],
                            "delay_ms": cmd["delay_ms"]
                        })
                self._update_sequence_list()
            except:
                self.command_sequence = []
            
            self.current_profile_id = profile_id
            self.btn_delete.setEnabled(True)
            self.btn_save.setEnabled(True)  # Always allow saving
    
    def _update_sequence_list(self):
        """Update sequence list display."""
        self.sequence_list.clear()
        for i, cmd in enumerate(self.command_sequence, 1):
            cmd_type = cmd.get('command_type', 'uart')
            type_label = "UART" if cmd_type == "uart" else "I2C"
            text = f"{i}. [{type_label}] {cmd['command_name']} ({cmd['delay_ms']}ms)"
            self.sequence_list.addItem(text)

    def _on_add_command(self):
        """Add command to sequence."""
        if self.cmd_combo.count() == 0:
            QMessageBox.warning(self, "Error", "No commands available")
            return

        cmd_type = self.cmd_type_combo.currentData()
        cmd_id = self.cmd_combo.currentData()
        cmd_name = self.cmd_combo.currentText()
        delay = self.delay_spin.value()

        self.command_sequence.append({
            "command_type": cmd_type,
            "command_id": cmd_id,
            "command_name": cmd_name,
            "delay_ms": delay
        })

        self._update_sequence_list()
        self.btn_save.setEnabled(True)
    
    def _on_move_up(self):
        """Move selected command up."""
        idx = self.sequence_list.currentRow()
        if idx > 0:
            self.command_sequence[idx], self.command_sequence[idx-1] = \
                self.command_sequence[idx-1], self.command_sequence[idx]
            self._update_sequence_list()
            self.sequence_list.setCurrentRow(idx-1)
            self.btn_save.setEnabled(True)
    
    def _on_move_down(self):
        """Move selected command down."""
        idx = self.sequence_list.currentRow()
        if 0 <= idx < len(self.command_sequence) - 1:
            self.command_sequence[idx], self.command_sequence[idx+1] = \
                self.command_sequence[idx+1], self.command_sequence[idx]
            self._update_sequence_list()
            self.sequence_list.setCurrentRow(idx+1)
            self.btn_save.setEnabled(True)
    
    def _on_remove_command(self):
        """Remove selected command."""
        idx = self.sequence_list.currentRow()
        if idx >= 0:
            del self.command_sequence[idx]
            self._update_sequence_list()
            self.btn_save.setEnabled(True)
    
    def _on_profile_selected(self, current, previous):
        """Handle profile selection."""
        if current:
            profile_id = current.data(Qt.ItemDataRole.UserRole)
            self._load_profile_details(profile_id)
    
    def _on_add_clicked(self):
        """Handle add button."""
        self.name_input.clear()
        self.desc_input.clear()
        self.print_rx_checkbox.setChecked(False)  # Default to disabled
        self.command_sequence = []
        self._update_sequence_list()
        
        self.profile_list.clearSelection()
        self.current_profile_id = None
        self.btn_delete.setEnabled(False)
        self.btn_save.setEnabled(True)
        self.name_input.setFocus()
    
    def _on_delete_clicked(self):
        """Handle delete button."""
        if not self.current_profile_id:
            return
        
        reply = QMessageBox.question(
            self, "Confirm Delete",
            f"Delete profile '{self.name_input.text()}'?",
            QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No
        )
        if reply != QMessageBox.StandardButton.Yes:
            return
        
        try:
            self.db_conn.execute(
                "DELETE FROM session_profiles WHERE profile_id = ?",
                (self.current_profile_id,)
            )
            self.db_conn.commit()
            self.profile_deleted.emit(self.current_profile_id)
            self._load_profiles()
            self.name_input.clear()
            self.desc_input.clear()
            self.command_sequence = []
            self._update_sequence_list()
            self.current_profile_id = None
            self.btn_save.setEnabled(False)
            self.btn_delete.setEnabled(False)
            QMessageBox.information(self, "Success", "Profile deleted")
        except Exception as e:
            QMessageBox.critical(self, "Error", f"Delete failed: {str(e)}")
    
    def _on_save_clicked(self):
        """Handle save button."""
        name = self.name_input.text().strip()
        if not name:
            QMessageBox.warning(self, "Error", "Profile name required")
            return
        
        if not self.command_sequence:
            QMessageBox.warning(self, "Error", "Add at least one command")
            return
        
        desc = self.desc_input.text().strip()
        print_rx = 1 if self.print_rx_checkbox.isChecked() else 0
        
        # Build JSON
        json_obj = {
            "commands": [
                {
                    "command_id": cmd["command_id"],
                    "command_type": cmd.get("command_type", "uart"),
                    "delay_ms": cmd["delay_ms"]
                }
                for cmd in self.command_sequence
            ]
        }
        json_text = json.dumps(json_obj)
        
        try:
            if self.current_profile_id:
                self.db_conn.execute(
                    "UPDATE session_profiles SET profile_name=?, description=?, "
                    "command_sequence=?, print_command_rx=?, last_modified=datetime('now') WHERE profile_id=?",
                    (name, desc, json_text, print_rx, self.current_profile_id)
                )
                msg = "Profile updated"
            else:
                cursor = self.db_conn.execute(
                    "INSERT INTO session_profiles (profile_name, description, command_sequence, print_command_rx) "
                    "VALUES (?, ?, ?, ?)",
                    (name, desc, json_text, print_rx)
                )
                self.current_profile_id = cursor.lastrowid
                msg = "Profile created"
            
            self.db_conn.commit()
            self.profile_saved.emit(self.current_profile_id)
            self._load_profiles()
            QMessageBox.information(self, "Success", msg)
            self.btn_save.setEnabled(False)
        except Exception as e:
            QMessageBox.critical(self, "Error", f"Save failed: {str(e)}")


if __name__ == "__main__":
    import sys
    from PyQt6.QtWidgets import QApplication
    
    app = QApplication(sys.argv)
    db = DatabaseManager("database/ehinge.db")
    db.initialize()
    
    widget = ConfigureSessionWidget(db)
    widget.setWindowTitle("Configure Session Profiles")
    widget.resize(1000, 600)
    widget.show()
    
    sys.exit(app.exec())
