"""Video transcription using Whisper."""

import subprocess
import os
import sys
import platform
from pathlib import Path
from typing import Optional

# For GPU detection
try:
    import torch
    HAS_TORCH = True
except ImportError:
    HAS_TORCH = False

# Check if we're on Windows with a non-Unicode terminal
if platform.system() == "Windows":
    IS_UNICODE_TERMINAL = False
    try:
        IS_UNICODE_TERMINAL = sys.stdout.encoding.lower() == 'utf-8'
    except:
        pass
else:
    # Assume Unix-based systems support Unicode
    IS_UNICODE_TERMINAL = True


def transcribe_video(video_path: str, output_path: Optional[str] = None, model: str = "small") -> str:
    """
    Transcribe a video file to SRT subtitles using Whisper.
    
    Args:
        video_path: Path to the video file
        output_path: Optional path to save the SRT file. If not provided,
                    saves to the same directory as the video with .srt extension
        model: Whisper model to use. Options:
               - Language agnostic: tiny, base, small, medium, large
               - English-specific: tiny.en, base.en, small.en, medium.en
               Smaller models are faster but less accurate. 
               .en models are faster but only work well with English content.
    
    Returns:
        Path to the created SRT file
    """
    video_path = Path(video_path)
    
    if not video_path.exists():
        raise FileNotFoundError(f"Video file not found: {video_path}")
    
    if output_path is None:
        output_path = video_path.with_suffix(".srt")
    
    try:
        print(f"Starting Whisper transcription of {video_path}...")
        
        # Determine if GPU is available and set device
        device = "cpu"
        if HAS_TORCH:
            if torch.cuda.is_available():
                device = "cuda"
            elif platform.system() == "Darwin" and hasattr(torch.backends, "mps") and torch.backends.mps.is_available():
                # For Apple Silicon GPU
                device = "mps"
        
        if IS_UNICODE_TERMINAL:
            print(f"🖥️ Using device: {device}")
        else:
            print(f"Using device: {device}")
        
        # Run whisper with optimized settings for faster performance
        command = [
            "whisper", 
            str(video_path),
            "--model", model,       # Use specified model (default: small.en)
            "--output_format", "srt",
            "--output_dir", str(video_path.parent),
            "--device", device,
            "--verbose", "True",
            "--fp16", "True",       # Enable fp16 for faster GPU processing
            "--beam_size", "3",     # Smaller beam size for faster processing (default is 5)
            "--threads", str(max(1, os.cpu_count() - 1)),  # Use multiple CPU cores but leave one free
            "--condition_on_previous_text", "False",  # Faster but might reduce consistency
        ]
        
        print(f"Running whisper command: {' '.join(command)}")
        print("----------- Actual whisper output below -----------")
        
        # Run whisper without capturing output so user can see real progress
        result = subprocess.run(
            command,
            check=True,
            timeout=1800  # 30 minute timeout
        )
        
        print("----------- Whisper output end -----------")
        if IS_UNICODE_TERMINAL:
            print("✅ Transcription complete")
        else:
            print(">> Transcription complete")
        
        # Whisper creates the output filename by appending .srt to the input basename
        expected_output = video_path.with_suffix("").with_suffix(".srt")
        
        if not expected_output.exists():
            raise RuntimeError(f"Whisper did not create expected output file: {expected_output}")
        
        # If custom output path was specified, move the file
        if str(expected_output) != str(output_path):
            os.rename(expected_output, output_path)
        
        return str(output_path)
    
    except subprocess.CalledProcessError as e:
        print(f"Whisper transcription failed")
        if hasattr(e, 'stderr') and e.stderr:
            print(f"Error details: {e.stderr}")
        raise RuntimeError(f"Whisper transcription failed")
    except subprocess.TimeoutExpired as e:
        print(f"Whisper process timed out after {e.timeout} seconds")
        if hasattr(e, 'stderr') and e.stderr:
            print(f"Error details: {e.stderr}")
        raise RuntimeError(f"Whisper transcription timed out after {e.timeout} seconds")
    except Exception as e:
        print(f"Unexpected error during transcription: {type(e).__name__}: {e}")
        raise