#!D:\IDE\Anaconda3\envs\Microscope_Scan python
# -*- coding: UTF-8 -*-
"""
@FileName   : SlideTableDropBusiness.py
@Account    : Administrator
@Time       : 2025/9/3 10:23
@Author     : xsh
@Description: 
"""
from PyQt5                                  import Qt
from abc                                    import abstractmethod, abstractclassmethod, abstractstaticmethod
from AppInterfaces.utils                    import *
from AppSettings.utils                      import *
from AppCore.Levels                         import *
from AppCore.Managers                       import *
from AppCore.Impls                          import *
from AppCore.Requests                       import *
from AppCore.DBModels                       import *
from AppUtils.utils                         import *
from AppCore.Events                         import *
from AppBackEnd.AppEventBusBusiness         import *
from AppCore.Readers                        import *
from AppSettings.AppGlobalStatus            import AppGlobalStatus, AppStatus
from AppSettings.AppGlobalAlgorithm         import AppGlobalAlgorithm
from AppCore.AppAlgorithms.ImageAlgorithm   import ImageAlgorithm
from AppBackEnd.AppBusinessController       import AppBusinessController, AppBusinessInterface
class SlideTableDropBusiness(Qt.QObject, AppBusinessController, SingletonInterface):
    Locker      : Qt.QMutex = Qt.QMutex()
    @classmethod
    def GetInstance(cls, *args, **kwargs) -> 'SlideTableDropBusiness':
        return super(SlideTableDropBusiness, cls).GetInstance(*args, **kwargs)
    def __init__(self, parent: AppBusinessInterface = None):
        super(SlideTableDropBusiness, self).__init__(parent=parent if parent is not None else parent.m_Control)
        self.initialize()
        self.ScanLevel = ScanStatusLevel.DropTraySlide_Status
        self.initModules(parent)

    def initModules(self, parent: AppBusinessInterface):
        if isinstance(parent, AppBusinessInterface):
            self.Config                             = parent.config                       #
            self.SystemConfig                       = parent.system                       #
            self.HardWare                           = parent.devices                      #
            self.GlobalStatus                       = parent.status                       #
            self.Application                        = parent.application                  #
            self.Algorithm                          = parent.algorithm                    #
            self.EventBus                           = parent.eventBus                     #
            self.Process                            = parent.process                      #
            self.HitBotConfig                       = parent.hitbotConfig                 #


    def isValid(self) -> bool:
        return self.hasHitBot and self.hasGlobalStatus and self.hasSystemConfig and self.hasConfig
    @property
    def isAvailable(self) -> bool:
        return self.hasHitBot and self.hitbot.isAvailable

    def Done(self, ChamberNumber: int, *args, **kwargs):
        isWrong: int = RECODE_FAILURE
        self.status.setScanningStatus(self.ScanLevel)
        isSafe      : bool  = AppConvert.ObjectConvert(kwargs.get('isSafe'      , True), bool)
        RowNumber   : int   = AppConvert.ObjectConvert(kwargs.get('RowNumber'   , None), int)
        TrayNumber  : int   = AppConvert.ObjectConvert(kwargs.get('TrayNumber'  , None), int)
        isExit      : bool  = AppConvert.ObjectConvert(kwargs.get('isExit'      , True), bool)
        try:
            if isinstance(ChamberNumber, int) and isinstance(RowNumber, int) and isinstance(TrayNumber, int):
                isWrong = self.SlideTableSampleDropping(ChamberNumber, RowNumber, TrayNumber, isSafe, isExit)
        except Exception as e:
            AppUtils.print_Exception(e)
        if self.status.isExit:
            self.status.setScanningStatus(ScanStatusLevel.FinishScanning_Status)
        # elif self.status.isJumpScanning():
        #     self.status.setScanningStatus(ScanStatusLevel.JumpScanning_Status)
        elif not ScanStatusLevel.isHitBotWarning(self.status.scanning_level):
            self.status.changedChamberScanningStatus(ChamberNumber, RowNumber, ScanStatusLevel.DropTraySlide_Warning_Status)
            self.status.setScanningStatus(ScanStatusLevel.DropTraySlide_Warning_Status)

        return

    def WaitDone(self, ChamberNumber: int, *args, **kwargs) -> int:
        isWrong: int = RECODE_FAILURE
        self.status.setScanningStatus(self.ScanLevel)
        isSafe      : bool  = AppConvert.ObjectConvert(kwargs.get('isSafe'      , True), bool   )
        RowNumber   : int   = AppConvert.ObjectConvert(kwargs.get('RowNumber'   , None), int    )
        TrayNumber  : int   = AppConvert.ObjectConvert(kwargs.get('TrayNumber'  , None), int    )
        isExit      : bool  = AppConvert.ObjectConvert(kwargs.get('isExit'      , True), bool   )
        try:
            if isinstance(ChamberNumber, int) and isinstance(RowNumber, int) and isinstance(TrayNumber, int):
                isWrong = self.SlideTableSampleDropping(ChamberNumber, RowNumber, TrayNumber, isSafe, isExit)
        except Exception as e:
            AppUtils.print_Exception(e)
        if self.status.isExit:
            self.status.setScanningStatus(ScanStatusLevel.FinishScanning_Status)
        # elif RECODE_SUCCEED == isWrong:
        #     self.status.setScanningStatus(self.ScanLevel)
        elif not ScanStatusLevel.isHitBotWarning(self.status.scanning_level):
            self.status.changedChamberScanningStatus(ChamberNumber, RowNumber, ScanStatusLevel.DropTraySlide_Warning_Status)
            self.status.setScanningStatus(ScanStatusLevel.DropTraySlide_Warning_Status)
        return isWrong




    def SlideTableSampleDropping(self, chamber_number: int, row_number: int, tray_number: int, isSafe: bool = True, isExit: bool = True) -> int:
        isWrong                 : int
        self.status.setSlideTableStatus(chamber_number, row_number, tray_number)
        isWrong                 = self.readySlideTableSampleDropping(chamber_number, row_number, tray_number)

        if RECODE_SUCCEED != isWrong:
            return isWrong
        if isSafe:
            self.hitbot.moveToSafePosition()

        """处理暂停 退出"""
        while self.status.waitForPauseRunning():
            AppTimeLoop.processEvents(self.system.WarningWaitTimes())
        if isExit:
            if self.status.waitForExitRunning():
                if isSafe:
                    self.hitbot.moveToSafePosition()
                return RECODE_SUCCEED


        isWrong = self.waitForSlideTableDroping(chamber_number, row_number, tray_number)
        tray_status: bool = RECODE_SUCCEED == isWrong and not ScanStatusLevel.isHitBotAlarm(self.status.scanning_level)
        self.status.setTrayStatus(tray_number, tray_status)
        if RECODE_SUCCEED == isWrong:
            """如果所有动作完成 把夹爪状态改为0 """
            self.hitbotConfig.setIsClamp(False)
        else:
            """如果所有动作完成 把夹爪状态改为0 """
            self.hitbotConfig.setIsClamp(True)


        self.status.setSlideTableStatus(chamber_number, row_number, tray_number)
        """如果机械臂错误 直接退出"""
        if ScanStatusLevel.isHitBotAlarm(self.status.scanning_level):
            return RECODE_FAILURE
        if isSafe and RECODE_SUCCEED == isWrong:
            self.hitbot.moveToSafePosition()
        """处理暂停 退出"""
        while self.status.waitForPauseRunning():
            AppTimeLoop.processEvents(self.system.WarningWaitTimes())
        if isExit:
            if self.status.waitForExitRunning():
                return RECODE_SUCCEED
        return isWrong

    def readySlideTableSampleDropping(self, chamber_number: int, row_number: int, tray_number: int) -> int:
        isWrong             : int                           = RECODE_FAILURE
        MinChamberNumber    : int
        MaxChamberNumber    : int
        MinRowNumber        : int
        MaxRowNumber        : int
        MinRowNumber    , MaxRowNumber       = self.system.getRowRange      ()
        MinChamberNumber, MaxChamberNumber   = self.system.getChamberRange  ()
        if MinChamberNumber <= chamber_number <= MaxChamberNumber and MinRowNumber <= row_number <= MaxRowNumber:
            try:
                """如果当前夹抓没有夹到玻片 退出"""
                if not self.hitbotConfig.hitbotIsClamp():
                    if not self.hitbot.IsGrab():
                        return RECODE_FAILURE
                    self.hitbotConfig.setIsClamp(True)
                if not self.isValid():
                    return RECODE_FAILURE
                if not self.isAvailable:
                    return RECODE_FAILURE
                isWrong = RECODE_SUCCEED
            except Exception as e:
                AppUtils.print_Exception(e)
        return isWrong


