import subprocess
import os
import sys
import textwrap
import random

#  Validate input arguments
if len(sys.argv) < 6:
    print("Usage: python make_video.py <image> <audio> <font.ttf> <text> <output.mp4> [logo.png] [watermark text]")
    print("Optional: pass '' for logo or watermark if not needed.")
    sys.exit(1)

image = sys.argv[1]
audio = sys.argv[2]
font = sys.argv[3]
raw_text = sys.argv[4]
output = os.path.abspath(sys.argv[5])
logo = sys.argv[6] if len(sys.argv) > 6 and sys.argv[6] != "''" else None
watermark_text = sys.argv[7] if len(sys.argv) > 7 and sys.argv[7] != "''" else None

def get_duration(file):
    cmd = [
        "ffprobe", "-v", "error",
        "-show_entries", "format=duration",
        "-of", "default=noprint_wrappers=1:nokey=1", file
    ]
    try:
        out = subprocess.check_output(cmd).decode().strip()
        return float(out)
    except subprocess.CalledProcessError as e:
        print("Error getting audio duration:")
        print(e.output.decode())
        sys.exit(1)

def split_lines(text, width=22):
    wrapped = textwrap.wrap(text, width=width)
    padded = [f"    {line}    " for line in wrapped]
    escaped = [line.replace(":", "\\:").replace(",", "\\,") for line in padded]
    return escaped

#  Prepare text and duration
lines = split_lines(raw_text)
duration = get_duration(audio)
framecount = int(duration * 30)
z_expr = f"1.0+0.3*sin(PI*on/{framecount})"

fontsize = 48
spacing = 64
last_label = "v0"
inputs = ["-loop", "1", "-i", image, "-i", audio]
if logo:
    inputs += ["-i", logo]

#  Base image + zoom effect + semi-transparent black overlay
filter_complex = (
    f"[0:v]scale=720:1280,format=rgba,"
    f"drawbox=x=0:y=0:w=iw:h=ih:color=black@0.4:t=fill,"
    f"zoompan=z='{z_expr}':d=1:x='iw/2-(iw/zoom/2)':y='ih/2-(ih/zoom/2)',"
    f"scale=720:1280[{last_label}]"
)

#  Logo overlay (top-right)
if logo:
    filter_complex += (
        f";[2:v]scale=80:80,format=rgba,colorchannelmixer=aa=0.4[logo];"
        f"[{last_label}][logo]overlay=W-w-40:20[v1]"
    )
    last_label = "v1"

#  Watermark text (faint white, random position)
if watermark_text:
    rand_x = random.randint(40, 600)
    rand_y = random.randint(100, 1000)
    safe_wm = watermark_text.replace(":", "\\:").replace("'", "\\'")
    filter_complex += (
        f";[{last_label}]drawtext=fontfile='{font}':"
        f"text='{safe_wm}':x={rand_x}:y={rand_y}:fontsize=36:"
        f"fontcolor=white@0.15:box=1:boxcolor=black@0.2[v2]"
    )
    last_label = "v2"

#  Centered multiline yellow text with transparent black box
for i, line in enumerate(lines):
    y_center = 720
    y_offset = (i - len(lines)//2) * spacing
    y_pos = f"{y_center + y_offset - fontsize//2}"
    safe_line = line.replace(":", "\\:").replace("'", "\\'")
    draw = (
        f"drawtext=fontfile='{font}':text='{safe_line}':"
        f"fontcolor=yellow:fontsize={fontsize}:"
        f"borderw=3:bordercolor=black@0.8:"
        f"x=(w-text_w)/2:y={y_pos}:"
        f"box=1:boxcolor=black@0.5:boxborderw=10"
    )
    filter_complex += f";[{last_label}]{draw}[v{i}]"
    last_label = f"v{i}"

#  Final map
final_map = last_label

#  FFmpeg command
cmd = ["ffmpeg", "-y"] + inputs + [
    "-filter_complex", filter_complex,
    "-map", f"[{final_map}]",
    "-map", "1:a",
    "-shortest",
    "-movflags", "+faststart",
    "-pix_fmt", "yuv420p",
    "-c:v", "libx264", "-preset", "veryfast", "-crf", "23",
    "-c:a", "aac", "-b:a", "128k",
    output
]

#  Run FFmpeg
print(" Generating video with:")
print("- Smooth zoom background")
print("- Centered yellow text with black overlay")
print("- Optional logo & watermark")
print(f"Output: {output}")

result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)

if result.returncode != 0:
    print("FFmpeg failed:\n", result.stderr)
    sys.exit(1)
elif not os.path.exists(output):
    print(" Output file not found.")
    sys.exit(1)
else:
    size = os.path.getsize(output)
    if size > 1000:
        print(f" Video created successfully: {output} ({size / 1024:.1f} KB)")
    else:
        print(" Output file is too small.")
