"""
Text Overlay Service for Arabic Videos
Handles adding Arabic text overlays to videos using ffmpeg
"""
import os
import subprocess
import tempfile
from typing import List, Dict
from flask import current_app


class TextOverlayService:
    """Add Arabic text overlays to videos using ffmpeg."""

    def __init__(self):
        self.ffprobe_path = self._find_ffprobe()
        self.ffmpeg_path = self._find_ffmpeg()

    def _find_ffmpeg(self):
        """Find ffmpeg executable."""
        for path in ['/usr/bin/ffmpeg', '/usr/local/bin/ffmpeg', 'ffmpeg']:
            try:
                subprocess.run([path, '-version'], capture_output=True, check=True)
                return path
            except (subprocess.CalledProcessError, FileNotFoundError):
                continue
        return None

    def _find_ffprobe(self):
        """Find ffprobe executable."""
        for path in ['/usr/bin/ffprobe', '/usr/local/bin/ffprobe', 'ffprobe']:
            try:
                subprocess.run([path, '-version'], capture_output=True, check=True)
                return path
            except (subprocess.CalledProcessError, FileNotFoundError):
                continue
        return None

    def get_arabic_font_path(self, font_name: str = "Noto") -> str:
        """Get path to Arabic font file."""
        font_paths = {
            "Cairo": "/usr/share/fonts/truetype/cairo/Cairo-Bold.ttf",
            "Tajawal": "/usr/share/fonts/truetype/tajawal/Tajawal-Bold.ttf",
            "Noto": "/usr/share/fonts/google-noto/NotoNaskhArabic-Bold.ttf",
            "NotoSans": "/usr/share/fonts/google-noto/NotoSansArabic-Bold.ttf",
            "DejaVu": "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"  # Fallback
        }
        return font_paths.get(font_name, "/usr/share/fonts/google-noto/NotoNaskhArabic-Bold.ttf")

    def add_arabic_text_overlay(self,
                               video_path: str,
                               text_overlays: List[Dict],
                               output_path: str,
                               font_name: str = "Cairo",
                               font_size: int = 48,
                               font_color: str = "white",
                               background_color: str = "black@0.5") -> bool:
        """
        Add Arabic text overlays to video using ffmpeg.

        Args:
            video_path: Path to input video
            text_overlays: List of text overlay configurations
            output_path: Path for output video
            font_name: Font name (Cairo, Tajawal, etc.)
            font_size: Font size in pixels
            font_color: Text color (ffmpeg color format)
            background_color: Background color with opacity

        Returns:
            bool: True if successful, False otherwise
        """
        if not self.ffmpeg_path:
            current_app.logger.error("ffmpeg not found")
            return False

        try:
            # Build ffmpeg filter complex for multiple text overlays
            filter_complex = []
            inputs = [f"-i,{video_path}"]

            for i, overlay in enumerate(text_overlays):
                text = overlay.get('text', '')
                start_time = overlay.get('start_time', 0)
                end_time = overlay.get('end_time', 5)
                position = overlay.get('position', 'center')

                if not text:
                    continue

                # Escape text for ffmpeg - write to temp file
                temp_text_file = f"/tmp/text_overlay_{i}.txt"
                with open(temp_text_file, 'w', encoding='utf-8') as f:
                    f.write(text)

                # Get font path
                font_path = self.get_arabic_font_path(font_name)

                # Calculate position coordinates
                x, y = self._get_position_coords(position)

                # Build drawtext filter
                filter_text = (
                    f"drawtext=textfile='{temp_text_file}':"
                    f"fontsize={font_size}:"
                    f"fontcolor={font_color}:"
                    f"x={x}:y={y}:"
                    f"enable='between(t,{start_time},{end_time})':"
                    f"fontfile={font_path}:"
                    f"reload=1"
                )

                # Add background box if requested
                if background_color:
                    filter_text += f":box=1:boxcolor={background_color}:boxborderw=10"

                filter_complex.append(filter_text)

            if not filter_complex:
                current_app.logger.warning("No valid text overlays provided")
                return False

            # Build ffmpeg command
            cmd = [
                self.ffmpeg_path,
                '-i', video_path,
                '-vf', ','.join(filter_complex),
                '-c:a', 'copy',  # Copy audio without re-encoding
                '-y',  # Overwrite output file
                output_path
            ]

            # Execute ffmpeg
            result = subprocess.run(cmd, capture_output=True, text=True)

            if result.returncode != 0:
                current_app.logger.error(f"ffmpeg error: {result.stderr}")
                return False

            current_app.logger.info(f"Text overlay completed: {output_path}")
            return True

        except Exception as e:
            current_app.logger.error(f"Text overlay error: {e}")
            return False

    def _get_position_coords(self, position: str) -> tuple:
        """Calculate x, y coordinates for text position."""
        positions = {
            'center': '(w-text_w)/2:(h-text_h)/2',
            'top': '(w-text_w)/2:50',
            'bottom': '(w-text_w)/2:h-text_h-50',
            'top-right': 'w-text_w-50:50',
            'top-left': '50:50',
            'bottom-right': 'w-text_w-50:h-text_h-50',
            'bottom-left': '50:h-text_h-50'
        }
        return positions.get(position, positions['center'])

    def get_video_duration(self, video_path: str) -> float:
        """Get video duration in seconds."""
        if not self.ffprobe_path:
            return 0.0

        try:
            cmd = [
                self.ffprobe_path,
                '-v', 'error',
                '-show_entries', 'format=duration',
                '-of', 'json',
                video_path
            ]
            result = subprocess.run(cmd, capture_output=True, text=True, check=True)
            import json
            data = json.loads(result.stdout)
            return float(data['format']['duration'])
        except Exception as e:
            current_app.logger.error(f"Duration check error: {e}")
            return 0.0

    def test_arabic_rendering(self) -> Dict[str, any]:
        """Test Arabic text rendering with sample video."""
        try:
            # Create test video with black background
            test_video_path = "/tmp/test_video.mp4"
            subprocess.run([
                self.ffmpeg_path, '-f', 'lavfi',
                '-i', 'color=c=black:s=1280x720:d=3',
                '-c:v', 'libx264', '-t', '3', '-y',
                test_video_path
            ], check=True, capture_output=True)

            # Test Arabic text overlay
            test_text = "مرحباً بكم"  # "Welcome"
            text_overlays = [{
                'text': test_text,
                'position': 'center',
                'start_time': 0,
                'end_time': 3
            }]

            output_path = "/tmp/test_video_with_text.mp4"
            success = self.add_arabic_text_overlay(
                test_video_path, text_overlays, output_path
            )

            if success:
                return {
                    "status": "success",
                    "message": "Arabic text rendering works correctly",
                    "test_video": output_path,
                    "duration": self.get_video_duration(output_path)
                }
            else:
                return {"status": "error", "message": "Arabic text rendering failed"}

        except Exception as e:
            return {"status": "error", "message": str(e)}