import os
import shutil
import subprocess
import time
import sys
from pathlib import Path
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
from logger import get_system_logger, log_exception

# ==========================================
# 接口配置
# ==========================================
STAGE_DIR = r'./stage'
BACKUP_DIR = r'./backup'
SESSION_DIR = r'./session'
MIN_DURATION_SECONDS = 15 * 60 
VIDEO_EXTS = {'.mp4', '.mkv', '.avi', '.mov', '.flv', '.wmv'}

# 初始化日志
logger = get_system_logger('monitor')
# ==========================================

def get_video_duration(file_path):
    try:
        cmd = ['ffprobe', '-v', 'error', '-show_entries', 'format=duration', '-of', 'default=noprint_wrappers=1:nokey=1', str(file_path)]
        result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        duration = float(result.stdout)
        logger.debug(f"获取视频时长: {file_path.name} = {duration}秒")
        return duration
    except Exception as e:
        log_exception(logger, e, f"获取视频时长失败: {file_path}")
        return 0

class VideoHandler(FileSystemEventHandler):
    def on_created(self, event):
        if not event.is_directory:
            # 兼容处理 watchdog 路径编码问题
            src_path = event.src_path
            if isinstance(src_path, bytes):
                src_path = src_path.decode('utf-8')
            
            logger.debug(f"检测到文件创建事件: {src_path}")
            self.handle_file(Path(src_path))

    def handle_file(self, file_path):
        if file_path.suffix.lower() not in VIDEO_EXTS: 
            logger.debug(f"跳过非视频文件: {file_path.name}")
            return
        
        logger.info(f"发现新视频文件: {file_path.name}，正在检查写入状态...")
        
        # 改进：通过检查文件大小变化来判断是否写入完成
        last_size = -1
        while True:
            try:
                if not file_path.exists():
                    logger.warning(f"文件在检查期间消失: {file_path}")
                    return
                current_size = file_path.stat().st_size
                if current_size == last_size and current_size > 0:
                    break
                last_size = current_size
                time.sleep(5) # 每5秒检查一次大小
            except Exception as e:
                logger.error(f"检查文件状态异常: {e}")
                break
        
        try:
            duration = get_video_duration(file_path)
            logger.info(f"视频时长: {file_path.name} = {duration/60:.1f} 分钟")
            
            if duration < MIN_DURATION_SECONDS:
                logger.info(f"时长不足 {MIN_DURATION_SECONDS/60:.0f} 分钟，移动到备份区")
                dst = Path(BACKUP_DIR) / file_path.name
                shutil.move(str(file_path), str(dst))
                logger.info(f"已移动至备份: {dst}")
            else:
                # 核心联动：创建专属工作区
                session_folder = Path(SESSION_DIR) / file_path.stem
                session_folder.mkdir(parents=True, exist_ok=True)
                logger.info(f"创建工作区: {session_folder}")
                
                logger.info(f"派发转录任务: {file_path.name}")
                # 改进：使用 sys.executable 保证环境一致性
                process = subprocess.Popen([
                    sys.executable, 'video2srt.py', 
                    str(file_path), 
                    str(session_folder)
                ])
                logger.info(f"转录进程已启动 (PID: {process.pid})")
                
        except Exception as e:
            log_exception(logger, e, "监控处理异常")

if __name__ == "__main__":
    logger.info("="*50)
    logger.info("视频监控模块启动")
    logger.info("="*50)
    
    for d in [STAGE_DIR, BACKUP_DIR, SESSION_DIR]: 
        Path(d).mkdir(parents=True, exist_ok=True)
    logger.info(f"监控目录: {STAGE_DIR}")
    logger.info(f"备份目录: {BACKUP_DIR}")
    logger.info(f"工作目录: {SESSION_DIR}")
    
    handler = VideoHandler()
    
    # 启动时扫描已有文件
    logger.info("正在扫描 stage 目录下的存量视频...")
    for f in Path(STAGE_DIR).iterdir():
        if f.is_file():
            handler.handle_file(f)
            
    observer = Observer()
    observer.schedule(handler, STAGE_DIR, recursive=False)
    observer.start()
    logger.info("文件监控已启动")
    
    try:
        while True: time.sleep(1)
    except KeyboardInterrupt:
        logger.info("接收到停止信号，正在关闭...")
        observer.stop()
    observer.join()
    logger.info("视频监控模块已停止")
