"""
Example generator for FMUS-VID documentation.

This module provides tools for generating and validating code examples.
"""

import ast
import inspect
from pathlib import Path
from typing import Dict, List, Optional, Any
from dataclasses import dataclass
import logging
import textwrap
import fmusvid

logger = logging.getLogger(__name__)

@dataclass
class Example:
    """Code example with description and validation."""
    title: str
    description: str
    code: str
    output: Optional[str] = None
    requires: List[str] = None

    def __post_init__(self):
        """Initialize optional fields."""
        self.requires = self.requires or []

class ExampleGenerator:
    """
    Generates runnable code examples for documentation.
    """

    def __init__(self):
        """Initialize example generator."""
        self.examples: Dict[str, List[Example]] = {}
        self._setup_basic_examples()
        self._setup_advanced_examples()

    def _setup_basic_examples(self):
        """Set up basic usage examples."""
        # Contoh dasar loading dan saving
        self.examples["basic"] = [
            Example(
                title="Loading and Saving",
                description="Basic example of loading and saving a video file.",
                code="""
                import fmusvid

                # Load video file
                video = fmusvid.load("input.mp4")

                # Save to new format
                video.save("output.webm")
                """,
                requires=["input.mp4"]
            ),

            Example(
                title="Basic Transformations",
                description="Common video transformations.",
                code="""
                import fmusvid

                video = fmusvid.load("input.mp4")

                # Apply transformations
                processed = (video
                    .trim(start=5, end=15)      # Trim to 10 seconds
                    .resize(width=1280)         # Resize width, keep aspect
                    .rotate(90)                 # Rotate 90 degrees
                    .save("output.mp4"))
                """,
                requires=["input.mp4"]
            ),

            Example(
                title="Audio Operations",
                description="Basic audio manipulation.",
                code="""
                import fmusvid

                video = fmusvid.load("input.mp4")

                # Adjust audio
                video.volume(0.5)               # Reduce volume to 50%
                video.add_audio("music.mp3")    # Add background music
                video.save("output.mp4")
                """,
                requires=["input.mp4", "music.mp3"]
            )
        ]

    def _setup_advanced_examples(self):
        """Set up advanced usage examples."""
        self.examples["advanced"] = [
            Example(
                title="Video Composition",
                description="Combining multiple videos.",
                code="""
                import fmusvid

                # Load videos
                video1 = fmusvid.load("clip1.mp4")
                video2 = fmusvid.load("clip2.mp4")
                video3 = fmusvid.load("clip3.mp4")

                # Create picture-in-picture
                main = video1.overlay(
                    video2,
                    position=(50, 50),
                    start=5.0
                )

                # Create grid layout
                grid = fmusvid.grid(
                    [video1, video2, video3],
                    rows=2,
                    cols=2
                )
                grid.save("grid_output.mp4")
                """,
                requires=["clip1.mp4", "clip2.mp4", "clip3.mp4"]
            ),

            Example(
                title="Effects and Filters",
                description="Applying visual effects.",
                code="""
                import fmusvid

                video = fmusvid.load("input.mp4")

                # Apply effects
                processed = (video
                    .grayscale()                # Convert to grayscale
                    .blur(radius=2.0)           # Apply blur
                    .brightness(1.2)            # Increase brightness
                    .contrast(1.1)              # Adjust contrast
                    .save("output.mp4"))
                """,
                requires=["input.mp4"]
            ),

            Example(
                title="AI Features",
                description="Using AI-enhanced features.",
                code="""
                import fmusvid
                from fmusvid.ai import ObjectDetector, ObjectTracker

                video = fmusvid.load("input.mp4")

                # Initialize AI components
                detector = ObjectDetector()
                tracker = ObjectTracker()

                # Process video
                for frame in video.frames():
                    # Detect objects
                    detections = detector.detect(frame)

                    # Track objects
                    tracks = tracker.update(detections)

                    # Annotate frame
                    for track in tracks:
                        frame = track.annotate_frame(frame)

                video.save("tracked_output.mp4")
                """,
                requires=["input.mp4"]
            )
        ]

        # Menambahkan contoh async
        self.examples["async"] = [
            Example(
                title="Asynchronous Processing",
                description="Using async features for better performance.",
                code="""
                import asyncio
                import fmusvid

                async def process_video(input_path: str, output_path: str):
                    video = await fmusvid.load_async(input_path)

                    # Process asynchronously
                    await video.resize_async(width=1920)
                    await video.apply_effect_async("blur", radius=2.0)

                    # Save with progress callback
                    await video.save_async(
                        output_path,
                        progress_callback=lambda p: print(f"Progress: {p:.1%}")
                    )

                asyncio.run(process_video("input.mp4", "output.mp4"))
                """,
                requires=["input.mp4"]
            )
        ]

    def generate_markdown(self) -> str:
        """
        Generate Markdown documentation with examples.

        Returns:
            Markdown formatted examples
        """
        sections = ["# FMUS-VID Examples\n"]

        # Basic Examples
        sections.append("## Basic Examples\n")
        for example in self.examples["basic"]:
            sections.append(self._format_example(example))

        # Advanced Examples
        sections.append("\n## Advanced Examples\n")
        for example in self.examples["advanced"]:
            sections.append(self._format_example(example))

        # Async Examples
        sections.append("\n## Asynchronous Examples\n")
        for example in self.examples["async"]:
            sections.append(self._format_example(example))

        return "\n\n".join(sections)

    def _format_example(self, example: Example) -> str:
        """Format single example as Markdown."""
        sections = [
            f"### {example.title}\n",
            example.description + "\n",
            "```python",
            textwrap.dedent(example.code).strip(),
            "```"
        ]

        if example.requires:
            sections.extend([
                "\nRequires:",
                "- " + "\n- ".join(example.requires)
            ])

        if example.output:
            sections.extend([
                "\nOutput:",
                "```",
                example.output,
                "```"
            ])

        return "\n".join(sections)

    def validate_examples(self) -> List[str]:
        """
        Validate all examples by parsing them as Python code.

        Returns:
            List of validation errors
        """
        errors = []

        for category, examples in self.examples.items():
            for example in examples:
                try:
                    # Memastikan kode dapat di-parse
                    ast.parse(textwrap.dedent(example.code))
                except SyntaxError as e:
                    errors.append(
                        f"Syntax error in {category} example '{example.title}': {e}"
                    )

        return errors

class TutorialGenerator:
    """
    Generates step-by-step tutorials with examples.
    """

    def __init__(self):
        """Initialize tutorial generator."""
        self.tutorials = {
            "quickstart": self._generate_quickstart(),
            "video_editing": self._generate_video_editing(),
            "ai_features": self._generate_ai_features()
        }

    def _generate_quickstart(self) -> List[Example]:
        """Generate quickstart tutorial."""
        return [
            Example(
                title="Installation",
                description="Installing FMUS-VID using pip.",
                code="""
                pip install fmusvid

                # Optional dependencies for AI features
                pip install fmusvid[ai]
                """
            ),

            Example(
                title="First Steps",
                description="Your first FMUS-VID script.",
                code="""
                import fmusvid

                # Load a video
                video = fmusvid.load("input.mp4")

                # Get video information
                print(f"Duration: {video.duration} seconds")
                print(f"Resolution: {video.width}x{video.height}")
                print(f"FPS: {video.fps}")

                # Basic processing
                video.trim(0, 10).save("output.mp4")
                """
            )
        ]

    def _generate_video_editing(self) -> List[Example]:
        """Generate video editing tutorial."""
        return [
            Example(
                title="Basic Editing",
                description="Common video editing operations.",
                code="""
                import fmusvid

                video = fmusvid.load("input.mp4")

                # Trim and resize
                edited = (video
                    .trim(start=5, end=15)
                    .resize(width=1920, height=1080)
                    .rotate(90)
                )

                # Add effects
                final = (edited
                    .brightness(1.2)
                    .contrast(1.1)
                    .blur(2.0)
                )

                final.save("output.mp4")
                """
            ),

            Example(
                title="Advanced Composition",
                description="Creating complex video compositions.",
                code="""
                import fmusvid

                # Load videos
                main = fmusvid.load("main.mp4")
                overlay = fmusvid.load("overlay.mp4")

                # Resize overlay
                overlay.resize(width=480)  # Picture-in-picture size

                # Create composition
                result = (main
                    .overlay(overlay, position=(50, 50))
                    .add_audio("background.mp3", volume=0.3)
                )

                result.save("composition.mp4")
                """
            )
        ]

    def _generate_ai_features(self) -> List[Example]:
        """Generate AI features tutorial."""
        return [
            Example(
                title="Object Detection",
                description="Detecting objects in video.",
                code="""
                import fmusvid
                from fmusvid.ai import ObjectDetector

                video = fmusvid.load("input.mp4")
                detector = ObjectDetector()

                # Process each frame
                for frame in video.frames():
                    detections = detector.detect(frame)
                    frame = detector.annotate_frame(frame, detections)

                video.save("detected.mp4")
                """
            ),

            Example(
                title="Smart Cropping",
                description="Content-aware video cropping.",
                code="""
                import fmusvid
                from fmusvid.ai import SmartCropper

                video = fmusvid.load("input.mp4")
                cropper = SmartCropper()

                # Find optimal crop region
                region = cropper.find_best_region(video)

                # Apply crop
                result = video.crop(
                    x=region.x,
                    y=region.y,
                    width=region.width,
                    height=region.height
                )

                result.save("cropped.mp4")
                """
            )
        ]

    def generate_markdown(self) -> str:
        """
        Generate Markdown documentation with tutorials.

        Returns:
            Markdown formatted tutorials
        """
        sections = ["# FMUS-VID Tutorials\n"]

        for name, examples in self.tutorials.items():
            sections.append(f"## {name.replace('_', ' ').title()}\n")
            for example in examples:
                sections.append(self._format_tutorial(example))

        return "\n\n".join(sections)

    def _format_tutorial(self, example: Example) -> str:
        """Format tutorial step as Markdown."""
        sections = [
            f"### {example.title}\n",
            example.description + "\n",
            "```python",
            textwrap.dedent(example.code).strip(),
            "```"
        ]

        if example.requires:
            sections.extend([
                "\nRequired files:",
                "- " + "\n- ".join(example.requires)
            ])

        return "\n".join(sections)

def generate_examples(output_dir: Path) -> None:
    """
    Generate all documentation examples.

    Args:
        output_dir: Output directory for example files
    """
    output_dir = Path(output_dir)
    output_dir.mkdir(parents=True, exist_ok=True)

    # Membuat examples
    example_gen = ExampleGenerator()
    tutorial_gen = TutorialGenerator()

    # Validasi examples
    errors = example_gen.validate_examples()
    if errors:
        for error in errors:
            logger.error(error)
        raise ValueError("Example validation failed")

    # Menyimpan ke file
    (output_dir / "examples.md").write_text(
        example_gen.generate_markdown(),
        encoding='utf-8'
    )

    (output_dir / "tutorials.md").write_text(
        tutorial_gen.generate_markdown(),
        encoding='utf-8'
    )

    logger.info(f"Examples generated in {output_dir}")
