#!D:/IDE/anaconda3/envs python
# -*- coding: UTF-8 -*-
"""
 @Author: Administrator
 @FileName：CellFlowView.py\n
 @DateTime: 2025/7/27 9:06\n
 @Author  ：xsh
"""
import numpy as np
from PyQt5 import Qt
from AppSettings.Settings import SIGNAL_CONNECTION_TYPE
from AppUtils.ImageUtils import ImageUtils
from AppCore.Levels import *
from AppCore.DBModels import *
from AppUtils.UiUtils import UiUtils
from AppInterfaces.UiInterface import UiInterface, AppUiProperty, AppUtils, AppConvert
from AppInterfaces.globalSlot import globalSlot, AppSlot
from AppHeadEnd.Commons.FlowLayout import FlowLayout

class CellFlowView(Qt.QWidget, UiInterface):
    IOLocker    : Qt.QReadWriteLock = Qt.QReadWriteLock()
    Area        : Qt.QScrollArea      #
    Flow        : Qt.QGridLayout      #
    Boxs        : Qt.QWidget          #
    Images      : list[Qt.QLabel]
    ImageW      : int
    ImageH      : int
    CellImageW  : int
    CellImageH  : int
    Row         : int
    Col         : int
    isClear     : bool

    def __init__(self, parent: Qt.QWidget = None):
        super(CellFlowView, self).__init__(parent=parent)
        self.Initialization('CellFlowView', self, parent)
        self.initWidgetStyle()



    def initWidgetStyle(self):
        self.setStyleSheet(UiUtils.getWidgetStyle())

    def initConnect(self):
        super(CellFlowView, self).initConnect()
        TYPE: Qt.Qt.ConnectionType= Qt.Qt.ConnectionType(Qt.Qt.AutoConnection | Qt.Qt.UniqueConnection)
        AppSlot.CellImageSignal.connect(slot=self.SlotCellImageSignal, type=TYPE)
        AppSlot.ClearImageListSignal.connect(slot=self.SlotClearImageListSignal, type=TYPE)


    def SlotClearImageListSignal(self, tray_number: int, chamber_number: int):
        Locker: Qt.QWriteLocker = Qt.QWriteLocker(self.IOLocker)
        self.isClear = True
        try:
            if not self.hasImages:
                return
            count: int = len(self.Images)
            child: Qt.QLayoutItem
            widget: Qt.QWidget
            while count > 0:
                widget = self.Images.pop(-1)
                if widget is not None:
                    self.Flow.removeWidget(widget)
                    widget.setParent(None)
                    widget.setVisible(False)
                    del widget
                count -= 1
            self.Boxs.setFixedHeight(self.ImageH + 50)
            self.Row = 0
            self.Col = 0
        except Exception as e:
            AppUtils.print_Exception(e)
        self.Area.verticalScrollBar().setValue(self.Area.verticalScrollBar().minimum())
        self.isClear = False

    def clearLayoutWidgets(self):
        try:
            widget: Qt.QWidget
            for widget in self.Images:
                if widget is not None:
                    self.Flow.removeWidget(widget)
                    widget.setVisible(False)
            self.Boxs.setFixedHeight(self.ImageH + 50)
            self.Row = 0
            self.Col = 0
        except Exception as e:
            AppUtils.print_Exception(e)

    def flushLayout(self):
        Locker: Qt.QWriteLocker = Qt.QWriteLocker(self.IOLocker)
        col     : int = self.Flow.columnCount()
        width   : int = self.size().width()
        _colCount: int = width // self.ImageW
        if col == _colCount:
            return
        self.clearLayoutWidgets()
        index: int
        width: Qt.QLabel
        self.Row = 0
        self.Col = 0
        for index, widget in enumerate(self.Images):
            widget.setVisible(True)
            self.Flow.addWidget(widget, self.Row, self.Col, 1, 1)
            self.Col += 1
            if self.Col >= _colCount:
                self.Col = 0
                self.Row += 1
                self.Boxs.setFixedHeight(self.ImageH * (self.Row + 2))
                self.Area.verticalScrollBar().setValue(self.Area.verticalScrollBar().maximum())

    def resizeEvent(self, ev: Qt.QResizeEvent) -> None:
        super(CellFlowView, self).resizeEvent(ev)
        width: int = self.size().width()
        col: int = self.Flow.columnCount()
        _colCount: int = width // self.ImageW
        if col != _colCount:
            self.Boxs.setMinimumWidth(width - 25)
            self.flushLayout()

    def SlotCellImageSignal(self, info, image):
        self.initImageSize  ()
        self.initImages     ()
        if isinstance(info, np.ndarray):
            return self.appendImage(ImageUtils.cv2_to_QImage(info, self.ImageW, self.ImageH))
        elif isinstance(info, Qt.QImage):
            return self.appendImage(info)
        elif isinstance(image, np.ndarray):
            return self.appendImage(ImageUtils.cv2_to_QImage(image, self.ImageW, self.ImageH))
        elif isinstance(image, Qt.QImage):
            return self.appendImage(image)
        elif isinstance(info, CellModel):
            return self.appendImage(info.toQImage(self.ImageW, self.ImageH))
        elif isinstance(image, CellModel):
            return self.appendImage(image.toQImage(self.ImageW, self.ImageH))

    def appendImage(self, image: Qt.QImage):
        Locker: Qt.QWriteLocker = Qt.QWriteLocker(self.IOLocker)
        if not isinstance(image, Qt.QImage):
            return
        self.initImageSize()
        self.initImages()
        img: Qt.QImage
        if image.width() != self.ImageW or image.height() != self.ImageH:
            img = image.scaled(self.imageSize, Qt.Qt.IgnoreAspectRatio, Qt.Qt.SmoothTransformation)
        else:
            img = image
        if img.isNull():
            return
        width: int = self.size().width() - 24
        _colCount: int = width // self.ImageW
        label: Qt.QLabel = Qt.QLabel()
        label.setScaledContents(False)
        label.setFixedSize(self.imageSize)
        label.setPixmap(Qt.QPixmap.fromImage(img))
        label.setContentsMargins(0, 0, 0, 0)
        self.Images.append(label)

        self.Flow.addWidget(label, self.Row, self.Col, 1, 1)
        self.Col += 1
        if self.Col > _colCount:
            self.Col = 0
            self.Row += 1
            self.Boxs.setMinimumHeight(self.ImageH * (self.Row + 2))
            self.Area.verticalScrollBar().setValue(self.Area.verticalScrollBar().maximum())

    # def appendCellImage(self, image: Qt.QImage):
    #     Locker: Qt.QWriteLocker = Qt.QWriteLocker(self.IOLocker)
    #     if not isinstance(image, Qt.QImage):
    #         return
    #     self.initImageSize()
    #     self.initImages()
    #     img: Qt.QImage
    #     if image.width() != self.CellImageW or image.height() != self.CellImageH:
    #         img = image.scaled(Qt.QSize(self.CellImageW, self.CellImageH), Qt.Qt.IgnoreAspectRatio, Qt.Qt.SmoothTransformation)
    #     else:
    #         img = image
    #     if img.isNull():
    #         return
    #     width: int = self.size().width() - 24
    #     _colCount: int = width // self.CellImageW
    #     label: Qt.QLabel = Qt.QLabel()
    #     label.setScaledContents(False)
    #     label.setFixedSize(Qt.QSize(self.CellImageW, self.CellImageH))
    #     label.setPixmap(Qt.QPixmap.fromImage(img))
    #     label.setContentsMargins(0, 0, 0, 0)
    #     self.Images.append(label)
    #
    #     self.Flow.addWidget(label, self.Row, self.Col, 1, 1)
    #     self.Col += 1
    #     if self.Col > _colCount:
    #         self.Col = 0
    #         self.Row += 1
    #         self.Boxs.setMinimumHeight(self.CellImageH * (self.Row + 2))
    #         self.Area.verticalScrollBar().setValue(self.Area.verticalScrollBar().maximum())

    def initValue(self):
        super(CellFlowView, self).initValue()
        self.initWindows()
        self.initImageSize()
        self.isClear = False

    def initProperty(self):
        super(CellFlowView, self).initProperty()
        self.initImageSize()
        self.Row = 0
        self.Col = 0
        self.setMinimumWidth(self.ImageW * 4 + 30)
        self.setMinimumHeight(self.ImageH * 4   )



    def initLayouts(self):
        if self.hasWindowLayouts:
            return
        widget_layout: Qt.QHBoxLayout = Qt.QHBoxLayout()
        widget_layout.setSpacing(0)
        widget_layout.setContentsMargins(0, 0, 0, 0)
        self.Boxs.setLayout(self.Flow)
        self.Boxs.setMinimumWidth(self.ImageW * 5 + 10)
        self.Boxs.setMinimumHeight(self.ImageH * 5)
        if self.Area.widget() != self.Boxs:
            self.Area.setWidget(self.Boxs)

        self.Area.setWidget(self.Boxs)
        widget_layout.addWidget(self.Area)
        self.setLayout(widget_layout)

    def initWindows(self):
        self.initFlow()
        self.initBoxs()
        self.initArea()
        self.initImages()

    @property
    def imageSize(self) -> Qt.QSize:
        self.initImageSize()
        return Qt.QSize(self.ImageW, self.ImageH)

    def initFlow(self):
        if not self.hasFlow:
            self.Flow = Qt.QGridLayout   ()
            self.Flow.setContentsMargins(0, 0, 0, 0)
            self.Flow.setSpacing(0)
            self.Flow.setAlignment(Qt.Qt.AlignLeft | Qt.Qt.AlignTop)

    def initBoxs(self):
        if not self.hasBoxs:
            self.Boxs = Qt.QWidget (self)
    def initImageSize(self):
        if not self.hasImageW  or not self.ImageH:
            self.ImageW, self.ImageH = ImageConfigModel.ImageListSize()

        self.CellImageW, self.CellImageH = int(self.ImageW * 1.5), self.ImageH
    def initArea(self):
        if not self.hasArea:
            self.Area = Qt.QScrollArea()
    def initImages(self):
        if not self.hasImages:
            self.Images = []

    @property
    def hasFlow(self) -> bool:
        return hasattr(self, 'Flow') and isinstance(self.Flow, FlowLayout  )

    @property
    def hasBoxs(self) -> bool:
        return hasattr(self, 'Boxs') and isinstance(self.Boxs, Qt.QWidget)

    @property
    def hasImageW(self) -> bool:
        return hasattr(self, 'ImageW') and isinstance(self.ImageW, int)

    @property
    def hasImageH(self) -> bool:
        return hasattr(self, 'ImageH') and isinstance(self.ImageH, int)
    @property
    def hasArea(self) -> bool:
        return hasattr(self, 'Area') and isinstance(self.Area, Qt.QScrollArea)

    @property
    def hasImages(self) -> bool:
        return hasattr(self, 'Images') and isinstance(self.Images, list)