import sys
sys.stdout.reconfigure(encoding='utf-8')

import os
from pathlib import Path
from moviepy.editor import VideoFileClip, CompositeVideoClip, ImageClip
import pysrt
import logging
import warnings
import numpy as np
import gi
gi.require_version("Pango", "1.0")
gi.require_version("PangoCairo", "1.0")
from gi.repository import Pango, PangoCairo
import arabic_reshaper
import cairo
from colorama import init, Fore, Style
import concurrent.futures

# تهيئة colorama لطباعة ملونة في الطرفية
init(autoreset=True)

# إعداد Logger
logger = logging.getLogger()
logger.setLevel(logging.INFO)
handler = logging.StreamHandler(sys.stdout)
formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
handler.setFormatter(formatter)
logger.handlers = [handler]

# إعداد المسارات
BASE_DIR = Path("/workspaces/VedioGen5")
SRT_FOLDER = BASE_DIR / "OUTPUT" / "Pro Output Sound" / "SRT_Folder"
VIDEO_FOLDER = BASE_DIR / "OUTPUT" / "Final_Videos"
OUTPUT_FOLDER = BASE_DIR / "OUTPUT" / "Processed_Videos"
OUTPUT_FOLDER.mkdir(parents=True, exist_ok=True)

DEFAULT_FONT = "Amiri Bold"  # الخط المستخدم

warnings.filterwarnings("ignore", category=UserWarning)


def process_arabic_text(text):
    """
    إعادة تشكيل النص العربي.
    """
    try:
        reshaper = arabic_reshaper.ArabicReshaper({'delete_harakat': False})
        return reshaper.reshape(text)
    except Exception as e:
        logger.error(f"خطأ في معالجة النص العربي: {str(e)}")
        return text


def capitalize_text(text):
    """
    تحويل أول حرف من كل كلمة إلى حرف كبير.
    """
    try:
        return ' '.join(word.capitalize() for word in text.split())
    except Exception as e:
        logger.error(f"خطأ في تحويل النص إلى Capitalized: {str(e)}")
        return text


def split_text_into_groups(text, group_size=3):
    """
    تقسيم النص إلى مجموعات للحفاظ على التنسيق الصحيح.
    """
    words = text.strip().split()
    return [' '.join(words[i:i+group_size]) for i in range(0, len(words), group_size)]


def create_subtitle_clips(subtitles, video_size, font_size=50, group_size=3):
    """
    إنشاء مقاطع الترجمة بحيث يكون النص في أسفل الفيديو وفي منتصف الشاشة تمامًا.
    
    - يتم ضبط التخطيط ليكون بعرض الفيديو بالكامل مع محاذاة CENTER.
    - يتم تحديد الموضع بحيث يكون النص على بعد 300 بيكسل من أسفل الفيديو.
    - يُرسم إطار باللون الأسود (سميك قليلاً) ثم يتم رسم النص الأساسي باللون الأبيض.
    """
    clips = []
    video_width, video_height = video_size

    for subtitle in subtitles:
        try:
            start_time = subtitle.start.ordinal / 1000
            end_time = subtitle.end.ordinal / 1000
            duration = end_time - start_time

            text_groups = split_text_into_groups(subtitle.text.replace("\n", " "), group_size)
            if not text_groups:
                continue

            group_duration = duration / len(text_groups)

            for idx, group_text in enumerate(text_groups):
                group_start = start_time + idx * group_duration
                group_end = group_start + group_duration

                # تحويل النص بحيث تبدأ كل كلمة بحرف كبير ثم إعادة تشكيله (في حالة وجود نص عربي)
                processed_text = capitalize_text(group_text)
                processed_text = process_arabic_text(processed_text)

                # إنشاء سطح Cairo للرسم
                surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, video_width, video_height)
                context = cairo.Context(surface)

                # إنشاء وتكوين تخطيط Pango
                layout = PangoCairo.create_layout(context)
                layout.set_text(processed_text, -1)
                font_desc = Pango.FontDescription(f"{DEFAULT_FONT} {font_size}")
                layout.set_font_description(font_desc)
                layout.set_alignment(Pango.Alignment.CENTER)
                layout.set_width(Pango.units_from_double(video_width))
                layout.set_wrap(Pango.WrapMode.WORD_CHAR)

                # الحصول على أبعاد النص
                text_width, text_height = layout.get_pixel_size()

                # تحديد الموضع بحيث يكون النص على بعد 300 بيكسل من أسفل الفيديو
                x_pos = 0
                y_pos = video_height - text_height - 300

                # رسم إطار أسود حول النص باستخدام إزاحات من -4 إلى +4 (لتكون السماكة أكبر)
                outline_offsets = [(dx, dy) for dx in range(-4, 5) for dy in range(-4, 5) if not (dx == 0 and dy == 0)]
                for dx, dy in outline_offsets:
                    context.move_to(x_pos + dx, y_pos + dy)
                    context.set_source_rgb(0, 0, 0)  # اللون الأسود للإطار
                    PangoCairo.update_layout(context, layout)
                    PangoCairo.show_layout(context, layout)

                # رسم النص الأساسي باللون الأبيض فوق الإطار
                context.move_to(x_pos, y_pos)
                context.set_source_rgb(1.0, 1.0, 1.0)  # اللون الأبيض للنص
                PangoCairo.update_layout(context, layout)
                PangoCairo.show_layout(context, layout)

                # تحويل الصورة إلى مصفوفة Numpy
                img_data = np.frombuffer(surface.get_data(), np.uint8)
                img_data = img_data.reshape((video_height, video_width, 4))
                img_data = np.roll(img_data, 1, axis=2)

                # إنشاء مقطع الترجمة باستخدام MoviePy
                txt_clip = ImageClip(img_data, transparent=True)
                txt_clip = txt_clip.set_duration(group_duration).set_start(group_start)
                clips.append(txt_clip)

                logger.info(f"✅ Created subtitle clip: '{group_text}' from {group_start:.2f} to {group_end:.2f} seconds")
        except Exception as e:
            logger.error(f"❌ Error creating subtitle clip: {str(e)}")

    return clips


def process_single_video(video_file_path, srt_file_path):
    """
    معالجة فيديو واحد مع ملف SRT الخاص به وإضافة الترجمة.
    بعد نجاح المعالجة يتم حذف الفيديو الأصلي لتفريغ المساحة.
    """
    video_file = Path(video_file_path)
    srt_file = Path(srt_file_path)
    logger.info(f"🎬 Processing video: {video_file.name} with SRT: {srt_file.name}")
    try:
        with VideoFileClip(str(video_file)) as video_clip:
            subtitles = pysrt.open(str(srt_file), encoding="utf-8")
            subtitle_clips = create_subtitle_clips(
                subtitles,
                video_size=video_clip.size,
                font_size=50,  # حجم الخط 50
                group_size=3
            )

            if not subtitle_clips:
                raise ValueError("No subtitle clips were created.")

            final_clip = CompositeVideoClip([video_clip] + subtitle_clips)
            output_path = OUTPUT_FOLDER / f"{video_file.stem}_processed.mp4"

            final_clip.write_videofile(
                str(output_path),
                codec="libx264",
                audio_codec="aac",
                threads=4,
                preset='slow',
                bitrate="5000k",
                verbose=True,
                temp_audiofile=str(OUTPUT_FOLDER / "temp-audio.m4a"),
                remove_temp=True
            )

            logger.info(f"✅ Processed and saved video to: {output_path}")

        # حذف ملف الفيديو الأصلي بعد المعالجة الناجحة
        try:
            video_file.unlink()
            logger.info(f"🗑️ Deleted input video: {video_file.name}")
        except Exception as e:
            logger.error(f"❌ Error deleting input video {video_file.name}: {e}")

        return f"Processed {video_file.name}"
    except Exception as e:
        logger.error(f"❌ Error processing video '{video_file.name}': {str(e)}")
        return f"Error processing {video_file.name}: {str(e)}"


def process_videos_concurrently():
    """
    البحث عن ملفات الفيديو وملفات SRT المطابقة ومعالجتها بشكل متوازي.
    بالإضافة إلى حذف ملفات الفيديو التي ليس لها ترجمة لتفادي امتلاء مساحة البيئة.
    """
    srt_files = list(SRT_FOLDER.glob("*.srt"))
    video_files = list(VIDEO_FOLDER.glob("*.mp4"))

    logger.info(f"📂 Found {len(srt_files)} SRT files and {len(video_files)} videos.")

    # حذف الفيديوهات المعالجة سابقًا
    for file in OUTPUT_FOLDER.glob("*_processed.mp4"):
        try:
            file.unlink()
            logger.info(f"🗑️ Deleted processed file: {file.name}")
        except Exception as e:
            logger.error(f"❌ Error deleting file {file.name}: {e}")

    tasks = []
    for video_file in video_files:
        video_name = video_file.stem
        video_prefix = "_".join(video_name.split("_")[:2])
        matching_srt = next((srt for srt in srt_files if video_prefix in srt.stem), None)
        if matching_srt:
            tasks.append((str(video_file), str(matching_srt)))
        else:
            logger.warning(f"⚠️ No matching SRT file found for video: {video_name}")
            try:
                video_file.unlink()
                logger.info(f"🗑️ Deleted unprocessed video: {video_file.name}")
            except Exception as e:
                logger.error(f"❌ Error deleting unprocessed video {video_file.name}: {e}")

    if not tasks:
        logger.info("❗ No tasks to process. Exiting.")
        return

    workers = os.cpu_count() or 4
    logger.info(f"🚀 Starting parallel processing with {workers} workers.")

    results = []
    with concurrent.futures.ProcessPoolExecutor(max_workers=workers) as executor:
        futures = {
            executor.submit(process_single_video, video_path, srt_path): video_path
            for video_path, srt_path in tasks
        }
        for future in concurrent.futures.as_completed(futures):
            try:
                result = future.result()
                results.append(result)
                logger.info(result)
            except Exception as e:
                logger.error(f"❌ Error in parallel processing: {e}")

    logger.info("🎉 Video processing completed.")
    return results


if __name__ == "__main__":
    process_videos_concurrently()
 اضف الى هذا الكود اطار للخط باللون الاسود وحدد الرقم بعلامة مميزة للتعديل فيما بعض وقوم بالغاء وظيفة مسح ملفات الانبوت من الكود