import subprocess
import random
import re
from pathlib import Path
from moviepy.editor import VideoFileClip
from pydub import AudioSegment

class VerticalVideoGenerator:
    def __init__(self, source_folder, temp_folder, preview_generator, shorts_resolution=(1080, 1920), target_duration=59):
        """
        Ініціалізація генератора вертикальних відео (Shorts та повних)
        Args:
            source_folder: Папка з фоновими відео
            temp_folder: Папка для тимчасових файлів
            preview_generator: Об'єкт PreviewGenerator для створення превью
            shorts_resolution: Розмір вертикальних відео (ширина, висота)
            target_duration: Цільова тривалість Shorts у секундах
        """
        self.source_folder = Path(source_folder)
        self.temp_folder = Path(temp_folder)
        self.preview_generator = preview_generator
        self.shorts_resolution = shorts_resolution
        self.target_duration = target_duration

    def create_gradient_background(self, width, height, colors=None):
        """Створює градієнтний фон для заповнення порожніх областей"""
        if colors is None:
            # Красивий фіолетово-синій градієнт
            colors = [
                (147, 112, 219),  # medium slate blue
                (72, 61, 139),    # dark slate blue  
                (25, 25, 112),    # midnight blue
                (0, 0, 139)       # dark blue
            ]
        
        gradient_path = self.temp_folder / f"gradient_{width}x{height}.png"
        
        # Створюємо вертикальний градієнт
        cmd = [
            "ffmpeg", "-y",
            "-f", "lavfi",
            "-i", f"color=c=#{colors[0][0]:02x}{colors[0][1]:02x}{colors[0][2]:02x}:size={width}x{height}:duration=1",
            "-vf", f"geq=r='r(X,Y)+({colors[1][0]-colors[0][0]})*Y/{height}':g='g(X,Y)+({colors[1][1]-colors[0][1]})*Y/{height}':b='b(X,Y)+({colors[1][2]-colors[0][2]})*Y/{height}'",
            "-frames:v", "1",
            str(gradient_path)
        ]
        
        try:
            subprocess.run(cmd, check=True, capture_output=True)
            return gradient_path
        except subprocess.CalledProcessError:
            # Fallback: створюємо простий градієнт
            return self.create_simple_gradient(width, height, colors[0], colors[-1])

    def create_simple_gradient(self, width, height, color1, color2):
        """Створює простий градієнт як fallback"""
        gradient_path = self.temp_folder / f"simple_gradient_{width}x{height}.png"
        
        cmd = [
            "ffmpeg", "-y",
            "-f", "lavfi",
            "-i", f"color=c=#{color1[0]:02x}{color1[1]:02x}{color1[2]:02x}:size={width}x{height}:duration=1",
            "-frames:v", "1",
            str(gradient_path)
        ]
        
        subprocess.run(cmd, check=True, capture_output=True)
        return gradient_path

    def apply_safe_fade_filters(self, use_dur, base_filters):
        """Застосовує fade фільтри безпечно для вертикального відео"""
        fade_in_duration = min(0.3, use_dur * 0.3)
        fade_out_duration = min(0.3, use_dur * 0.3)
        
        if fade_in_duration + fade_out_duration > use_dur:
            fade_in_duration = use_dur * 0.4
            fade_out_duration = use_dur * 0.4
        
        fade_out_start = max(0, use_dur - fade_out_duration)
        
        fade_filters = []
        if fade_in_duration > 0.05:
            fade_filters.append(f"fade=t=in:st=0:d={fade_in_duration}")
        if fade_out_duration > 0.05 and fade_out_start > fade_in_duration:
            fade_filters.append(f"fade=t=out:st={fade_out_start}:d={fade_out_duration}")
        
        all_filters = [base_filters] + fade_filters
        return ",".join(all_filters)

    def create_vertical_video_with_gradient(self, video_path, output_path, duration, with_gradient=True):
        """Створює вертикальне відео з градієнтним фоном замість чорних сму
Made on
Tilda