"""Local SHiRE AIOS preview for the shared Kinect Vision Service."""

from PyQt5.QtCore import Qt, QTimer
from PyQt5.QtGui import (
    QColor,
    QImage,
    QPainter,
    QPixmap,
)
from PyQt5.QtWidgets import (
    QFrame,
    QLabel,
    QSizePolicy,
    QVBoxLayout,
)

from services.kinect_vision_service import (
    get_kinect_vision_service,
)


class KinectCameraTile(QFrame):
    """Local preview only; does not own or record the camera."""

    def __init__(
        self,
        parent=None,
        vision_service=None,
        consumer_id=None,
    ):
        super().__init__(parent)

        self.vision_service = (
            vision_service
            or get_kinect_vision_service()
        )

        self.consumer_id = (
            consumer_id
            or f"aios-preview-{id(self):x}"
        )

        self.last_frame = None
        self._local_blink_closed = False
        self._acquired = False

        self.setMinimumWidth(210)
        self.setMaximumWidth(280)
        self.setMinimumHeight(160)
        self.setMaximumHeight(176)
        self.setSizePolicy(
            QSizePolicy.Expanding,
            QSizePolicy.Fixed,
        )

        self.setStyleSheet(
            "QFrame {"
            "background:#03070d;"
            "border:2px solid #8f35ff;"
            "border-radius:7px;"
            "}"
        )

        layout = QVBoxLayout(self)
        layout.setContentsMargins(3, 2, 3, 3)
        layout.setSpacing(2)

        title = QLabel("KINECT VISION")
        title.setAlignment(Qt.AlignCenter)
        title.setStyleSheet(
            "color:#00ff88;"
            "border:none;"
            "font-size:10px;"
            "font-weight:bold;"
        )

        self.preview = QLabel("STARTING KINECT")
        self.preview.setAlignment(Qt.AlignCenter)
        self.preview.setMinimumHeight(125)
        self.preview.setStyleSheet(
            "background:#000;"
            "color:#70558f;"
            "border:1px solid #00ff88;"
            "font-size:9px;"
            "font-weight:bold;"
        )

        self.status = QLabel("STANDBY")
        self.status.setAlignment(Qt.AlignCenter)
        self.status.setStyleSheet(
            "color:#ffaa33;"
            "border:none;"
            "font-size:9px;"
            "font-weight:bold;"
        )

        layout.addWidget(title)
        layout.addWidget(self.preview, 1)
        layout.addWidget(self.status)

        self.vision_service.frame_ready.connect(
            self._display_frame
        )
        self.vision_service.status_changed.connect(
            self._vision_status_changed
        )
        self.vision_service.camera_error.connect(
            self._camera_error
        )

    def start_camera(self):
        if self._acquired:
            return

        self.preview.setText("STARTING KINECT")
        self.status.setText("STARTING")

        self._acquired = True
        state = self.vision_service.acquire(
            self.consumer_id,
            start=True,
        )
        self._vision_status_changed(state)

    def stop_camera(self):
        if not self._acquired:
            return

        self._acquired = False
        self.vision_service.release(
            self.consumer_id
        )

        self.last_frame = None
        self.preview.clear()
        self.preview.setText("KINECT STANDBY")
        self.status.setText("STANDBY")

    def begin_local_blink(self):
        """Close only the local AIOS preview eyelids."""
        self._local_blink_closed = True
        self._refresh_preview()

    def end_local_blink(self):
        """Reopen only the local AIOS preview eyelids."""
        self._local_blink_closed = False
        self._refresh_preview()

    def _display_frame(self, image):
        if not self._acquired:
            return

        self.last_frame = image
        self._refresh_preview()
        self.status.setText("LIVE • SHARED VISION")

    def _refresh_preview(self):
        if self.last_frame is None:
            return

        pixmap = QPixmap.fromImage(
            self.last_frame
        ).scaled(
            self.preview.size(),
            Qt.KeepAspectRatio,
            Qt.SmoothTransformation,
        )

        if self._local_blink_closed:
            blinked = QPixmap(pixmap.size())
            blinked.fill(QColor("#010104"))

            painter = QPainter(blinked)
            painter.drawPixmap(0, 0, pixmap)

            width = pixmap.width()
            height = pixmap.height()
            centre = height // 2
            slit = max(2, height // 22)
            eyelid = QColor(1, 1, 4, 252)

            painter.fillRect(
                0,
                0,
                width,
                max(0, centre - slit),
                eyelid,
            )
            painter.fillRect(
                0,
                centre + slit,
                width,
                max(0, height - centre - slit),
                eyelid,
            )
            painter.end()
            pixmap = blinked

        self.preview.setText("")
        self.preview.setPixmap(pixmap)

    def _vision_status_changed(self, state):
        if not self._acquired:
            return

        if state.get("last_error"):
            self.status.setText(
                f"ERROR: {state['last_error'][:26]}"
            )
        elif state.get("camera_active"):
            self.status.setText("LIVE • SHARED VISION")
        else:
            self.status.setText("STARTING")

    def _camera_error(self, message):
        if self._acquired:
            self.status.setText(
                f"ERROR: {str(message)[:26]}"
            )

    def resizeEvent(self, event):
        super().resizeEvent(event)
        self._refresh_preview()

    def showEvent(self, event):
        super().showEvent(event)
        QTimer.singleShot(250, self.start_camera)

    def hideEvent(self, event):
        self.end_local_blink()
        self.stop_camera()
        super().hideEvent(event)
