from PySide6.QtWidgets import (
    QMainWindow,
    QWidget,
    QVBoxLayout,
    QSplitter,
    QToolBar,
    QStatusBar,
    QLabel,
)
from PySide6.QtCore import Qt, QRect
from PySide6.QtGui import QAction

from app.ui.analysis_panel import AnalysisPanel
from app.core.sync_controller import sync_manager
from app.ui.components.toggle_button import ToggleButton
from app.ui.dialogs.api_key_dialog import APIKeyDialog
from app.core.settings import get_settings_manager
from app.ui.widgets.ai_floating_chat import AIFloatingButton, AIChatDialog, animate_open, animate_close


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("SL200 AI Smart Analyzer")
        self.resize(1800, 1000)

        self.setup_ui()
        self.setup_menubar()
        self.setup_toolbar()

        # 패널 데이터 로드 시 날짜 비교를 위한 시그널 연결
        self.left_panel.data_loaded.connect(self.check_sync_availability)
        self.right_panel.data_loaded.connect(self.check_sync_availability)

        # AI 클라이언트 초기화
        self._init_ai_client()

    def setup_ui(self):
        central = QWidget()
        self.setCentralWidget(central)
        layout = QVBoxLayout(central)

        # 좌우 분할
        splitter = QSplitter(Qt.Orientation.Horizontal)

        # 왼쪽/오른쪽 패널 생성 (ID 부여)
        self.left_panel = AnalysisPanel("left")
        self.right_panel = AnalysisPanel("right")

        splitter.addWidget(self.left_panel)
        splitter.addWidget(self.right_panel)
        splitter.setSizes([900, 900])  # 1:1 비율

        layout.addWidget(splitter)

        self.status_bar = QStatusBar()
        self.setStatusBar(self.status_bar)

        # 플로팅 AI 버튼
        self._ai_button = AIFloatingButton(central)
        self._ai_button.clicked.connect(self._open_ai_chat)
        self._ai_button.show()
        self._ai_chat: AIChatDialog | None = None
        self._ai_button.move_to_bottom_right()

    def resizeEvent(self, event):
        super().resizeEvent(event)
        try:
            if hasattr(self, "_ai_button") and self._ai_button:
                self._ai_button.move_to_bottom_right()
        except Exception:
            pass

    def setup_toolbar(self):
        toolbar = QToolBar("Main Toolbar")
        self.addToolBar(toolbar)

        # 커스텀 토글 버튼
        self.sync_toggle = ToggleButton(width=60, active_color="#00D084")  # 녹색
        self.sync_toggle.toggled.connect(self.on_sync_toggled)
        self.sync_toggle.setEnabled(False)  # 초기에는 비활성화

        toolbar.addWidget(QLabel("  SYNC MODE: "))
        toolbar.addWidget(self.sync_toggle)

        # 상태 라벨
        self.sync_status_label = QLabel(" (데이터 없음)")
        self.sync_status_label.setStyleSheet("color: #888;")
        toolbar.addWidget(self.sync_status_label)

    def setup_menubar(self):
        """메뉴바 설정"""
        menubar = self.menuBar()

        # 파일 메뉴
        menubar.addMenu("파일(&F)")

        # 설정 메뉴
        settings_menu = menubar.addMenu("설정(&S)")

        # AI API 키 설정
        ai_settings_action = QAction("🔑 AI API 키 설정...", self)
        ai_settings_action.setShortcut("Ctrl+Shift+A")
        ai_settings_action.triggered.connect(self.show_api_key_dialog)
        settings_menu.addAction(ai_settings_action)

        # 도움말 메뉴
        menubar.addMenu("도움말(&H)")

    def show_api_key_dialog(self):
        """API 키 설정 다이얼로그 표시"""
        dialog = APIKeyDialog(self)
        dialog.settings_changed.connect(self._on_ai_settings_changed)
        dialog.exec()

    def _on_ai_settings_changed(self):
        """AI 설정이 변경되었을 때"""
        self.status_bar.showMessage("AI 설정이 저장되었습니다.", 3000)
        self._init_ai_client()

    def check_sync_availability(self):
        """두 패널의 데이터 날짜가 같은지 확인하여 Sync 버튼 활성화/비활성화"""
        left_date = self.left_panel.get_data_date()
        right_date = self.right_panel.get_data_date()

        # 둘 다 데이터가 있는 경우에만 비교
        if left_date and right_date:
            if left_date == right_date:
                # 날짜가 같으면 Sync 활성화
                self.sync_toggle.setEnabled(True)
                self.sync_status_label.setText(f" ({left_date})")
                self.sync_status_label.setStyleSheet("color: #00D084;")
            else:
                # 날짜가 다르면 Sync 비활성화
                self.sync_toggle.setEnabled(False)
                self.sync_toggle.setChecked(False)  # 자동으로 끔
                self.sync_status_label.setText(f" (날짜 불일치: {left_date} ≠ {right_date})")
                self.sync_status_label.setStyleSheet("color: #FF5252;")
        elif left_date or right_date:
            # 한쪽만 데이터가 있음
            self.sync_toggle.setEnabled(False)
            date_info = left_date or right_date
            self.sync_status_label.setText(f" ({date_info} - 상대 패널 없음)")
            self.sync_status_label.setStyleSheet("color: #888;")
        else:
            # 둘 다 데이터 없음
            self.sync_toggle.setEnabled(False)
            self.sync_status_label.setText(" (데이터 없음)")
            self.sync_status_label.setStyleSheet("color: #888;")

    def on_sync_toggled(self, checked):
        """동기화 모드 변경 시 동작"""
        sync_manager.is_sync_enabled = checked

        if checked:
            # [SYNC ON]
            # 1. 오른쪽 패널의 파일 로드 버튼 숨김
            self.right_panel.set_slave_mode(True)

            # 2. 왼쪽 패널의 데이터가 있다면 오른쪽으로 복사
            if self.left_panel.raw_data:
                self.right_panel.receive_shared_data(self.left_panel.raw_data)

            self.status_bar.showMessage("Sync ON: 오른쪽 패널이 왼쪽 데이터와 동기화됩니다.")
        else:
            # [SYNC OFF]
            self.right_panel.set_slave_mode(False)
            self.status_bar.showMessage("Sync OFF: 독립 분석 모드")

    def _init_ai_client(self):
        """저장된 설정으로 AI 클라이언트 초기화(가능할 때만)"""
        try:
            from app.ai import get_ai_client, AIProviderType

            settings = get_settings_manager().ai_settings
            current_provider = settings.get_current_provider()

            if not current_provider:
                return

            api_key = settings.get_api_key(current_provider)
            model = settings.get_model(current_provider)

            if not api_key:
                return

            client = get_ai_client()
            provider_type = AIProviderType(current_provider)
            if client.set_provider(provider_type, api_key, model):
                st = client.get_status()
                self.status_bar.showMessage(f"AI 준비: {st.get('provider')} / {st.get('model')}", 3000)
        except Exception as e:
            print(f"AI 클라이언트 초기화 실패: {e}")

    def _get_panel_ctx(self, panel_id: str, user_query: str | None = None):
        panel = self.right_panel if panel_id == "right" else self.left_panel
        ctx = panel.get_ai_context()

        # 질의에 따라 추가 분석 결과를 포함(프롬프트 품질 개선)
        if user_query:
            q = user_query.lower()
            if ("pg3" in q or "pg3-2" in q) and ("역" in user_query):
                try:
                    ctx.setdefault("analysis", {})
                    ctx["analysis"]["pg3_2_per_station"] = panel.compute_pg_at_station("PG3-2")
                except Exception:
                    pass

        return ctx

    def _is_qobject_alive(self, obj) -> bool:
        """PySide6 객체가 이미 delete된 상태인지 안전하게 판별"""
        if obj is None:
            return False
        try:
            import shiboken6  # type: ignore
            return bool(shiboken6.isValid(obj))
        except Exception:
            # shiboken6이 없거나, 일부 환경에서 import 실패 시 런타임 호출로 체크
            try:
                obj.objectName()
                return True
            except Exception:
                return False

    def _on_ai_chat_destroyed(self, *_args):
        # 삭제된 객체 참조 제거(다음 클릭에서 RuntimeError 방지)
        self._ai_chat = None
        self._ai_button.set_open_state(False)

    def _open_ai_chat(self):
        # 열려 있으면: 웹처럼 버튼(X)로 닫기 동작
        if self._ai_chat and self._is_qobject_alive(self._ai_chat) and self._ai_chat.isVisible():
            btn = self._ai_button
            start_rect = self._ai_chat.geometry()
            # 닫힘 애니메이션은 버튼 위치로 축소
            btn_pos = btn.mapTo(self, btn.rect().topLeft())
            end_rect = QRect(btn_pos.x(), btn_pos.y(), btn.width(), btn.height())
            animate_close(self._ai_chat, start_rect, end_rect, duration_ms=180)
            return

        # 레퍼런스는 남아있지만 이미 삭제된 경우 정리
        if self._ai_chat and not self._is_qobject_alive(self._ai_chat):
            self._ai_chat = None
            self._ai_button.set_open_state(False)

        self._ai_chat = AIChatDialog(self, self._get_panel_ctx)
        self._ai_chat.setAttribute(Qt.WA_DeleteOnClose, True)
        self._ai_chat.destroyed.connect(self._on_ai_chat_destroyed)
        self._ai_button.set_open_state(True)

        # 버튼 위치 기준으로 확장 애니메이션
        btn = self._ai_button
        # 메인윈도우 좌표로 변환
        btn_top_left = btn.mapTo(self, btn.rect().topLeft())
        start_rect = QRect(btn_top_left.x(), btn_top_left.y(), btn.width(), btn.height())

        # 최종 크기: 버튼을 가리지 않도록 '버튼 위로' 배치(가능하면)
        w, h = 560, 680
        gap = 10
        margin = 14

        # 1) 우선: 버튼 위로(오른쪽 정렬)
        end_x = btn_top_left.x() + btn.width() - w
        end_y = btn_top_left.y() - h - gap

        # 위로 배치 불가능하면: 버튼 왼쪽으로
        if end_y < margin:
            end_y = max(margin, btn_top_left.y() + btn.height() - h)  # 세로는 버튼과 겹치지 않게 최대한 맞춤
            end_x = btn_top_left.x() - w - gap

        # 그래도 화면 밖이면: 화면 안으로 클램프(버튼 가림 최소화)
        end_x = max(margin, min(end_x, self.width() - w - margin))
        end_y = max(margin, min(end_y, self.height() - h - margin))

        end_rect = QRect(end_x, end_y, w, h)

        animate_open(self._ai_chat, start_rect, end_rect, duration_ms=280)


