import json
import os

from PyQt5.QtWidgets import QWidget, QLabel, QProgressBar, QVBoxLayout, QApplication
from PyQt5.QtCore import Qt, QThread, pyqtSignal
from PyQt5.QtGui import QPainter, QPainterPath, QColor


class SplashScreen(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
        self.setAttribute(Qt.WA_TranslucentBackground)
        self.setFixedSize(500, 300)

        screen = QApplication.primaryScreen().geometry()
        self.move(
            (screen.width()  - self.width())  // 2,
            (screen.height() - self.height()) // 2,
        )
        self._build_ui()

    def _build_ui(self):
        layout = QVBoxLayout(self)
        layout.setContentsMargins(40, 40, 40, 30)
        layout.setSpacing(0)

        title = QLabel("리플렉터 검사 시스템")
        title.setAlignment(Qt.AlignCenter)
        title.setStyleSheet(
            "color:#ffffff; font-size:22px; font-weight:bold; background:transparent;"
        )

        subtitle = QLabel("Reflector Inspection System")
        subtitle.setAlignment(Qt.AlignCenter)
        subtitle.setStyleSheet("color:#555555; font-size:12px; background:transparent;")

        layout.addStretch(2)
        layout.addWidget(title)
        layout.addSpacing(6)
        layout.addWidget(subtitle)
        layout.addStretch(3)

        self.status_label = QLabel("초기화 중...")
        self.status_label.setAlignment(Qt.AlignCenter)
        self.status_label.setStyleSheet(
            "color:#888888; font-size:13px; background:transparent;"
        )
        layout.addWidget(self.status_label)
        layout.addSpacing(10)

        self.progress_bar = QProgressBar()
        self.progress_bar.setRange(0, 100)
        self.progress_bar.setValue(0)
        self.progress_bar.setFixedHeight(6)
        self.progress_bar.setTextVisible(False)
        self.progress_bar.setStyleSheet("""
            QProgressBar {
                background: #2a2a2a;
                border: none;
                border-radius: 3px;
            }
            QProgressBar::chunk {
                background: #1D9E75;
                border-radius: 3px;
            }
        """)
        layout.addWidget(self.progress_bar)
        layout.addStretch(1)

        version = QLabel("v1.0.0")
        version.setAlignment(Qt.AlignCenter)
        version.setStyleSheet("color:#333333; font-size:11px; background:transparent;")
        layout.addWidget(version)

    def update_progress(self, value: int, message: str):
        self.progress_bar.setValue(value)
        self.status_label.setText(message)
        QApplication.processEvents()

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing)
        path = QPainterPath()
        path.addRoundedRect(0.0, 0.0, float(self.width()), float(self.height()), 12.0, 12.0)
        painter.fillPath(path, QColor("#0d0d0d"))


class InitWorker(QThread):
    progress = pyqtSignal(int, str)   # (진행률, 메시지)
    finished = pyqtSignal(object)     # 초기화 결과 dict

    def run(self):
        from utils.path_helper import get_path
        from camera.insight import InSightCamera
        from camera.basler import BaslerCamera
        from ai.detector import Detector
        from db.sql_client import SQLClient

        results = {}

        # ── 1단계: 설정 로드 ──────────────────────────────────────────── #
        self.progress.emit(10, "설정 불러오는 중...")
        try:
            with open(get_path("config.json"), encoding="utf-8") as f:
                config = json.load(f)
        except Exception as e:
            print(f"[InitWorker] 설정 로드 실패: {e}")
            config = {}
        results["config"] = config

        # ── 2단계: 코그넥스 카메라 ────────────────────────────────────── #
        self.progress.emit(25, "코그넥스 카메라 연결 중...")
        insight = InSightCamera()
        try:
            cognex_cfg = config.get("cognex", {})
            ip   = cognex_cfg.get("ip", "")
            port = cognex_cfg.get("port", 23)
            if ip:
                insight.connect(ip, port)
        except Exception as e:
            print(f"[InitWorker] 코그넥스 연결 실패: {e}")
        results["insight"] = insight

        # ── 3단계: Basler 카메라 ──────────────────────────────────────── #
        self.progress.emit(45, "Basler 카메라 연결 중...")
        basler = BaslerCamera()
        try:
            basler.connect()
        except Exception as e:
            print(f"[InitWorker] Basler 연결 실패: {e}")
        results["basler"] = basler

        # ── 4단계: AI 모델 로드 ───────────────────────────────────────── #
        self.progress.emit(65, "AI 모델 로드 중...")
        detector = Detector()
        try:
            from paths import resolve_path
            model_path = config.get("ai", {}).get("model_path", "")
            if model_path:
                abs_path = resolve_path(model_path)
                if abs_path and os.path.exists(abs_path):
                    detector.load_model(abs_path)
        except Exception as e:
            print(f"[InitWorker] AI 모델 로드 실패: {e}")
        results["detector"] = detector

        # ── 5단계: DB 연결 ────────────────────────────────────────────── #
        self.progress.emit(80, "DB 연결 중...")
        db_client = SQLClient()
        try:
            db_cfg = config.get("db", {})
            if db_cfg.get("server"):
                db_client.connect(
                    db_cfg["server"],
                    db_cfg["database"],
                    db_cfg["username"],
                    db_cfg["password"],
                )
        except Exception as e:
            print(f"[InitWorker] DB 연결 실패: {e}")
        results["db"] = db_client

        # ── 6단계: PLC 연결 ───────────────────────────────────────────── #
        self.progress.emit(92, "PLC 연결 중...")
        plc_client = None
        try:
            from plc.plc_client import PLCClient
            plc_cfg = config.get("plc", {})
            ip   = plc_cfg.get("ip", "").strip()
            port = plc_cfg.get("port", 5010)
            if ip:
                client = PLCClient()
                if client.connect(ip, port):
                    plc_client = client
        except Exception as e:
            print(f"[InitWorker] PLC 연결 실패: {e}")
        results["plc"] = plc_client

        # ── 완료 ──────────────────────────────────────────────────────── #
        self.progress.emit(100, "시작 중...")
        self.finished.emit(results)
