"""
Studio Historical-2d - Episode 01: Cannae 216 BC
Bridge Voiceover & Seamless Transition Generator
Author: Arthur Pendelton (Head of Audio & Multilingual Localization)
"""

import os
import asyncio
import subprocess
import edge_tts
import numpy as np
import wave

BASE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))
AUDIO_VOICE_DIR = os.path.join(BASE_DIR, "episodes", "EP01_Cannae_216BC", "04_Audio_Voice")
BRIDGE_DIR = os.path.join(AUDIO_VOICE_DIR, "bridge")
VOICE_VI_DIR = os.path.join(AUDIO_VOICE_DIR, "voice_vi")
VOICE_EN_DIR = os.path.join(AUDIO_VOICE_DIR, "voice_en")

os.makedirs(BRIDGE_DIR, exist_ok=True)
os.makedirs(VOICE_VI_DIR, exist_ok=True)
os.makedirs(VOICE_EN_DIR, exist_ok=True)

SAMPLE_RATE = 44100

BRIDGE_TEXT_VI = "Và hành trình của chúng ta bắt đầu tại chảo lửa Apulia, miền Nam nước Ý... Mùa hè năm 216 Trước Công Nguyên."
BRIDGE_TEXT_EN = "And our journey begins in the crucible of Apulia, southern Italy... The summer of 216 BC."

CUE1_TEXT_VI = (
    "Hãy nhìn vào những khối cờ lệnh này trên sa bàn. Ngày hôm nay, chúng ta cùng giải mã một trong những nghịch lý quân sự vĩ đại và đẫm máu nhất trong lịch sử nhân loại: "
    "Làm thế nào mà một đạo quân La Mã đông kỷ lục — hơn tám vạn sáu ngàn binh sĩ dày dạn, được trang bị vũ khí tối tân nhất của thời cổ đại — "
    "lại có thể tự bước chân vào một cái bẫy không lối thoát, để rồi bị xóa sổ hoàn toàn chỉ trong một buổi chiều bởi một lực lượng đối phương có quân số chưa bằng một nửa? "
    "Thảm họa này không bắt nguồn từ sự hèn nhát của những người lính cầm khiên. Nó bắt nguồn từ chính sự kiêu ngạo của một cỗ máy cơ học khổng lồ, "
    "và sự tính toán lạnh lùng đến từng milimet đất của một thiên tài quân sự: Hannibal Barca. "
    "Hãy cùng tôi lật lại từng trang bản đồ tác chiến của ngày định mệnh ấy."
)

CUE1_TEXT_EN = (
    "Look upon these command markers on the sandtable. Today, we decode one of the greatest and bloodiest military paradoxes in human history: "
    "How could a record Roman army — over eighty-six thousand seasoned legionaries, equipped with the finest weapons of the ancient world — "
    "march straight into an inescapable trap, only to be completely annihilated in a single afternoon by an enemy force less than half their size? "
    "This catastrophe did not stem from cowardice among the men holding the scutum shields. It arose from the mechanical hubris of a colossal war machine, "
    "and the glacial, millimeter precision of a military prodigy: Hannibal Barca. "
    "Join me as we unfold the battle maps of that fateful day."
)

async def synthesize_voice(text, voice, rate="-4%", pitch="-2Hz", output_path="voice.mp3"):
    """
    Synthesize speech using edge-tts with documentary voice parameters.
    """
    communicate = edge_tts.Communicate(text, voice, rate=rate, pitch=pitch)
    await communicate.save(output_path)
    print(f"[OK] Voice synthesized: {output_path}")
    return output_path

def apply_documentary_eq_and_normalize(input_mp3, output_wav, lang="en"):
    """
    Apply warm Baritone Broadcast EQ, subtle micro-pause dynamics, and EBU R128 loudness normalization (-14 LUFS).
    """
    # Documentary EQ:
    # 1. Warm chest resonance: +2.5 dB @ 120Hz (Q=1.2)
    # 2. De-box muddy low-mids: -1.5 dB @ 450Hz (Q=1.5)
    # 3. Articulation & Presence: +1.8 dB @ 3800Hz (Q=1.0)
    # 4. Air polish: +1.0 dB @ 11000Hz shelf
    # 5. EBU R128 normalization (-14 LUFS, TP -1.0)
    eq_filter = (
        "equalizer=f=120:t=q:w=1.2:g=2.5,"
        "equalizer=f=450:t=q:w=1.5:g=-1.5,"
        "equalizer=f=3800:t=q:w=1.0:g=1.8,"
        "equalizer=f=11000:t=h:g=1.0,"
        "loudnorm=I=-14.0:TP=-1.0:LRA=11.0"
    )
    cmd = [
        "ffmpeg", "-y",
        "-i", input_mp3,
        "-af", eq_filter,
        "-ar", str(SAMPLE_RATE),
        output_wav
    ]
    subprocess.run(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=True)
    return output_wav

def mix_bridge(voice_wav, sfx_wav, output_mix_wav):
    """
    Hòa trộn 5.0s Audio Bridge: Voice (-14 LUFS anchor) + SFX Background (-24 LUFS).
    Đảm bảo tuyệt đối không giật nổ, mượt mà chuẩn phát thanh EBU R128 (-14.0 LUFS).
    """
    cmd = [
        "ffmpeg", "-y",
        "-i", voice_wav,
        "-i", sfx_wav,
        "-filter_complex",
        "[0:a]volume=1.0[v_voice];"
        "[1:a]volume=0.45[v_sfx];"
        "[v_voice][v_sfx]amix=inputs=2:duration=first:dropout_transition=0.5[a_raw];"
        "[a_raw]loudnorm=I=-14.0:TP=-1.0:LRA=11.0[a_norm]",
        "-map", "[a_norm]",
        "-ar", str(SAMPLE_RATE),
        output_mix_wav
    ]
    subprocess.run(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=True)
    print(f"[OK] Bridge Full Mix saved: {output_mix_wav}")
    return output_mix_wav

def create_seamless_sequence(intro_audio, bridge_audio, cue1_audio, output_master_sequence):
    """
    Nối liền mạch từ Intro (30.9s) qua Bridge (5.0s) đến Cue 1 (49s) thành một luồng âm thanh
    hoàn chỉnh (duration ~85s), chứng minh việc chuyển cảnh mượt mà, không giật nổ.
    """
    # Use FFmpeg concat filter with smooth equal-power crossfades at boundaries
    cmd = [
        "ffmpeg", "-y",
        "-i", intro_audio,
        "-i", bridge_audio,
        "-i", cue1_audio,
        "-filter_complex",
        "[0:a][1:a]acrossfade=d=0.8:c1=tri:c2=tri[a01];"
        "[a01][2:a]acrossfade=d=0.8:c1=tri:c2=tri[a_full];"
        "[a_full]loudnorm=I=-14.0:TP=-1.0:LRA=11.0[a_master]",
        "-map", "[a_master]",
        "-ar", str(SAMPLE_RATE),
        output_master_sequence
    ]
    subprocess.run(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=True)
    print(f"[OK] Seamless Intro-to-Cue1 Sequence saved: {output_master_sequence}")
    return output_master_sequence

async def main():
    print("--- [STEP 3] Generating Bridge & Cue 1 Voices (VI & EN) ---")
    
    # 1. Bridge Voice VI & EN
    br_mp3_vi = os.path.join(BRIDGE_DIR, "bridge_voice_vi_raw.mp3")
    br_mp3_en = os.path.join(BRIDGE_DIR, "bridge_voice_en_raw.mp3")
    await synthesize_voice(BRIDGE_TEXT_VI, "vi-VN-NamMinhNeural", rate="-2%", pitch="-2Hz", output_path=br_mp3_vi)
    await synthesize_voice(BRIDGE_TEXT_EN, "en-US-ChristopherNeural", rate="-4%", pitch="-2Hz", output_path=br_mp3_en)
    
    br_wav_vi = os.path.join(BRIDGE_DIR, "bridge_voice_vi_eq.wav")
    br_wav_en = os.path.join(BRIDGE_DIR, "bridge_voice_en_eq.wav")
    apply_documentary_eq_and_normalize(br_mp3_vi, br_wav_vi, "vi")
    apply_documentary_eq_and_normalize(br_mp3_en, br_wav_en, "en")
    
    # 2. Cue 1 Voice VI & EN
    c1_mp3_vi = os.path.join(VOICE_VI_DIR, "cue01_cold_open_vi_raw.mp3")
    c1_mp3_en = os.path.join(VOICE_EN_DIR, "cue01_cold_open_en_raw.mp3")
    await synthesize_voice(CUE1_TEXT_VI, "vi-VN-NamMinhNeural", rate="-3%", pitch="-2Hz", output_path=c1_mp3_vi)
    await synthesize_voice(CUE1_TEXT_EN, "en-US-ChristopherNeural", rate="-4%", pitch="-2Hz", output_path=c1_mp3_en)
    
    c1_wav_vi = os.path.join(VOICE_VI_DIR, "cue01_cold_open_vi_master.wav")
    c1_wav_en = os.path.join(VOICE_EN_DIR, "cue01_cold_open_en_master.wav")
    apply_documentary_eq_and_normalize(c1_mp3_vi, c1_wav_vi, "vi")
    apply_documentary_eq_and_normalize(c1_mp3_en, c1_wav_en, "en")
    
    # 3. Mix Bridge Full (Voice + SFX)
    sfx_bridge = os.path.join(BRIDGE_DIR, "cannae_bridge_sfx_5s_master.wav")
    bridge_mix_vi = os.path.join(BRIDGE_DIR, "cannae_bridge_full_mix_vi.wav")
    bridge_mix_en = os.path.join(BRIDGE_DIR, "cannae_bridge_full_mix_en.wav")
    mix_bridge(br_wav_vi, sfx_bridge, bridge_mix_vi)
    mix_bridge(br_wav_en, sfx_bridge, bridge_mix_en)
    
    # 4. Build Seamless Sequence Intro -> Bridge -> Cue 1
    intro_wav = os.path.join(BASE_DIR, "output", "seven_intro_war_room_ambience.wav")
    seq_vi = os.path.join(BRIDGE_DIR, "cannae_seamless_intro_to_cue1_vi.wav")
    seq_en = os.path.join(BRIDGE_DIR, "cannae_seamless_intro_to_cue1_en.wav")
    create_seamless_sequence(intro_wav, bridge_mix_vi, c1_wav_vi, seq_vi)
    create_seamless_sequence(intro_wav, bridge_mix_en, c1_wav_en, seq_en)
    
    print("\n[SUCCESS] Audio Cross-Fade Bridge & Seamless Transition Pipeline completed successfully!")

if __name__ == "__main__":
    asyncio.run(main())
