import threading
import queue
import datetime
import cv2
from core.DBManager import DBManager
from myutils.ConfigManager import myCongif

class WarnData:
    def __init__(self):
        self.width  = None  #视频画面的width
        self.height = None  #视频画面的height
        self.channel_id = None
        self.model_name = None  #模型名称,如人员入侵
        self.img_buffer = None      #视频缓冲区      赋值时要拷贝一个备份

        self.warn_text = None
        self.channel_name = None



class WarnManager:
    def __init__(self):
        self.warn_q = queue.Queue() #线程安全
        self.brun = True
        # 保存视频相关内容
        self.FPS = myCongif.get_data("verify_rate")  # 视频帧率--是否能实现动态帧率
        self.fourcc = cv2.VideoWriter_fourcc(*'mp4v')  # 使用 mp4 编码

    def __del__(self):
        pass

    def add_warn_data(self,warn_data):
        self.warn_q.put(warn_data)

    def th_warnmanager(self):
        myDBM = DBManager()
        myDBM.connect()
        while self.brun:
            warn_data = None
            try:
                warn_data = self.warn_q.get(timeout=5)
            except queue.Empty:
                continue
            if warn_data:
                ret = self.save_warn(warn_data.model_name,warn_data.img_buffer,warn_data.width,warn_data.height,
                               warn_data.channel_id,self.FPS,self.fourcc,myDBM)
                self.send_warn()
                del warn_data.img_buffer
                warn_data.img_buffer = None
                del warn_data
                warn_data = None


    def start_warnmanager_th(self):
        th_warn = threading.Thread(target=self.th_warnmanager)  # 一个视频通道一个线程,线程句柄暂时部保留
        th_warn.start()

    def stop_warnmanager_th(self):
        self.brun = False
        del self.warn_q

    def send_warn(self):
        '''发送报警信息'''
        pass

    def save_warn(self,model_name,buffer,width,height,channnel_id,FPS,fourcc,myDBM):
        '''
        保存报警信息 --- 涉及到I/O操作可以通过线程取执行 -- 避免主线程阻塞 --还未验证-2024-7-6
        :param model_name: 模型名称,如人员入侵
        :param w_s_count:  报警已存储的最新帧序列
        :param buffer_count: 当前视频缓冲区的最新帧序列
        :param buffer:      视频缓存区
        :param width:       视频画面的width
        :param height:      视频画面的height
        :param channnel_id: 视频通道ID
        :return: ret        数据库操作记录
        '''
        now = datetime.datetime.now()  # 获取当前日期和时间
        current_time_str = now.strftime("%Y-%m-%d_%H-%M-%S")
        filename = f"{channnel_id}_{current_time_str}"
        save_path = myCongif.get_data("warn_video_path")
        # 保存视频
        str_video = f"{save_path}{filename}.mp4"
        video_writer = cv2.VideoWriter(str_video, fourcc, FPS, (width, height))
        #print(f"File: {str_video}, FourCC: {fourcc}, FPS: {FPS}, Size: ({width}, {height})")
        if not video_writer.isOpened():
            print(f"Failed to open video writer for model/warn/{filename}.mp4")
            return False
        ilen = len(buffer)
        istart = 0;
        iend = ilen

        for i in range(len(buffer)):
            video_writer.write(buffer[i])
        video_writer.release()
        # 保存图片
        ret = cv2.imwrite(f"model/warn/{filename}.png", buffer[-1])
        # buffer使用完后删除
        del buffer
        if not ret:
            print("保存图片失败")
            return False
        # 保存数据库

        strsql = (f"INSERT INTO warn (model_name ,video_path ,img_path ,creat_time,channel_id ) "
                  f"Values ('{model_name}','model/warn/{filename}.mp4','model/warn/{filename}.png',"
                  f"'{current_time_str}','{channnel_id}');")
        ret = myDBM.do_sql(strsql)
        return ret