#!/usr/bin/env python3
"""
I2C Control Widget - Integrated
================================
Command table (left) + I2C core widget (right)

Author: Kynsight
Version: 3.0.0
"""

from PyQt6.QtWidgets import QWidget, QHBoxLayout, QSplitter
from PyQt6.QtCore import Qt, pyqtSignal

from command_table.command_table import CommandTableWidget
from i2c.i2c_kit.i2c_core_widget import I2CWidget


class I2CControlWidget(QWidget):
    """
    Integrated I2C control widget.
    
    Layout: Command table (left) | I2C core (right)
    
    Signals:
        command_sent: (command_id, operation, register)
        reading_received: (reading_info)
        connection_changed: (is_connected)
    """
    
    command_sent = pyqtSignal(int, str, str)  # command_id, operation, register
    reading_received = pyqtSignal(object)
    connection_changed = pyqtSignal(bool)
    
    def __init__(self, db_connection, parent=None):
        super().__init__(parent)
        
        self.conn = db_connection
        
        self._init_ui()
        self._setup_connections()
    
    def _init_ui(self):
        """Initialize UI - side by side layout."""
        layout = QHBoxLayout()
        self.setLayout(layout)
        
        # Splitter for resizable layout
        splitter = QSplitter(Qt.Orientation.Horizontal)
        
        # Left: Command table
        self.command_table = CommandTableWidget(self.conn, 'i2c')
        splitter.addWidget(self.command_table)
        
        # Right: I2C core widget
        self.i2c_core = I2CWidget()
        splitter.addWidget(self.i2c_core)
        
        # Set initial sizes (40% table, 60% core)
        splitter.setSizes([400, 600])
        
        layout.addWidget(splitter)
        
        # Initialize buses on startup
        self.i2c_core._refresh_buses()
        
        # Table always enabled, CRUD buttons disabled initially (not connected)
        self._update_table_mode(False)
    
    def _setup_connections(self):
        """Connect signals between table and core."""
        
        # Command table → Execute via I2C (when connected) OR Edit (when disconnected)
        self.command_table.command_double_clicked.connect(self._on_command_double_click)
        
        # I2C connection → Change table mode
        self.i2c_core.connection_changed.connect(self._on_connection_changed)
        
        # Forward I2C signals
        self.i2c_core.reading_received.connect(self.reading_received.emit)
    
    def _update_table_mode(self, is_connected):
        """Update table mode based on connection state."""
        if is_connected:
            # Connected mode: CRUD buttons disabled, double-click executes
            self.command_table.btn_add.setEnabled(False)
            self.command_table.btn_edit.setEnabled(False)
            self.command_table.btn_delete.setEnabled(False)
        else:
            # Disconnected mode: CRUD buttons enabled, double-click edits
            self.command_table.btn_add.setEnabled(True)
            # Edit/Delete enabled only if something selected
            has_selection = bool(self.command_table.table.selectedItems())
            self.command_table.btn_edit.setEnabled(has_selection)
            self.command_table.btn_delete.setEnabled(has_selection)
    
    def _on_command_double_click(self, command_id, cmd_data):
        """Handle double-click: Execute if connected, Edit if disconnected."""
        if self.i2c_core.is_connected:
            # Connected: Execute command
            self._execute_command(command_id, cmd_data)
        else:
            # Disconnected: Edit command
            self.command_table._edit_command()
    
    def _execute_command(self, command_id, cmd_data):
        """Execute I2C command."""
        operation = cmd_data.get('operation', '')
        register = cmd_data.get('register', '')
        hex_string = cmd_data.get('hex_string', '')
        device_address = cmd_data.get('device_address', '0x40')
        
        if not operation or not register:
            return
        
        try:
            # Remove 0x prefix if present for consistency
            device_addr_clean = device_address.replace('0x', '').replace('0X', '')
            register_clean = register.replace('0x', '').replace('0X', '')
            
            # Populate manual I/O fields (correct field names from i2c_core_widget)
            self.i2c_core.edit_io_addr.setText(device_addr_clean)
            self.i2c_core.edit_io_reg.setText(register_clean)
            
            if operation == 'read':
                # Determine bytes to read
                if 'Angle' in cmd_data.get('command_name', ''):
                    num_bytes = 2
                elif 'Magnitude' in cmd_data.get('command_name', ''):
                    num_bytes = 2
                else:
                    num_bytes = 1
                
                # Set length
                self.i2c_core.spin_io_length.setValue(num_bytes)
                
                # Trigger read (use the button's method)
                self.i2c_core._on_read()
                
            else:  # write
                # Parse data value and set write data field
                if hex_string:
                    data_clean = hex_string.replace('0x', '').replace('0X', '')
                    self.i2c_core.edit_write_data.setText(data_clean)
                    
                    # Trigger write
                    self.i2c_core._on_write()
            
            # Emit signal
            self.command_sent.emit(command_id, operation, register)
            
        except Exception as e:
            print(f"I2C execute error: {e}")
    
    def _on_connection_changed(self, is_connected):
        """Handle connection state change."""
        # Update table mode (CRUD buttons, double-click behavior)
        self._update_table_mode(is_connected)
        
        # Forward signal
        self.connection_changed.emit(is_connected)
    
    def get_i2c_core(self):
        """Get I2C core widget for direct access."""
        return self.i2c_core
    
    def get_command_table(self):
        """Get command table for direct access."""
        return self.command_table


if __name__ == "__main__":
    import sys
    from PyQt6.QtWidgets import QApplication
    import sqlite3
    
    app = QApplication(sys.argv)
    
    conn = sqlite3.connect("./database/ehinge.db")
    
    widget = I2CControlWidget(conn)
    widget.setWindowTitle("I2C Control - Integrated")
    widget.resize(1400, 800)
    widget.show()
    
    sys.exit(app.exec())
