#!/usr/bin/env python3
"""
Spin Animation - Rotate objects continuously or with variation.

Creates spinning, rotating, and wobbling effects.
"""

import sys
from pathlib import Path
import math

sys.path.append(str(Path(__file__).parent.parent))

from PIL import Image
from core.gif_builder import GIFBuilder
from core.frame_composer import create_blank_frame, draw_emoji_enhanced, draw_circle
from core.easing import interpolate


def create_spin_animation(
    object_type: str = 'emoji',
    object_data: dict | None = None,
    num_frames: int = 30,
    rotation_type: str = 'clockwise',  # 'clockwise', 'counterclockwise', 'wobble', 'pendulum'
    full_rotations: float = 1.0,
    easing: str = 'linear',
    center_pos: tuple[int, int] = (240, 240),
    frame_width: int = 480,
    frame_height: int = 480,
    bg_color: tuple[int, int, int] = (255, 255, 255)
) -> list[Image.Image]:
    """
    Create spinning/rotating animation.

    Args:
        object_type: 'emoji', 'image', 'text'
        object_data: Object configuration
        num_frames: Number of frames
        rotation_type: Type of rotation
        full_rotations: Number of complete 360° rotations
        easing: Easing function for rotation speed
        center_pos: Center position for rotation
        frame_width: Frame width
        frame_height: Frame height
        bg_color: Background color

    Returns:
        List of frames
    """
    frames = []

    # Default object data
    if object_data is None:
        if object_type == 'emoji':
            object_data = {'emoji': '🔄', 'size': 100}

    for i in range(num_frames):
        frame = create_blank_frame(frame_width, frame_height, bg_color)
        t = i / (num_frames - 1) if num_frames > 1 else 0

        # Calculate rotation angle
        if rotation_type == 'clockwise':
            angle = interpolate(0, 360 * full_rotations, t, easing)
        elif rotation_type == 'counterclockwise':
            angle = interpolate(0, -360 * full_rotations, t, easing)
        elif rotation_type == 'wobble':
            # Back and forth rotation
            angle = math.sin(t * full_rotations * 2 * math.pi) * 45
        elif rotation_type == 'pendulum':
            # Smooth pendulum swing
            angle = math.sin(t * full_rotations * 2 * math.pi) * 90
        else:
            angle = interpolate(0, 360 * full_rotations, t, easing)

        # Create object on transparent background to rotate
        if object_type == 'emoji':
            # For emoji, we need to create a larger canvas to avoid clipping during rotation
            emoji_size = object_data['size']
            canvas_size = int(emoji_size * 1.5)
            emoji_canvas = Image.new('RGBA', (canvas_size, canvas_size), (0, 0, 0, 0))

            # Draw emoji in center of canvas
            from core.frame_composer import draw_emoji_enhanced
            draw_emoji_enhanced(
                emoji_canvas,
                emoji=object_data['emoji'],
                position=(canvas_size // 2 - emoji_size // 2, canvas_size // 2 - emoji_size // 2),
                size=emoji_size,
                shadow=False
            )

            # Rotate the canvas
            rotated = emoji_canvas.rotate(angle, resample=Image.BICUBIC, expand=False)

            # Paste onto frame
            paste_x = center_pos[0] - canvas_size // 2
            paste_y = center_pos[1] - canvas_size // 2
            frame.paste(rotated, (paste_x, paste_y), rotated)

        elif object_type == 'text':
            from core.typography import draw_text_with_outline
            # Similar approach - create canvas, draw text, rotate
            text = object_data.get('text', 'SPIN!')
            font_size = object_data.get('font_size', 50)

            canvas_size = max(frame_width, frame_height)
            text_canvas = Image.new('RGBA', (canvas_size, canvas_size), (0, 0, 0, 0))

            # Draw text
            text_canvas_rgb = text_canvas.convert('RGB')
            text_canvas_rgb.paste(bg_color, (0, 0, canvas_size, canvas_size))
            draw_text_with_outline(
                text_canvas_rgb,
                text,
                position=(canvas_size // 2, canvas_size // 2),
                font_size=font_size,
                text_color=object_data.get('text_color', (0, 0, 0)),
                outline_color=object_data.get('outline_color', (255, 255, 255)),
                outline_width=3,
                centered=True
            )

            # Convert back to RGBA for rotation
            text_canvas = text_canvas_rgb.convert('RGBA')

            # Make background transparent
            data = text_canvas.getdata()
            new_data = []
            for item in data:
                if item[:3] == bg_color:
                    new_data.append((255, 255, 255, 0))
                else:
                    new_data.append(item)
            text_canvas.putdata(new_data)

            # Rotate
            rotated = text_canvas.rotate(angle, resample=Image.BICUBIC, expand=False)

            # Composite onto frame
            frame_rgba = frame.convert('RGBA')
            frame_rgba = Image.alpha_composite(frame_rgba, rotated)
            frame = frame_rgba.convert('RGB')

        frames.append(frame)

    return frames


def create_loading_spinner(
    num_frames: int = 20,
    spinner_type: str = 'dots',  # 'dots', 'arc', 'emoji'
    size: int = 100,
    color: tuple[int, int, int] = (100, 150, 255),
    frame_width: int = 128,
    frame_height: int = 128,
    bg_color: tuple[int, int, int] = (255, 255, 255)
) -> list[Image.Image]:
    """
    Create a loading spinner animation.

    Args:
        num_frames: Number of frames
        spinner_type: Type of spinner
        size: Spinner size
        color: Spinner color
        frame_width: Frame width
        frame_height: Frame height
        bg_color: Background color

    Returns:
        List of frames
    """
    from PIL import ImageDraw
    frames = []
    center = (frame_width // 2, frame_height // 2)

    for i in range(num_frames):
        frame = create_blank_frame(frame_width, frame_height, bg_color)
        draw = ImageDraw.Draw(frame)

        angle_offset = (i / num_frames) * 360

        if spinner_type == 'dots':
            # Circular dots
            num_dots = 8
            for j in range(num_dots):
                angle = (j / num_dots * 360 + angle_offset) * math.pi / 180
                x = center[0] + size * 0.4 * math.cos(angle)
                y = center[1] + size * 0.4 * math.sin(angle)

                # Fade based on position
                alpha = 1.0 - (j / num_dots)
                dot_color = tuple(int(c * alpha) for c in color)
                dot_radius = int(size * 0.1)

                draw.ellipse(
                    [x - dot_radius, y - dot_radius, x + dot_radius, y + dot_radius],
                    fill=dot_color
                )

        elif spinner_type == 'arc':
            # Rotating arc
            start_angle = angle_offset
            end_angle = angle_offset + 270
            arc_width = int(size * 0.15)

            bbox = [
                center[0] - size // 2,
                center[1] - size // 2,
                center[0] + size // 2,
                center[1] + size // 2
            ]
            draw.arc(bbox, start_angle, end_angle, fill=color, width=arc_width)

        elif spinner_type == 'emoji':
            # Rotating emoji spinner
            angle = angle_offset
            emoji_canvas = Image.new('RGBA', (frame_width, frame_height), (0, 0, 0, 0))
            draw_emoji_enhanced(
                emoji_canvas,
                emoji='⏳',
                position=(center[0] - size // 2, center[1] - size // 2),
                size=size,
                shadow=False
            )
            rotated = emoji_canvas.rotate(angle, center=center, resample=Image.BICUBIC)
            frame.paste(rotated, (0, 0), rotated)

        frames.append(frame)

    return frames


# Example usage
if __name__ == '__main__':
    print("Creating spin animations...")

    builder = GIFBuilder(width=480, height=480, fps=20)

    # Example 1: Clockwise spin
    frames = create_spin_animation(
        object_type='emoji',
        object_data={'emoji': '🔄', 'size': 100},
        num_frames=30,
        rotation_type='clockwise',
        full_rotations=2
    )
    builder.add_frames(frames)
    builder.save('spin_clockwise.gif', num_colors=128)

    # Example 2: Wobble
    builder.clear()
    frames = create_spin_animation(
        object_type='emoji',
        object_data={'emoji': '🎯', 'size': 100},
        num_frames=30,
        rotation_type='wobble',
        full_rotations=3
    )
    builder.add_frames(frames)
    builder.save('spin_wobble.gif', num_colors=128)

    # Example 3: Loading spinner
    builder = GIFBuilder(width=128, height=128, fps=15)
    frames = create_loading_spinner(num_frames=20, spinner_type='dots')
    builder.add_frames(frames)
    builder.save('loading_spinner.gif', num_colors=64, optimize_for_emoji=True)

    print("Created spin animations!")
