#!D:/IDE/anaconda3/envs/Microscope_Scan python
# -*- coding: UTF-8 -*-
"""
@FileName：StatusController.py
@Description：
@Author：XSH
@Time：2025/11/15 11:53
@Department：研发部
@Copyright：©2025 乐辰生物
"""
import asyncio
from qasync import QEventLoop, asyncSlot
import numpy as np
import cv2
from PyQt5                                                  import Qt                       #
from AppInterfaces.utils                                    import *                        #
from AppUtils.utils                                         import *                        #
from AppInterfaces.EventInterfaces                          import *                        #
from AppCore.Levels                                         import *                        #
from AppInterfaces.ReaderInterfaces                         import WebReaderInterface       #
from AppCore.Requests                                       import *                        #
from AppInterfaces.ConfigureInterfaces                      import StatusConfigInterface    #

class StatusController(Qt.QThread, AppEventInterface, SingletonInterface):
    AppendItem: Qt.pyqtSignal = Qt.pyqtSignal(object)
    AppendText: Qt.pyqtSignal = Qt.pyqtSignal(str)
    _IOLocker   : Qt.QReadWriteLock         = Qt.QReadWriteLock()           #
    Locker      : Qt.QMutex                 = Qt.QMutex()                   #
    WebServer   : WebReaderInterface                                        #
    WaitTimes   : int

    @classmethod
    def GetInstance(cls, *args, **kwargs) -> 'StatusController':
        return super(StatusController, cls).GetInstance(*args, **kwargs)

    def __init__(self, parent: Qt.QObject = None):
        super(StatusController, self).__init__(parent=parent)
        self.Initialization('StatusController', self, parent)
        self.Mode = EventLevel.WebSocketMode
        self.WaitTimes = 3000
        self.is_async = True


    def initConnect(self):
        super(StatusController, self).initConnect()
        TYPE: Qt.Qt.ConnectionType = Qt.Qt.ConnectionType(Qt.Qt.AutoConnection | Qt.Qt.UniqueConnection)
        AppSlot.ClearImageListSignal.connect(slot=self.SlotClearImageListSignal, type=TYPE)
        self.AppendText.connect(slot=self.SlotAppendText, type=TYPE)
        self.AppendItem.connect(slot=self.SlotAppendItem, type=TYPE)

    def SlotAppendItem(self, item):
        self.appendItem(item)

    def SlotClearImageListSignal(self, info, name):
        if isinstance(info, str) and info == 'changedSlide':
            self.SendEvent(Request.APIClearPreview(changedSlide=True))
        elif isinstance(name, str) and name == 'changedSlide':
            self.SendEvent(Request.APIClearPreview(changedSlide=True))
        else:
            self.SendEvent(Request.APIClearPreview(changedSlide=False))

    def StartFocusing(self, isShowFocusing: bool = True, **args):
        self.initPools()
        self.Start()

    def StopFocusing(self, isShowFocusing: bool = True, **args):
        pass

    def SlotAppendText(self, text):
        if not self.isRunning():
            self.is_running = True
            self.start(Qt.QThread.NormalPriority)
        if isinstance(text, str):
            with self.condition:
                self.DataBuffer.put(text)
                self.condition.notify_all()

    def appendItem(self, item: (Response, Request), *args, **kwargs):
        if not self.isRunning():
            self.is_running = True
            self.start(Qt.QThread.NormalPriority)
        if isinstance(item, (Response, Request)):
            with self.condition:
                self.DataBuffer.put(item)
                self.condition.notify_all()

    def initValue(self):
        super(StatusController, self).initValue()
        self.initPools()

    def SendEvent(self, value, **args):
        self.AppendItem.emit(value)
        AppTimeLoop.processGlobalEvents(200)

    def StartWork(self):
        self.initPools  ()
        self.Start      ()

    def StopWork(self):
        self.delePools()



    def Start(self):
        if self.isRunning():
            return
        self.initPools()
        self.is_running = True
        self.start(Qt.QThread.NormalPriority)

    def initPools(self):
        self.initWebServer()

    def delePools(self):
        pass


    def run(self) -> None:
        if self.isAsync:
            asyncio.run(self.async_process())
        else:
            self.process()


    async def async_process(self):
        self.process()


    def process(self):
        self.is_running = True
        self.is_finish = False
        while self.is_running:
            with self.condition:
                if not self.is_running:
                    break
                try:
                    self.WaitDone(None)
                except Exception as e:
                    AppUtils.print_Exception(e)
                AppTimeLoop.processEvents(self.waittimes)
        self.is_running = False
        self.is_finish = True
        if isinstance(self, Qt.QThread):
            print("%-20s \t线程结束\tID:%-20s\n" % (self.__class__.__name__, self.currentThreadId().__int__()))
        elif isinstance(self, threading.Thread):
            print("%-20s \t线程结束\tID:%-20s\n" % (self.__class__.__name__, self.ident))
    def WaitDone(self, item, *args, **kwargs):
        try:
            if not self.hasWebServer:
                self.initWebServer()
            if not self.webserver.IsOpen:
                self.webserver.ReOpen()
            from AppSettings.AppStatusSetting import AppStatus
            request: Request = Request.APIInstance(WebAPILevel.getScanningData)
            request.data = AppStatus.scanningstatus()
            print("StatusController WaitDone", AppStatus.ScanningDateTime)
            self.webserver.SendRequest(request.toJson())

        except Exception as e:
            from AppLog.logHelper import logWEBSERVER
            logWEBSERVER << AppUtils.toString(e)

    @property
    def hasWebServer(self) -> bool:
        return hasattr(self, 'WebServer') and isinstance(self.WebServer, WebReaderInterface)

    @property
    def webserver(self) -> WebReaderInterface:
        return None if not self.hasWebServer else self.WebServer

    def initWebServer(self):
        if not self.hasWebServer:
            from AppCore.AppReaders.WebReader import appWebReader
            self.WebServer = appWebReader


    @property
    def hasWaitTimes(self) -> bool:
        return self.has_field('WaitTimes', (float, int))

    @property
    def waittimes(self) -> float:
        self.initWaitTimes()
        return self.WaitTimes


    def initWaitTimes(self):
        if not self.hasWaitTimes:
            self.WaitTimes = 1000



ScanStatusController: StatusController = StatusController.GetInstance()
