"""
신호 표시용 컴포넌트들
- OnOffSignalLabel: ON/OFF 신호 표시
- ModeSignalLabel: MODE 신호 표시 (여러 상태 중 하나)
- DataSignalLabel: 데이터 신호 표시 (신호명 + 값)
- SignalCard: 신호들을 그룹화하는 카드
"""

from PySide6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel, 
                               QFrame, QMenu, QGridLayout, QScrollArea, QSizePolicy)
from PySide6.QtCore import Qt, Signal, QPoint
from PySide6.QtGui import QCursor, QMouseEvent

# ============================================================================
# 1. ON/OFF 신호 라벨
# ============================================================================
class OnOffSignalLabel(QLabel):
    """
    ON/OFF 신호 표시용 라벨
    - ON: 연두색 배경 + 검은색 글자
    - OFF: 어두운 회색 배경 + 흰색 글자
    """
    
    clicked = Signal()
    right_clicked = Signal(QPoint)
    
    # 스타일 상수
    STYLE_ON = "background-color: #76FF03; color: black; border-radius: 3px; padding: 2px 6px; font-weight: bold;"
    STYLE_OFF = "background-color: #3C3C3C; color: #AAAAAA; border-radius: 3px; padding: 2px 6px;"
    
    def __init__(self, signal_name: str, display_name: str = None, 
                 description: str = "", on_list: list = None, off_list: list = None, parent=None):
        super().__init__(display_name or signal_name, parent)
        
        self.signal_name = signal_name
        self.display_name = display_name or signal_name
        self.description = description
        self.on_list = on_list or []   # ON일 때 목록
        self.off_list = off_list or []  # OFF일 때 목록
        self._style_on_override = None
        self._style_off_override = None
        
        self._is_on = False
        
        # UI 설정
        self.setAlignment(Qt.AlignCenter)
        self.setCursor(Qt.PointingHandCursor)
        self.setMinimumSize(40, 18)
        self.setMaximumHeight(22)
        self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed)
        
        # 툴팁 설정
        if description:
            self.setToolTip(description)
        
        self.set_status(False)
    
    def set_status(self, is_on: bool):
        """신호 상태 설정"""
        self._is_on = is_on
        if is_on:
            self.setStyleSheet(self._style_on_override or self.STYLE_ON)
        else:
            self.setStyleSheet(self._style_off_override or self.STYLE_OFF)

    def set_style_override(self, on_style: str | None = None, off_style: str | None = None):
        """ON/OFF 스타일 오버라이드"""
        self._style_on_override = on_style
        self._style_off_override = off_style
        # 현재 상태 즉시 반영
        self.set_status(self._is_on)
    
    def mousePressEvent(self, event: QMouseEvent):
        if event.button() == Qt.LeftButton:
            self.clicked.emit()
        elif event.button() == Qt.RightButton:
            self.right_clicked.emit(event.pos())
            self._show_context_menu(event.globalPosition().toPoint())
        super().mousePressEvent(event)
    
    def _show_context_menu(self, global_pos):
        menu = QMenu(self)
        menu.setStyleSheet("""
            QMenu { background-color: #2D2D30; color: white; border: 1px solid #555; }
            QMenu::item:selected { background-color: #0078D7; }
        """)
        
        # ON일 때 목록
        if self.on_list:
            on_menu = menu.addMenu("🟢 ON 목록")
            for item in self.on_list:
                on_menu.addAction(item)
        
        # OFF일 때 목록
        if self.off_list:
            off_menu = menu.addMenu("⚫ OFF 목록")
            for item in self.off_list:
                off_menu.addAction(item)
        
        menu.addSeparator()
        
        # 신호 설명
        if self.description:
            desc_action = menu.addAction("ℹ️ 신호 설명")
            desc_action.triggered.connect(self._show_description_popup)
        
        menu.exec(global_pos)
    
    def _show_description_popup(self):
        from app.ui.components.clickableLabel import HoverInfoPopup
        popup = HoverInfoPopup(f"<b>{self.display_name}</b><br><br>{self.description}")
        popup.move(QCursor.pos() + QPoint(10, 10))
        popup.show()


# ============================================================================
# 2. MODE 신호 라벨 (여러 상태 중 하나)
# ============================================================================
class ModeSignalLabel(QLabel):
    """
    MODE 신호 표시용 라벨
    - 신호 없음: OFF (어두운 회색 배경 + 흰색 글자)
    - 신호 있음: 해당 모드 표시 (연보라색 배경 + 검은색 글자)
    """
    
    clicked = Signal()
    right_clicked = Signal(QPoint)
    
    STYLE_OFF = "background-color: #3C3C3C; color: #AAAAAA; border-radius: 3px; padding: 2px 6px;"
    STYLE_ON = "background-color: #B388FF; color: black; border-radius: 3px; padding: 2px 6px; font-weight: bold;"
    
    def __init__(self, signal_name: str, mode_list: list = None, 
                 description: str = "", parent=None):
        super().__init__("OFF", parent)
        
        self.signal_name = signal_name
        self.mode_list = mode_list or []  # 가능한 모드 목록
        self.description = description
        self._current_mode = None
        
        # UI 설정
        self.setAlignment(Qt.AlignCenter)
        self.setCursor(Qt.PointingHandCursor)
        self.setMinimumSize(45, 18)
        self.setMaximumHeight(22)
        self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed)
        
        if description:
            self.setToolTip(description)
        
        self.set_mode(None)
    
    def set_mode(self, mode: str):
        """현재 모드 설정"""
        self._current_mode = mode
        if mode:
            self.setText(mode)
            self.setStyleSheet(self.STYLE_ON)
        else:
            self.setText("OFF")
            self.setStyleSheet(self.STYLE_OFF)
    
    def mousePressEvent(self, event: QMouseEvent):
        if event.button() == Qt.LeftButton:
            self.clicked.emit()
        elif event.button() == Qt.RightButton:
            self.right_clicked.emit(event.pos())
            self._show_context_menu(event.globalPosition().toPoint())
        super().mousePressEvent(event)
    
    def _show_context_menu(self, global_pos):
        menu = QMenu(self)
        menu.setStyleSheet("""
            QMenu { background-color: #2D2D30; color: white; border: 1px solid #555; }
            QMenu::item:selected { background-color: #0078D7; }
        """)
        
        # 모드 목록
        if self.mode_list:
            mode_menu = menu.addMenu("📋 모드 목록")
            for mode in self.mode_list:
                action = mode_menu.addAction(mode)
                if mode == self._current_mode:
                    action.setEnabled(False)
        
        menu.addSeparator()
        
        if self.description:
            desc_action = menu.addAction("ℹ️ 신호 설명")
            desc_action.triggered.connect(self._show_description_popup)
        
        menu.exec(global_pos)
    
    def _show_description_popup(self):
        from app.ui.components.clickableLabel import HoverInfoPopup
        popup = HoverInfoPopup(f"<b>{self.signal_name}</b><br><br>{self.description}")
        popup.move(QCursor.pos() + QPoint(10, 10))
        popup.show()


# ============================================================================
# 3. DATA 신호 라벨 (신호명 + 값) - 세로 배치
# ============================================================================
class DataSignalLabel(QFrame):
    """
    데이터 신호 표시용 라벨 (신호명 + 값 2개 세로 조합)
    - 상단: 신호명 (밝은 파랑 배경 + 흰색 글자)
    - 하단: 신호값 (남색 배경 + 흰색 글자)
    """
    
    clicked = Signal()
    right_clicked = Signal(QPoint)
    
    STYLE_NAME = "background-color: #2196F3; color: white; border-radius: 3px 0 0 3px; padding: 2px 6px; font-size: 9px;"
    STYLE_VALUE = "background-color: #1A237E; color: white; border-radius: 0 3px 3px 0; padding: 2px 6px; font-weight: bold; font-size: 10px;"
    
    def __init__(self, signal_name: str, display_name: str = None,
                 unit: str = "", possible_values: list = None,
                 description: str = "", parent=None):
        super().__init__(parent)
        
        self.signal_name = signal_name
        self.display_name = display_name or signal_name
        self.unit = unit
        self.possible_values = possible_values or []
        self.description = description
        
        self._setup_ui()
        
        if description:
            self.setToolTip(description)
    
    def _setup_ui(self):
        # 가로 배치 (이름 | 값)
        layout = QHBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)
        
        # 좌측: 신호명 라벨
        self.lbl_name = QLabel(self.display_name)
        self.lbl_name.setStyleSheet(self.STYLE_NAME)
        self.lbl_name.setAlignment(Qt.AlignCenter)
        self.lbl_name.setMinimumWidth(40)
        self.lbl_name.setFixedHeight(22)
        
        # 우측: 신호값 라벨
        self.lbl_value = QLabel("-")
        self.lbl_value.setStyleSheet(self.STYLE_VALUE)
        self.lbl_value.setAlignment(Qt.AlignCenter)
        self.lbl_value.setMinimumWidth(50)
        self.lbl_value.setFixedHeight(22)
        
        layout.addWidget(self.lbl_name)
        layout.addWidget(self.lbl_value)
        
        self.setFixedHeight(24)  # 1행 높이
        self.setCursor(Qt.PointingHandCursor)
        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
    
    def set_value(self, value):
        """신호 값 설정"""
        if self.unit:
            self.lbl_value.setText(f"{value}{self.unit}")
        else:
            self.lbl_value.setText(str(value))

    def set_value_style(self, style: str):
        """값 라벨 스타일 커스텀 설정"""
        self.lbl_value.setStyleSheet(self.STYLE_VALUE + style)
    
    def mousePressEvent(self, event: QMouseEvent):
        if event.button() == Qt.LeftButton:
            self.clicked.emit()
        elif event.button() == Qt.RightButton:
            self.right_clicked.emit(event.pos())
            self._show_context_menu(event.globalPosition().toPoint())
        super().mousePressEvent(event)
    
    def _show_context_menu(self, global_pos):
        menu = QMenu(self)
        menu.setStyleSheet("""
            QMenu { background-color: #2D2D30; color: white; border: 1px solid #555; }
            QMenu::item:selected { background-color: #0078D7; }
        """)
        
        # 가능한 값 목록
        if self.possible_values:
            val_menu = menu.addMenu("📋 가능한 값")
            for val in self.possible_values:
                val_menu.addAction(str(val))
        
        menu.addSeparator()
        
        if self.description:
            desc_action = menu.addAction("ℹ️ 신호 설명")
            desc_action.triggered.connect(self._show_description_popup)
        
        menu.exec(global_pos)
    
    def _show_description_popup(self):
        from app.ui.components.clickableLabel import HoverInfoPopup
        popup = HoverInfoPopup(f"<b>{self.display_name}</b><br><br>{self.description}")
        popup.move(QCursor.pos() + QPoint(10, 10))
        popup.show()


# ============================================================================
# 4. 신호 카드 (그룹화)
# ============================================================================
class SignalCard(QFrame):
    """
    신호들을 그룹화하는 카드 컴포넌트
    - 타이틀 바
    - ON/OFF, MODE 컴포넌트: 1행 1열
    - DATA 컴포넌트: 1행에 2~4열 차지 (가로로 넓게)
    """
    
    def __init__(self, title: str, parent=None):
        super().__init__(parent)
        
        self.title = title
        self.signals = {}  # signal_name -> widget
        self._onoff_widgets = []  # ON/OFF, MODE 위젯들
        self._data_widgets = []   # DATA 위젯들
        self._horizontal_data_mode = False  # DATA 가로 배치 모드
        
        self._setup_ui()
    
    def _setup_ui(self):
        self.setStyleSheet("""
            SignalCard {
                background-color: #252526;
                border: 1px solid #3E3E42;
                border-radius: 4px;
            }
        """)
        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
        self.setMinimumWidth(150)
        
        layout = QVBoxLayout(self)
        layout.setContentsMargins(4, 4, 4, 4)
        layout.setSpacing(2)
        
        # 타이틀
        self.lbl_title = QLabel(self.title)
        self.lbl_title.setFixedHeight(20)  # 제목 높이 고정
        self.lbl_title.setStyleSheet("""
            font-weight: bold;
            color: #00B0FF;
            font-size: 10px;
            padding: 1px 3px;
            border-bottom: 1px solid #3E3E42;
        """)
        layout.addWidget(self.lbl_title)
        
        # 신호 컨테이너 (GridLayout 사용)
        self.signal_container = QWidget()
        self.signal_grid = QGridLayout(self.signal_container)
        self.signal_grid.setContentsMargins(0, 2, 0, 0)
        self.signal_grid.setSpacing(2)
        
        layout.addWidget(self.signal_container)
        
        # 현재 그리드 위치 추적
        self._grid_row = 0
        self._grid_col = 0
        self._max_cols = 4  # 4열 배치 (DATA가 2~4열 차지 가능)
        self._data_colspan = 2  # DATA 위젯의 기본 colspan (2~4열 조정 가능)
    
    def set_horizontal_data_mode(self, enabled: bool):
        """DATA 위젯 가로 배치 모드 설정"""
        self._horizontal_data_mode = enabled
    
    def add_signal(self, widget, signal_name: str = None):
        """신호 위젯 추가 - 타입에 따라 배치 방식 다름"""
        if isinstance(widget, DataSignalLabel):
            if self._horizontal_data_mode:
                # DATA 가로 배치 모드: 1행 1열 (ON/OFF처럼)
                self.signal_grid.addWidget(widget, self._grid_row, self._grid_col)
                self._grid_col += 1
                if self._grid_col >= self._max_cols:
                    self._grid_col = 0
                    self._grid_row += 1
            else:
                # 기본 모드: DATA 위젯은 1행에 2~4열 차지 (가로로 넓게)
                # 현재 열이 0이 아니면 다음 행으로 이동
                if self._grid_col != 0:
                    self._grid_row += 1
                    self._grid_col = 0
                
                # colspan 계산 (남은 공간에 따라 2~4열)
                colspan = min(self._data_colspan, self._max_cols - self._grid_col)
                self.signal_grid.addWidget(widget, self._grid_row, self._grid_col, 1, colspan)
                self._grid_col += colspan
                if self._grid_col >= self._max_cols:
                    self._grid_col = 0
                    self._grid_row += 1
            self._data_widgets.append(widget)
        else:
            # ON/OFF, MODE 위젯: 1행 1열
            self.signal_grid.addWidget(widget, self._grid_row, self._grid_col)
            self._grid_col += 1
            if self._grid_col >= self._max_cols:
                self._grid_col = 0
                self._grid_row += 1
            self._onoff_widgets.append(widget)
        
        if signal_name:
            self.signals[signal_name] = widget
    
    def get_signal(self, signal_name: str):
        """신호 위젯 가져오기"""
        return self.signals.get(signal_name)
    
    def finalize_layout(self):
        """레이아웃 마무리 - 남는 공간에 stretch 추가"""
        # 마지막 행 다음에 stretch 추가
        if self._grid_col > 0:
            self._grid_row += 1
        self.signal_grid.setRowStretch(self._grid_row, 1)


# ============================================================================
# 5. FlowLayout (하위 호환용 - 더 이상 사용하지 않음)
# ============================================================================
class FlowLayout(QVBoxLayout):
    """
    간단한 FlowLayout 구현 (레거시 호환용)
    """
    
    def __init__(self, parent=None):
        super().__init__(parent)
        self._widgets = []
        self._row_layouts = []
        self._spacing = 4
        self.setSpacing(4)
    
    def setSpacing(self, spacing):
        self._spacing = spacing
        super().setSpacing(spacing)
    
    def addWidget(self, widget):
        self._widgets.append(widget)
        self._reflow()
    
    def _reflow(self):
        # 기존 레이아웃 정리
        for row_layout in self._row_layouts:
            while row_layout.count():
                item = row_layout.takeAt(0)
        
        for row_layout in self._row_layouts:
            self.removeItem(row_layout)
        self._row_layouts.clear()
        
        # 새 행 생성
        current_row = QHBoxLayout()
        current_row.setSpacing(self._spacing)
        self._row_layouts.append(current_row)
        super().addLayout(current_row)
        
        for widget in self._widgets:
            current_row.addWidget(widget)
        
        current_row.addStretch()

