module VideoSlideGenerators
  def generate_intro_slide(slide)
    animation_duration = slide[:duration]
    hold_duration = slide[:hold_duration] || 1.0
    total_duration = animation_duration + hold_duration

    frames = (total_duration * 30).to_i

    frames.times do |frame|
      total_progress = frame.to_f / frames
      animation_progress = [total_progress / (animation_duration / total_duration), 1.0].min

      # Smooth ease-in-out animation
      eased_progress = ease_in_out(animation_progress)

      create_frame do |magick|
        magick.size "1920x1080"

        # Dynamic gradient background
        gradient_stop = (50 + eased_progress * 50).to_i
        magick << "gradient:#1DB954-#191414"

        # Animated overlay
        overlay_opacity = 0.4 + 0.2 * Math.sin(animation_progress * Math::PI * 4)
        magick.fill "rgba(0,0,0,#{overlay_opacity})"
        magick.draw "rectangle 0,0 1920,1080"

        # Main title with scale animation
        title_scale = 0.8 + 0.2 * eased_progress
        magick.font "DejaVu-Sans-Bold"
        magick.pointsize (120 * title_scale).to_i
        magick.fill "white"
        magick.gravity "Center"
        magick.annotate "+0-120", slide[:title]

        # Subtitle with delayed fade
        subtitle_opacity = [(animation_progress - 0.3) / 0.7, 0].max
        magick.pointsize 55
        magick.fill "rgba(255,255,255,#{subtitle_opacity})"
        magick.annotate "+0-20", slide[:subtitle]

        # Tagline with final fade
        tagline_opacity = [(animation_progress - 0.6) / 0.4, 0].max
        magick.pointsize 35
        magick.fill "rgba(29,185,84,#{tagline_opacity})"
        magick.annotate "+0+60", slide[:tagline]

        # Pulsing accent
        if animation_progress > 0.8
          pulse = Math.sin((animation_progress - 0.8) * Math::PI * 20) * 0.3 + 0.7
          magick.fill "rgba(29,185,84,#{pulse * 0.5})"
          magick.draw "circle 960,540 960,#{540 + 200 * pulse}"
        end
      end
    end
  end

  def generate_roast_slide(slide)
    animation_duration = slide[:duration]
    hold_duration = slide[:hold_duration] || 1.0
    total_duration = animation_duration + hold_duration

    frames = (total_duration * 30).to_i

    frames.times do |frame|
      total_progress = frame.to_f / frames
      animation_progress = [total_progress / (animation_duration / total_duration), 1.0].min

      create_frame do |magick|
        magick.size "1920x1080"
        magick << "xc:#191414"

        # Subtle background pattern
        pattern_opacity = 0.1 + 0.05 * Math.sin(animation_progress * Math::PI * 3)
        magick.fill "rgba(29,185,84,#{pattern_opacity})"
        (0..20).each do |i|
          y = i * 54
          magick.draw "rectangle 0,#{y} 1920,#{y+1}"
        end

        # Main text with typing effect
        chars_to_show = (slide[:title].length * animation_progress).to_i
        visible_title = slide[:title][0, chars_to_show]

        magick.font "DejaVu-Sans-Bold"
        magick.pointsize 85
        magick.fill "white"
        magick.gravity "Center"
        magick.annotate "+0-80", visible_title

        # Subtitle with fade
        if animation_progress > 0.4
          subtitle_opacity = (animation_progress - 0.4) / 0.6
          magick.pointsize 50
          magick.fill "rgba(255,255,255,#{subtitle_opacity})"
          magick.annotate "+0+20", slide[:subtitle]
        end

        # Tagline with final reveal
        if animation_progress > 0.7
          tagline_opacity = ((animation_progress - 0.7) / 0.3)
          magick.pointsize 30
          magick.fill "rgba(29,185,84,#{tagline_opacity})"
          magick.annotate "+0+100", slide[:tagline]
        end
      end
    end
  end

  def generate_stats_slide(slide)
    animation_duration = slide[:duration]
    hold_duration = slide[:hold_duration] || 1.0
    total_duration = animation_duration + hold_duration

    frames = (total_duration * 30).to_i

    frames.times do |frame|
      total_progress = frame.to_f / frames
      animation_progress = [total_progress / (animation_duration / total_duration), 1.0].min

      create_frame do |magick|
        magick.size "1920x1080"
        magick << "xc:#191414"

        # Title
        magick.font "DejaVu-Sans-Bold"
        magick.pointsize 75
        magick.fill "white"
        magick.gravity "Center"
        magick.annotate "+0-350", slide[:title]

        # Animate stats with staggered entrance
        slide[:stats].each_with_index do |stat, index|
          stat_delay = index * 0.25
          stat_progress = [(animation_progress - stat_delay) / (1.0 - stat_delay), 0].max
          next if stat_progress <= 0

          # Smooth entry animation
          entry_progress = ease_in_out([stat_progress, 1.0].min)
          y_offset = -150 + (index * 180)

          # Scale and fade animation
          scale = 0.5 + 0.5 * entry_progress
          opacity = entry_progress

          # Main stat with number animation
          if stat_progress > 0.3
            number_progress = [(stat_progress - 0.3) / 0.7, 1.0].min
            animated_value = (stat[:value].to_i * number_progress).to_i.to_s

            magick.pointsize (90 * scale).to_i
            magick.fill "rgba(29,185,84,#{opacity})"
            magick.annotate "+0+#{y_offset - 30}", sprintf(stat[:label], animated_value)
          end

          # Subtext with delayed fade
          if stat_progress > 0.6
            subtext_opacity = (stat_progress - 0.6) / 0.4
            magick.pointsize 28
            magick.fill "rgba(179,179,179,#{subtext_opacity})"
            magick.annotate "+0+#{y_offset + 40}", stat[:subtext]
          end
        end
      end
    end
  end

  def generate_top_list_slide(slide)
    animation_duration = slide[:duration]
    hold_duration = slide[:hold_duration] || 1.0
    total_duration = animation_duration + hold_duration

    frames = (total_duration * 30).to_i

    frames.times do |frame|
      total_progress = frame.to_f / frames
      animation_progress = [total_progress / (animation_duration / total_duration), 1.0].min

      create_frame do |magick|
        magick.size "1920x1080"
        magick << "xc:#191414"

        # Title with glow effect
        glow_radius = 20 + 10 * Math.sin(animation_progress * Math::PI * 3)
        magick.font "DejaVu-Sans-Bold"
        magick.pointsize 90
        magick.fill "#1DB954"
        magick.gravity "Center"
        magick.annotate "+0-380", slide[:title]

        # Subtitle
        magick.pointsize 32
        magick.fill "#B3B3B3"
        magick.annotate "+0-320", slide[:subtitle]

        # Animate list items with bounce
        slide[:items].each_with_index do |item, index|
          item_delay = index * 0.15
          item_progress = [(animation_progress - item_delay) * 3, 0].max
          next if item_progress <= 0

          # Bounce animation
          bounce_progress = [item_progress, 1.0].min
          bounce_offset = bounce_progress < 1.0 ?
            -30 * Math.sin(bounce_progress * Math::PI) : 0

          y_pos = -180 + (index * 90) + bounce_offset
          opacity = [item_progress, 1.0].min

          # Rank with medal emojis
          rank_emoji = case index
                      when 0 then "🥇"
                      when 1 then "🥈"
                      when 2 then "🥉"
                      else "#{index + 1}."
                      end

          magick.pointsize 45
          magick.fill "rgba(29,185,84,#{opacity})"
          magick.gravity "West"
          magick.annotate "+300+#{y_pos}", rank_emoji

          # Item name with emphasis
          magick.pointsize index == 0 ? 55 : 42
          magick.fill "rgba(255,255,255,#{opacity})"
          magick.annotate "+#{index == 0 ? 420 : 400}+#{y_pos}", item[:name]

          # Value
          magick.pointsize 30
          magick.fill "rgba(179,179,179,#{opacity})"
          magick.gravity "East"
          magick.annotate "-300+#{y_pos}", item[:value]

          # Roast text with delayed reveal
          if item_progress > 0.7
            roast_opacity = (item_progress - 0.7) * 3.33
            magick.pointsize 24
            magick.fill "rgba(29,185,84,#{roast_opacity})"
            magick.gravity "West"
            magick.annotate "+420+#{y_pos + 35}", item[:roast]
          end
        end
      end
    end
  end

  def generate_highlight_slide(slide)
    animation_duration = slide[:duration]
    hold_duration = slide[:hold_duration] || 1.0
    total_duration = animation_duration + hold_duration

    frames = (total_duration * 30).to_i

    frames.times do |frame|
      total_progress = frame.to_f / frames
      animation_progress = [total_progress / (animation_duration / total_duration), 1.0].min

      create_frame do |magick|
        magick.size "1920x1080"

        # Dynamic background with movement
        bg_offset = (animation_progress * 100).to_i
        magick << "gradient:#1DB954-#191414"
        magick.fill "rgba(25,20,20,0.6)"
        magick.draw "rectangle 0,0 1920,1080"

        # Animated particles
        if total_progress > 0.2
          20.times do |i|
            particle_progress = (total_progress - 0.2 + i * 0.02) % 1.0
            x = 100 + (i * 90) + (particle_progress * 200)
            y = 200 + Math.sin(particle_progress * Math::PI * 2) * 50
            opacity = Math.sin(particle_progress * Math::PI) * 0.3

            magick.fill "rgba(29,185,84,#{opacity})"
            magick.draw "circle #{x},#{y} #{x+5},#{y+5}"
          end
        end

        # Main title with dramatic scale
        title_scale = 0.7 + 0.3 * ease_in_out(animation_progress)
        title_glow = Math.sin(animation_progress * Math::PI * 2) * 0.2 + 0.8

        magick.font "DejaVu-Sans-Bold"
        magick.pointsize (140 * title_scale).to_i
        magick.fill "rgba(255,255,255,#{title_glow})"
        magick.gravity "Center"
        magick.annotate "+0-200", slide[:title]

        # Subtitle with slide-in
        if animation_progress > 0.3
          subtitle_offset = (1 - (animation_progress - 0.3) / 0.7) * 200
          magick.pointsize 48
          magick.fill "rgba(255,255,255,0.9)"
          magick.annotate "+#{subtitle_offset.to_i}+120", slide[:subtitle]
        end

        # Main stat with counter animation
        if animation_progress > 0.5
          stat_progress = (animation_progress - 0.5) / 0.5
          magick.pointsize 75
          magick.fill "#1DB954"
          magick.annotate "+0-60", slide[:main_stat]
        end

        # Flavor text with fade in
        if animation_progress > 0.6
          flavor_opacity = (animation_progress - 0.6) / 0.4
          magick.pointsize 35
          magick.fill "rgba(255,255,255,#{flavor_opacity})"
          magick.annotate "+0+20", slide[:flavor_text]
        end

        # Secondary text
        if animation_progress > 0.8
          secondary_opacity = (animation_progress - 0.8) / 0.2
          magick.pointsize 28
          magick.fill "rgba(179,179,179,#{secondary_opacity})"
          magick.annotate "+0+70", slide[:secondary_text]
        end
      end
    end
  end

  def generate_time_analysis_slide(slide)
    animation_duration = slide[:duration]
    hold_duration = slide[:hold_duration] || 1.0
    total_duration = animation_duration + hold_duration

    frames = (total_duration * 30).to_i

    frames.times do |frame|
      total_progress = frame.to_f / frames
      animation_progress = [total_progress / (animation_duration / total_duration), 1.0].min

      create_frame do |magick|
        magick.size "1920x1080"
        magick << "xc:#191414"

        # Title
        magick.font "DejaVu-Sans-Bold"
        magick.pointsize 65
        magick.fill "white"
        magick.gravity "Center"
        magick.annotate "+0-350", slide[:title]

        # Subtitle
        magick.pointsize 36
        magick.fill "#B3B3B3"
        magick.annotate "+0-280", slide[:subtitle]

        # Subtext with attitude
        if animation_progress > 0.3
          subtext_opacity = ((animation_progress - 0.3) / 0.7)
          magick.pointsize 28
          magick.fill "rgba(29,185,84,#{subtext_opacity})"
          magick.annotate "+0-230", slide[:subtext]
        end

        # Animated bar chart
        max_bar_height = 250
        bar_width = 200
        chart_start_x = 260
        chart_bottom_y = 750

        slide[:bars].each_with_index do |bar, index|
          bar_delay = index * 0.1
          bar_progress = [(animation_progress - bar_delay) / (1.0 - bar_delay), 0].max
          next if bar_progress <= 0

          # Bar animation with bounce
          height_progress = ease_out_bounce([bar_progress, 1.0].min)
          bar_height = (bar[:percentage] / 100.0 * max_bar_height * height_progress).to_i

          x_pos = chart_start_x + (index * (bar_width + 60))
          y_pos = chart_bottom_y - bar_height

          # Bar gradient
          magick.fill "#1DB954"
          magick.draw "rectangle #{x_pos},#{y_pos} #{x_pos + bar_width},#{chart_bottom_y}"

          # Bar glow effect
          glow_opacity = 0.3 * height_progress
          magick.fill "rgba(29,185,84,#{glow_opacity})"
          magick.draw "rectangle #{x_pos-5},#{y_pos-5} #{x_pos + bar_width+5},#{chart_bottom_y+5}"

          # Label
          magick.pointsize 28
          magick.fill "white"
          magick.gravity "Center"
          magick.annotate "+#{x_pos - 960 + bar_width/2}+#{chart_bottom_y - 540 + 40}", bar[:label]

          # Value on top of bar
          if bar_height > 30
            magick.pointsize 24
            magick.fill "white"
            magick.font "DejaVu-Sans-Bold"
            magick.annotate "+#{x_pos - 960 + bar_width/2}+#{y_pos - 540 + 20}", bar[:value]
          end
        end
      end
    end
  end

  def generate_surprise_slide(slide)
    animation_duration = slide[:duration]
    hold_duration = slide[:hold_duration] || 1.0
    total_duration = animation_duration + hold_duration

    frames = (total_duration * 30).to_i

    frames.times do |frame|
      total_progress = frame.to_f / frames
      animation_progress = [total_progress / (animation_duration / total_duration), 1.0].min

      create_frame do |magick|
        magick.size "1920x1080"

        # Surprise burst background
        burst_progress = ease_out_expo(animation_progress)
        magick << "radial-gradient:#1DB954-#191414"

        # Animated burst rays
        if animation_progress > 0.1
          12.times do |i|
            angle = (i * 30 + animation_progress * 360) % 360
            ray_length = 300 * burst_progress
            start_x = 960
            start_y = 540
            end_x = start_x + Math.cos(angle * Math::PI / 180) * ray_length
            end_y = start_y + Math.sin(angle * Math::PI / 180) * ray_length

            magick.stroke "rgba(255,255,255,0.1)"
            magick.strokewidth 3
            magick.draw "line #{start_x},#{start_y} #{end_x},#{end_y}"
          end
        end

        # Title with dramatic entrance
        title_scale = animation_progress < 0.5 ? animation_progress * 4 : 1.0 + Math.sin((animation_progress - 0.5) * Math::PI * 10) * 0.1
        magick.font "DejaVu-Sans-Bold"
        magick.pointsize (120 * title_scale).to_i
        magick.fill "white"
        magick.gravity "Center"
        magick.annotate "+0-150", slide[:title]

        # Subtitle with typewriter effect
        if animation_progress > 0.3
          chars_to_show = (((animation_progress - 0.3) / 0.7) * slide[:subtitle].length).to_i
          visible_subtitle = slide[:subtitle][0, chars_to_show]

          magick.pointsize 42
          magick.fill "rgba(255,255,255,0.9)"
          magick.annotate "+0-60", visible_subtitle
        end

        # Main stat with number roll
        if animation_progress > 0.6
          magick.pointsize 80
          magick.fill "#1DB954"
          magick.annotate "+0+30", slide[:main_stat]
        end

        # Flavor text with final reveal
        if animation_progress > 0.7
          flavor_opacity = ((animation_progress - 0.7) / 0.3)
          magick.pointsize 32
          magick.fill "rgba(255,255,255,#{flavor_opacity})"
          magick.annotate "+0+100", slide[:flavor_text]
        end
      end
    end
  end

  def generate_recap_slide(slide)
    animation_duration = slide[:duration]
    hold_duration = slide[:hold_duration] || 1.0
    total_duration = animation_duration + hold_duration

    frames = (total_duration * 30).to_i

    frames.times do |frame|
      total_progress = frame.to_f / frames
      animation_progress = [total_progress / (animation_duration / total_duration), 1.0].min

      create_frame do |magick|
        magick.size "1920x1080"

        # Final gradient with subtle animation
        gradient_opacity = 0.8 + 0.2 * Math.sin(animation_progress * Math::PI * 2)
        magick << "gradient:#1DB954-#191414"
        magick.fill "rgba(25,20,20,#{gradient_opacity * 0.4})"
        magick.draw "rectangle 0,0 1920,1080"

        # Floating particles finale
        50.times do |i|
          particle_progress = (total_progress + i * 0.02) % 1.0
          x = (i * 38.4) % 1920
          y = 100 + Math.sin(particle_progress * Math::PI + i) * 300
          opacity = Math.sin(particle_progress * Math::PI) * 0.2

          magick.fill "rgba(29,185,84,#{opacity})"
          magick.draw "circle #{x},#{y} #{x+3},#{y+3}"
        end

        # Title with celebration
        title_scale = 1.0 + Math.sin(animation_progress * Math::PI * 4) * 0.05
        magick.font "DejaVu-Sans-Bold"
        magick.pointsize (85 * title_scale).to_i
        magick.fill "white"
        magick.gravity "Center"
        magick.annotate "+0-300", slide[:title]

        # Subtitle
        magick.pointsize 38
        magick.fill "rgba(255,255,255,0.9)"
        magick.annotate "+0-230", slide[:subtitle]

        # Stats grid with staggered animation
        stats_per_row = 2
        # Animate stats with staggered entrance
        slide[:stats].each_with_index do |stat, index|
          stat_delay = index * 0.2
          stat_progress = [(animation_progress - stat_delay) / (1.0 - stat_delay), 0].max
          next if stat_progress <= 0

          row = index / stats_per_row
          col = index % stats_per_row

          x_offset = (col - 0.5) * 400
          y_offset = -100 + (row * 100)

          opacity = [stat_progress, 1.0].min
          scale = 0.8 + 0.2 * ease_in_out(stat_progress)

          # Stat label
          magick.pointsize (32 * scale).to_i
          magick.fill "rgba(179,179,179,#{opacity})"
          magick.annotate "+#{x_offset.to_i}+#{y_offset}", stat[:label]

          # Stat value
          magick.pointsize (45 * scale).to_i
          magick.fill "rgba(29,185,84,#{opacity})"
          magick.annotate "+#{x_offset.to_i}+#{y_offset + 40}", stat[:value]
        end

        # Final message with fade
        if animation_progress > 0.8
          message_opacity = ((animation_progress - 0.8) / 0.2)
          magick.pointsize 35
          magick.fill "rgba(255,255,255,#{message_opacity})"
          magick.annotate "+0+200", slide[:final_message]
        end
      end
    end
  end

  def generate_one_time_uses_slide(slide)
    animation_duration = slide[:duration]
    hold_duration = slide[:hold_duration] || 1.0
    total_duration = animation_duration + hold_duration

    frames = (total_duration * 30).to_i

    frames.times do |frame|
      total_progress = frame.to_f / frames
      animation_progress = [total_progress / (animation_duration / total_duration), 1.0].min

      create_frame do |magick|
        magick.size "1920x1080"
        magick << "xc:#191414"

        # Title with funky animation
        title_bounce = Math.sin(animation_progress * Math::PI * 4) * 5
        magick.font "DejaVu-Sans-Bold"
        magick.pointsize 75
        magick.fill "#1DB954"
        magick.gravity "Center"
        magick.annotate "+0-#{350 + title_bounce.to_i}", slide[:title]

        # Subtitle
        if animation_progress > 0.2
          subtitle_opacity = (animation_progress - 0.2) / 0.8
          magick.pointsize 40
          magick.fill "rgba(179,179,179,#{subtitle_opacity})"
          magick.annotate "+0-280", slide[:subtitle]
        end

        # List items with staggered animation
        slide[:items].each_with_index do |item, index|
          item_start = 0.3 + (index * 0.08)
          
          if animation_progress > item_start
            item_progress = (animation_progress - item_start) / (1.0 - item_start)
            opacity = [item_progress * 1.2, 1.0].min
            
            # Calculate position for 2 columns
            row = index / 2
            col = index % 2
            x_offset = col == 0 ? -300 : 300
            y_offset = -150 + (row * 80)
            
            # Slide in from sides
            slide_offset = (1 - ease_in_out(item_progress)) * (col == 0 ? -100 : 100)
            
            # Substance name
            magick.pointsize 42
            magick.fill "rgba(255,255,255,#{opacity})"
            magick.gravity "Center"
            magick.annotate "+#{x_offset + slide_offset.to_i}+#{y_offset}", item[:name]
            
            # "Just once" text
            magick.pointsize 28
            magick.fill "rgba(29,185,84,#{opacity * 0.8})"
            magick.annotate "+#{x_offset + slide_offset.to_i}+#{y_offset + 35}", item[:value]
            
            # Roast text if late enough
            if item_progress > 0.5 && item[:roast]
              roast_opacity = (item_progress - 0.5) * 2
              magick.pointsize 22
              magick.fill "rgba(179,179,179,#{roast_opacity * 0.7})"
              magick.font "DejaVu-Sans-Oblique"
              magick.annotate "+#{x_offset + slide_offset.to_i}+#{y_offset + 60}", item[:roast]
              magick.font "DejaVu-Sans"
            end
          end
        end
      end
    end
  end
end