#!/usr/bin/env python
# -*- coding: UTF-8 -*-

'''
@Project: NarratoAI
@File   : generate_video
@Author : Viccy同学
@Date   : 2025/5/7 上午11:55 
'''
import logging
import os
import subprocess
import traceback
from typing import Optional, Dict, Any

from PIL import ImageFont
from app.utils import ffmpeg_utils

# 配置日志
logger = logging.getLogger(__name__)


def get_video_duration(video_path: str) -> float:
    """获取视频时长（用于BGM循环）"""
    try:
        result = subprocess.run(
            ['ffmpeg', '-i', video_path, '-hide_banner', '-loglevel', 'error', '-show_entries', 'format=duration',
             '-of', 'default=noprint_wrappers=1:nokey=1'],
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            text=True
        )
        return float(result.stdout.strip()) if result.stdout else 0.0
    except:
        return 0.0


def check_hardware_acceleration() -> Optional[str]:
    """
    检查系统支持的硬件加速选项

    Returns:
        Optional[str]: 硬件加速参数，如果不支持则返回None
    """
    # 使用集中式硬件加速检测
    return ffmpeg_utils.get_ffmpeg_hwaccel_type()


def get_safe_encoder_config(hwaccel_type: Optional[str] = None) -> Dict[str, str]:
    """
    获取安全的编码器配置，基于ffmpeg_demo.py成功方案优化

    Args:
        hwaccel_type: 硬件加速类型

    Returns:
        Dict[str, str]: 编码器配置字典
    """
    # 基础配置 - 参考ffmpeg_demo.py的成功方案
    config = {
        "video_codec": "libx264",
        "audio_codec": "aac",
        "pixel_format": "yuv420p",
        "preset": "fast",
        "quality_param": "crf",  # 质量参数类型
        "quality_value": "23"  # 质量值
    }

    # 根据硬件加速类型调整配置（简化版本）
    if hwaccel_type in ["nvenc_pure", "nvenc_software", "cuda_careful", "nvenc", "cuda", "cuda_decode"]:
        # NVIDIA硬件加速 - 使用ffmpeg_demo.py中验证有效的参数
        config["video_codec"] = "h264_nvenc"
        config["preset"] = "fast"
        config["quality_param"] = "cq"  # CQ质量控制，而不是CRF
        config["quality_value"] = "23"
        config["pixel_format"] = "yuv420p"
    elif hwaccel_type == "amf":
        # AMD AMF编码器
        config["video_codec"] = "h264_amf"
        config["preset"] = "balanced"
        config["quality_param"] = "qp_i"
        config["quality_value"] = "23"
    elif hwaccel_type == "qsv":
        # Intel QSV编码器
        config["video_codec"] = "h264_qsv"
        config["preset"] = "fast"
        config["quality_param"] = "global_quality"
        config["quality_value"] = "23"
    elif hwaccel_type == "videotoolbox":
        # macOS VideoToolbox编码器
        config["video_codec"] = "h264_videotoolbox"
        config["preset"] = "fast"
        config["quality_param"] = "b:v"
        config["quality_value"] = "5M"
    else:
        # 软件编码（默认）
        config["video_codec"] = "libx264"
        config["preset"] = "fast"
        config["quality_param"] = "crf"
        config["quality_value"] = "23"

    return config


def merge_materials(
        video_path: str,
        audio_path: str,
        output_path: str,
        subtitle_path: Optional[str] = None,
        bgm_path: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None
) -> str:
    from app.services.com_video import merge_materials
    return merge_materials(video_path, audio_path, output_path, subtitle_path, bgm_path, options)


def is_valid_subtitle_file(subtitle_path: str) -> bool:
    """
    检查字幕文件是否有效

    参数:
        subtitle_path: 字幕文件路径

    返回:
        bool: 如果字幕文件存在且包含有效内容则返回True，否则返回False
    """
    if not subtitle_path or not os.path.exists(subtitle_path):
        return False

    try:
        with open(subtitle_path, 'r', encoding='utf-8') as f:
            content = f.read().strip()

        # 检查文件是否为空
        if not content:
            return False

        # 检查是否包含时间戳格式（SRT格式的基本特征）
        # SRT格式应该包含类似 "00:00:00,000 --> 00:00:00,000" 的时间戳
        import re
        time_pattern = r'\d{2}:\d{2}:\d{2},\d{3}\s*-->\s*\d{2}:\d{2}:\d{2},\d{3}'
        if not re.search(time_pattern, content):
            return False

        return True
    except Exception as e:
        logger.warning(f"检查字幕文件时出错: {str(e)}")
        return False


def get_video_encoder():
    hwaccel_type = check_hardware_acceleration()
    encoder_config = get_safe_encoder_config(hwaccel_type)
    return encoder_config['video_codec']


def wrap_text(text, max_width, font="Arial", fontsize=60):
    """
    文本换行函数，使长文本适应指定宽度
    
    参数:
        text: 需要换行的文本
        max_width: 最大宽度（像素）
        font: 字体路径
        fontsize: 字体大小
        
    返回:
        换行后的文本和文本高度
    """
    # 创建ImageFont对象
    try:
        font_obj = ImageFont.truetype(font, fontsize)
    except:
        # 如果无法加载指定字体，使用默认字体
        font_obj = ImageFont.load_default()

    def get_text_size(inner_text):
        inner_text = inner_text.strip()
        left, top, right, bottom = font_obj.getbbox(inner_text)
        return right - left, bottom - top

    width, height = get_text_size(text)
    if width <= max_width:
        return text, height

    processed = True

    _wrapped_lines_ = []
    words = text.split(" ")
    _txt_ = ""
    for word in words:
        _before = _txt_
        _txt_ += f"{word} "
        _width, _height = get_text_size(_txt_)
        if _width <= max_width:
            continue
        else:
            if _txt_.strip() == word.strip():
                processed = False
                break
            _wrapped_lines_.append(_before)
            _txt_ = f"{word} "
    _wrapped_lines_.append(_txt_)
    if processed:
        _wrapped_lines_ = [line.strip() for line in _wrapped_lines_]
        result = "\n".join(_wrapped_lines_).strip()
        height = len(_wrapped_lines_) * height
        return result, height

    _wrapped_lines_ = []
    chars = list(text)
    _txt_ = ""
    for word in chars:
        _txt_ += word
        _width, _height = get_text_size(_txt_)
        if _width <= max_width:
            continue
        else:
            _wrapped_lines_.append(_txt_)
            _txt_ = ""
    _wrapped_lines_.append(_txt_)
    result = "\n".join(_wrapped_lines_).strip()
    height = len(_wrapped_lines_) * height
    return result, height


if __name__ == '__main__':
    merger_mp4 = '/Users/apple/Desktop/home/NarratoAI/storage/tasks/qyn2-2-demo/merger.mp4'
    merger_sub = '/Users/apple/Desktop/home/NarratoAI/storage/tasks/qyn2-2-demo/merged_subtitle_00_00_00-00_01_30.srt'
    merger_audio = '/Users/apple/Desktop/home/NarratoAI/storage/tasks/qyn2-2-demo/merger_audio.mp3'
    bgm_path = '/Users/apple/Desktop/home/NarratoAI/resource/songs/bgm.mp3'
    output_video = '/Users/apple/Desktop/home/NarratoAI/storage/tasks/qyn2-2-demo/combined_test.mp4'

    # 调用示例
    options = {
        'voice_volume': 1.0,  # 配音音量
        'bgm_volume': 0.1,  # 背景音乐音量
        'original_audio_volume': 1.0,  # 视频原声音量，0表示不保留
        'keep_original_audio': True,  # 是否保留原声
        'subtitle_enabled': True,  # 是否启用字幕 - 修复字幕开关bug
        'subtitle_font': 'MicrosoftYaHeiNormal.ttc',  # 这里使用相对字体路径，会自动在 font_dir() 目录下查找
        'subtitle_font_size': 40,
        'subtitle_color': '#FFFFFF',
        'subtitle_bg_color': None,  # 直接使用None表示透明背景
        'subtitle_position': 'bottom',
        'threads': 2
    }

    try:
        merge_materials(
            video_path=merger_mp4,
            audio_path=merger_audio,
            subtitle_path=merger_sub,
            bgm_path=bgm_path,
            output_path=output_video,
            options=options
        )
    except Exception as e:
        logger.error(f"合并素材失败: \n{traceback.format_exc()}")
