import re
from PyQt5.QtWidgets import (
    QWidget, QVBoxLayout, QHBoxLayout, QLineEdit, QTableWidget,
    QTableWidgetItem, QHeaderView, QFrame, QLabel, QAbstractItemView,
    QSizePolicy
)
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QColor, QBrush, QFont

from gui.assets.theme.styler import current_theme


class PerceptsTableWidget(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self._all_percepts = []
        self._setup_ui()
    
    def _setup_ui(self):
        layout = QVBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(10)
        
        search_container = QHBoxLayout()
        search_container.setSpacing(8)
        
        self.search_input = QLineEdit()
        self.search_input.setPlaceholderText("Filter percepts...")
        self.search_input.setMinimumHeight(32)
        self.search_input.setClearButtonEnabled(True)
        self.search_input.textChanged.connect(self._on_filter_changed)
        self._style_search_input()
        
        search_container.addWidget(self.search_input)
        
        layout.addLayout(search_container)
        
        self.count_label = QLabel("0 percepts")
        self.count_label.setProperty("class", "text-secondary")
        self.count_label.setFont(QFont("Segoe UI", 9))
        layout.addWidget(self.count_label)
        
        self.table = QTableWidget()
        self.table.setColumnCount(2)
        self.table.setHorizontalHeaderLabels(["Key", "Value"])
        self.table.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.table.setSelectionMode(QAbstractItemView.SingleSelection)
        self.table.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.table.setAlternatingRowColors(False)
        self.table.verticalHeader().setVisible(False)
        self.table.setShowGrid(False)
        self.table.setFrameShape(QFrame.NoFrame)
        
        self.table.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.table.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.table.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum)
        
        header = self.table.horizontalHeader()
        header.setSectionResizeMode(0, QHeaderView.ResizeToContents)
        header.setSectionResizeMode(1, QHeaderView.Stretch)
        header.setMinimumSectionSize(100)
        
        self._style_table()
        
        layout.addWidget(self.table)
    
    def _style_search_input(self):
        bg_secondary = current_theme.get('background_secondary', '#1F2937')
        bg_tertiary = current_theme.get('background_tertiary', '#4B5563')
        text_primary = current_theme.get('text_primary', '#F9FAFB')
        text_secondary = current_theme.get('text_secondary', '#9CA3AF')
        interactive = current_theme.get('interactive_primary', '#3B82F6')
        
        self.search_input.setStyleSheet(f"""
            QLineEdit {{
                background-color: {bg_secondary};
                border: 1px solid {bg_tertiary};
                border-radius: 6px;
                padding: 6px 12px;
                color: {text_primary};
                font-size: 12px;
            }}
            QLineEdit:focus {{
                border: 1px solid {interactive};
            }}
            QLineEdit::placeholder {{
                color: {text_secondary};
            }}
        """)
    
    def _style_table(self):
        bg_secondary = current_theme.get('background_secondary', '#1F2937')
        bg_tertiary = current_theme.get('background_tertiary', '#4B5563')
        text_primary = current_theme.get('text_primary', '#F9FAFB')
        interactive = current_theme.get('interactive_primary', '#3B82F6')
        
        self.table.setStyleSheet(f"""
            QTableWidget {{
                background-color: transparent;
                border: none;
                gridline-color: transparent;
            }}
            QTableWidget::item {{
                padding: 8px 12px;
                border-bottom: 1px solid {bg_tertiary};
            }}
            QTableWidget::item:selected {{
                background-color: {interactive};
            }}
        """)
        
        header = self.table.horizontalHeader()
        header.setStyleSheet(f"""
            QHeaderView::section {{
                background-color: {bg_tertiary};
                color: {text_primary};
                padding: 6px 12px;
                border: none;
                border-bottom: 2px solid {interactive};
                font-weight: bold;
                font-size: 11px;
            }}
        """)
    
    def set_percepts(self, percepts_data):
        self._all_percepts = self._parse_percepts(percepts_data)
        self._update_table()
    
    def _parse_percepts(self, data):
        result = []
        
        if not data:
            return result
        
        if isinstance(data, list):
            for item in data:
                if isinstance(item, dict):
                    for key, value in item.items():
                        result.extend(self._expand_percepts(key, value))
        elif isinstance(data, dict):
            for key, value in data.items():
                result.extend(self._expand_percepts(key, value))
        
        return result
    
    def _expand_percepts(self, key, value):
        result = []
        value_str = str(value)

        percept_pattern = r"Percept\s*\(\s*'([^']+)'\s*,\s*(\([^)]*\)|[^,)]+)\s*(?:,\s*'[^']*'\s*)*(?:,\s*'[^']*'\s*)?\)"
        
        matches = re.findall(percept_pattern, value_str)
        
        if matches:
            for match in matches:
                percept_name = match[0]
                percept_value = match[1]
                result.append((percept_name, percept_value))
        else:
            clean_value = value_str.strip('{}').strip()
            if clean_value:
                result.append((key, clean_value))
            else:
                result.append((key, value_str))
        
        return result
    
    def _on_filter_changed(self, text):
        self._update_table()
    
    def _update_table(self):
        filter_text = self.search_input.text().lower().strip()
        
        if filter_text:
            filtered = [
                (k, v) for k, v in self._all_percepts
                if filter_text in k.lower() or filter_text in str(v).lower()
            ]
        else:
            filtered = self._all_percepts
        
        filtered = sorted(filtered, key=lambda x: (x[0].lower(), str(x[1]).lower()))
        
        total = len(self._all_percepts)
        showing = len(filtered)
        if filter_text:
            self.count_label.setText(f"Showing {showing} of {total} percepts")
        else:
            self.count_label.setText(f"{total} percepts")
        
        row_color_1 = QColor(current_theme.get('background_secondary', '#1F2937'))
        row_color_2 = QColor(current_theme.get('background_tertiary', '#4B5563'))
        text_color = QColor(current_theme.get('text_primary', '#F9FAFB'))
        key_color = QColor(current_theme.get('info', '#0EA5E9'))
        
        self.table.setRowCount(len(filtered))
        
        for row, (key, value) in enumerate(filtered):
            row_bg = row_color_1 if row % 2 == 0 else row_color_2
            
            key_item = QTableWidgetItem(str(key))
            key_item.setForeground(QBrush(key_color))
            key_item.setBackground(QBrush(row_bg))
            key_item.setFont(QFont("Segoe UI", 10, QFont.Bold))
            key_item.setToolTip(str(key))
            self.table.setItem(row, 0, key_item)
            
            value_str = self._format_value(value)
            value_item = QTableWidgetItem(value_str)
            value_item.setForeground(QBrush(text_color))
            value_item.setBackground(QBrush(row_bg))
            value_item.setFont(QFont("Segoe UI", 10))
            full_value = str(value)
            if len(full_value) > 50:
                value_item.setToolTip(full_value)
            self.table.setItem(row, 1, value_item)
        
        self.table.resizeRowsToContents()

        self._adjust_table_height()
    
    def _adjust_table_height(self):
        total_height = self.table.horizontalHeader().height()
        for row in range(self.table.rowCount()):
            total_height += self.table.rowHeight(row)
        total_height += 4  # margem
        self.table.setFixedHeight(total_height)
    
    def _format_value(self, value):
        value_str = str(value)
        
        max_len = 80
        if len(value_str) > max_len:
            return value_str[:max_len] + "..."
        
        return value_str
    
    def clear(self):
        self._all_percepts = []
        self.search_input.clear()
        self._update_table()
    
    def update_theme(self):
        self._style_search_input()
        self._style_table()
        self._update_table()