#!/usr/bin/env python3
"""
Video Analysis Example for FMUS-VID.

This example demonstrates how to use the analysis tools in FMUS-VID
to detect scene changes and analyze audio in videos.
"""

import os
import sys
import argparse
from pathlib import Path
import logging
import numpy as np
import matplotlib.pyplot as plt
from typing import List, Tuple

# Add parent directory to path to allow running from examples directory
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
from fmusvid.operations.analysis import SceneDetector, AudioAnalyzer
from fmusvid import Video

# Set up logging
logging.basicConfig(level=logging.INFO,
                   format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

def analyze_scenes(video_path: str, output_dir: str = None) -> List[Tuple[float, float]]:
    """
    Analyze a video to detect scene changes.

    Args:
        video_path: Path to the video file
        output_dir: Directory to save visualization (optional)

    Returns:
        List of scene change timestamps
    """
    logger.info(f"Analyzing scenes in {video_path}")

    # Create scene detector
    detector = SceneDetector(threshold=35.0, min_scene_length=15)

    # Detect scenes
    scene_changes = detector.detect_from_video(video_path)

    # Log results
    logger.info(f"Detected {len(scene_changes)} scene changes")
    for i, scene in enumerate(scene_changes):
        logger.info(f"Scene {i+1}: at {scene.timestamp:.2f}s (score: {scene.score:.2f})")

    # Create visualization if output directory is specified
    if output_dir:
        output_dir = Path(output_dir)
        output_dir.mkdir(exist_ok=True, parents=True)

        # Extract frames at scene changes
        video = Video(video_path)

        for i, scene in enumerate(scene_changes):
            # Extract frame before and after scene change
            before_frame = max(0, scene.frame_number - 5)
            after_frame = scene.frame_number + 5

            # Save frames
            video.extract_frames(
                start_time=video.frame_to_seconds(before_frame),
                end_time=video.frame_to_seconds(after_frame),
                fps=1,
                output_pattern=str(output_dir / f"scene_{i+1:03d}_frame_%03d.jpg")
            )

        # Create visualization of scene changes over time
        plt.figure(figsize=(12, 4))
        plt.plot([s.timestamp for s in scene_changes],
                [s.score for s in scene_changes], 'ro-')
        plt.xlabel("Time (seconds)")
        plt.ylabel("Scene Change Score")
        plt.title(f"Scene Changes in {Path(video_path).name}")
        plt.grid(True)
        plt.savefig(str(output_dir / "scene_changes.png"), dpi=150)

    return [(s.timestamp, s.score) for s in scene_changes]

def analyze_audio(video_path: str, output_dir: str = None) -> List[Tuple[float, float]]:
    """
    Analyze audio in a video to detect silent segments.

    Args:
        video_path: Path to the video file
        output_dir: Directory to save visualization (optional)

    Returns:
        List of silent segments as (start_time, end_time) tuples
    """
    logger.info(f"Analyzing audio in {video_path}")

    try:
        # Create audio analyzer
        analyzer = AudioAnalyzer()

        # Detect silent segments
        silent_segments = analyzer.detect_silence(
            video_path,
            threshold=0.05,  # Adjust threshold based on your video
            min_duration=0.5  # Minimum silence duration in seconds
        )

        # Log results
        logger.info(f"Detected {len(silent_segments)} silent segments")
        for i, (start, end) in enumerate(silent_segments):
            logger.info(f"Silence {i+1}: {start:.2f}s - {end:.2f}s (duration: {end-start:.2f}s)")
    except Exception as e:
        logger.warning(f"Could not analyze audio: {e}")
        silent_segments = []

    # Create visualization if output directory is specified
    if output_dir:
        output_dir = Path(output_dir)
        output_dir.mkdir(exist_ok=True, parents=True)

        # Create visualization of silent segments
        plt.figure(figsize=(12, 4))

        # Plot timeline
        video = Video(video_path)
        duration = video.duration

        for i, (start, end) in enumerate(silent_segments):
            plt.axvspan(start, end, alpha=0.3, color='red', label='Silence' if i == 0 else "")

        plt.xlim(0, duration)
        plt.xlabel("Time (seconds)")
        plt.yticks([])
        plt.title(f"Silent Segments in {Path(video_path).name}")
        plt.grid(True, axis='x')
        if silent_segments:
            plt.legend()
        plt.savefig(str(output_dir / "silent_segments.png"), dpi=150)

    return silent_segments

def create_analysis_report(video_path: str, output_dir: str) -> None:
    """
    Create a comprehensive analysis report for a video.

    Args:
        video_path: Path to the video file
        output_dir: Directory to save report
    """
    output_dir = Path(output_dir)
    output_dir.mkdir(exist_ok=True, parents=True)

    # Load video
    video = Video(video_path)

    # Get basic video info
    info = {
        "filename": Path(video_path).name,
        "duration": video.duration,
        "resolution": f"{video.width}x{video.height}",
        "fps": video.fps,
        "bitrate": video.bitrate if hasattr(video, "bitrate") else "Unknown"
    }

    # Run analysis
    scene_changes = analyze_scenes(video_path, output_dir / "scenes")
    silent_segments = analyze_audio(video_path, output_dir / "audio")

    # Create HTML report
    report_path = output_dir / "analysis_report.html"

    with open(report_path, "w") as f:
        f.write(f"""<!DOCTYPE html>
<html>
<head>
    <title>Video Analysis Report: {info['filename']}</title>
    <style>
        body {{ font-family: Arial, sans-serif; line-height: 1.6; margin: 0; padding: 20px; }}
        h1, h2 {{ color: #333; }}
        .container {{ max-width: 1200px; margin: 0 auto; }}
        .info-table {{ border-collapse: collapse; width: 100%; margin-bottom: 20px; }}
        .info-table th, .info-table td {{ border: 1px solid #ddd; padding: 8px; text-align: left; }}
        .info-table th {{ background-color: #f2f2f2; }}
        .scene-list, .silence-list {{ list-style-type: none; padding: 0; }}
        .scene-list li, .silence-list li {{ margin-bottom: 5px; padding: 5px; background-color: #f9f9f9; }}
        .visualization {{ margin: 20px 0; }}
    </style>
</head>
<body>
    <div class="container">
        <h1>Video Analysis Report</h1>

        <h2>Video Information</h2>
        <table class="info-table">
            <tr><th>Filename</th><td>{info['filename']}</td></tr>
            <tr><th>Duration</th><td>{info['duration']:.2f} seconds</td></tr>
            <tr><th>Resolution</th><td>{info['resolution']}</td></tr>
            <tr><th>Frame Rate</th><td>{info['fps']} fps</td></tr>
            <tr><th>Bitrate</th><td>{info['bitrate']}</td></tr>
        </table>

        <h2>Scene Analysis</h2>
        <p>Detected {len(scene_changes)} scene changes:</p>
        <ul class="scene-list">
""")

        for i, (timestamp, score) in enumerate(scene_changes):
            f.write(f'            <li>Scene {i+1}: at {timestamp:.2f}s (score: {score:.2f})</li>\n')

        f.write(f"""
        </ul>

        <div class="visualization">
            <img src="scenes/scene_changes.png" alt="Scene Changes" style="max-width: 100%;">
        </div>

        <h2>Audio Analysis</h2>
        <p>Detected {len(silent_segments)} silent segments:</p>
        <ul class="silence-list">
""")

        for i, (start, end) in enumerate(silent_segments):
            f.write(f'            <li>Silence {i+1}: {start:.2f}s - {end:.2f}s (duration: {end-start:.2f}s)</li>\n')

        f.write(f"""
        </ul>

        <div class="visualization">
            <img src="audio/silent_segments.png" alt="Silent Segments" style="max-width: 100%;">
        </div>
    </div>
</body>
</html>
""")

    logger.info(f"Analysis report saved to {report_path}")

def main():
    """Main function to run the example."""
    # Hardcoded sample videos to try
    sample_video_paths = [
        os.path.join("test_media", "test_video.mp4"),
        os.path.join("test_media", "sample.mp4"),
        os.path.join("test_media", "sample2.mp4")
    ]

    # Find the first existing sample video
    video_path = None
    for path in sample_video_paths:
        if os.path.exists(path):
            video_path = path
            break

    # If no sample videos found, create a test video with audio
    if video_path is None:
        logger.warning("No sample videos found. Creating a test video with audio.")

        # Create test_media directory if it doesn't exist
        os.makedirs("test_media", exist_ok=True)

        # Create a test video with audio using ffmpeg
        test_video_path = os.path.join("test_media", "generated_test_audio.mp4")

        # Generate a test video with audio using ffmpeg
        import subprocess
        result = subprocess.run([
            "ffmpeg", "-f", "lavfi", "-i", "color=c=green:s=640x360:d=5",
            "-f", "lavfi", "-i", "sine=frequency=1000:duration=5",
            "-c:v", "libx264", "-c:a", "aac", "-shortest",
            "-y", test_video_path
        ], capture_output=True, text=True)

        if result.returncode == 0:
            logger.info(f"Created test video with audio: {test_video_path}")
            video_path = test_video_path
        else:
            logger.error(f"Failed to create test video: {result.stderr}")
            return 1

    # Set output directory
    output_dir = "analysis_output"

    try:
        # Create analysis report
        logger.info(f"Analyzing video: {video_path}")
        create_analysis_report(video_path, output_dir)
        logger.info(f"Analysis completed successfully. Results saved to {output_dir}")
        logger.info(f"Open {output_dir}/analysis_report.html to view the report")
        return 0
    except Exception as e:
        logger.exception(f"Error during analysis: {e}")
        return 1

if __name__ == "__main__":
    sys.exit(main())
