require 'spec_helper'

RSpec.describe 'Jekyll Skyhook Integration' do
  let(:site) { create_test_site }
  let(:context) { create_liquid_context(site) }
  let(:skyhook) { Jekyll::Skyhook.instance(site) }

  before do
    # Create test images of different formats
    create_test_image(site, 'assets/hero.jpg', 1200, 800)
    create_test_image(site, 'assets/images/posts/2024/my-post.png', 800, 600)
    create_test_image(site, 'assets/blog/featured.jpg', 1000, 667)

    skyhook.process_assets
  end

  after do
    FileUtils.rm_rf(site.source)
    FileUtils.rm_rf(site.dest)
    FileUtils.rm_rf(site.cache_dir)
  end

  describe 'complete picture element workflow' do
    it 'generates all required image formats and sizes' do
      image_path = 'assets/hero.jpg'

      # Test AVIF srcset
      avif_tag = create_tag(Jekyll::Tags::SrcsetTag, "#{image_path}[format=\"avif\"] 400 800 1200")
      avif_result = avif_tag.render(context)

      expect(avif_result).to include('srcset="')
      expect(avif_result).to include('.avif')
      expect(avif_result).to include('400w')
      expect(avif_result).to include('800w')
      expect(avif_result).to include('1200w')

      # Test WebP srcset
      webp_tag = create_tag(Jekyll::Tags::SrcsetTag, "#{image_path}[format=\"webp\"] 400 800 1200")
      webp_result = webp_tag.render(context)

      expect(webp_result).to include('.webp')
      expect(webp_result).to include('400w')

      # Test PNG fallback srcset
      png_tag = create_tag(Jekyll::Tags::SrcsetTag, "#{image_path}[format=\"png\"] 400 800 1200")
      png_result = png_tag.render(context)

      expect(png_result).to include('.png')

      # Test fallback image
      fallback_tag = create_tag(Jekyll::Tags::ImageTransformTag, "#{image_path}[format=\"png\"][width=\"800\"]")
      fallback_result = fallback_tag.render(context)

      expect(fallback_result).to include('.png')
      expect(fallback_result).to include('width800')
    end
  end

  describe 'complex file paths' do
    it 'handles deeply nested image paths' do
      image_path = 'assets/images/posts/2024/my-post.png'

      transform_tag = create_tag(Jekyll::Tags::ImageTransformTag, "#{image_path}[width=\"400\"][format=\"webp\"]")
      result = transform_tag.render(context)

      expect(result).to include('_digested/assets/images/posts/2024/my-post-formatwebp-width400-')
      expect(result).to end_with('.webp')

      # Verify the file was actually created
      created_file = File.join(site.source, result[1..-1]) # Remove leading slash
      expect(File.exist?(created_file)).to be true
    end
  end

  describe 'multiple format conversions' do
    it 'converts same image to different formats' do
      image_path = 'assets/blog/featured.jpg'

      # Convert to WebP
      webp_tag = create_tag(Jekyll::Tags::ImageTransformTag, "#{image_path}[format=\"webp\"][width=\"600\"]")
      webp_result = webp_tag.render(context)

      # Convert to AVIF
      avif_tag = create_tag(Jekyll::Tags::ImageTransformTag, "#{image_path}[format=\"avif\"][width=\"600\"]")
      avif_result = avif_tag.render(context)

      # Convert to PNG
      png_tag = create_tag(Jekyll::Tags::ImageTransformTag, "#{image_path}[format=\"png\"][width=\"600\"]")
      png_result = png_tag.render(context)

      expect(webp_result).to end_with('.webp')
      expect(avif_result).to end_with('.avif')
      expect(png_result).to end_with('.png')

      # All should have different digests due to different formats
      webp_digest = webp_result.match(/-([a-f0-9]{32})\./)[1]
      avif_digest = avif_result.match(/-([a-f0-9]{32})\./)[1]
      png_digest = png_result.match(/-([a-f0-9]{32})\./)[1]

      expect([webp_digest, avif_digest, png_digest].uniq.length).to eq(3)
    end
  end

  describe 'responsive image sizes' do
    it 'generates multiple sizes of same image' do
      image_path = 'assets/hero.jpg'

      sizes = [200, 400, 800, 1200]
      results = sizes.map do |width|
        tag = create_tag(Jekyll::Tags::ImageTransformTag, "#{image_path}[width=\"#{width}\"]")
        tag.render(context)
      end

      # All results should be different
      expect(results.uniq.length).to eq(4)

      # Each should contain the correct width in filename
      sizes.each_with_index do |width, index|
        expect(results[index]).to include("width#{width}")
      end

      # Verify actual files exist and have correct dimensions
      results.each_with_index do |result, index|
        file_path = File.join(site.source, result[1..-1])
        expect(File.exist?(file_path)).to be true

        image = MiniMagick::Image.open(file_path)
        expect(image.width).to eq(sizes[index])
      end
    end
  end

  describe 'manifest persistence' do
    it 'persists transformations across Jekyll rebuilds' do
      image_path = 'assets/hero.jpg'

      # First build
      tag1 = create_tag(Jekyll::Tags::ImageTransformTag, "#{image_path}[width=\"400\"][format=\"webp\"]")
      result1 = tag1.render(context)

      # Write manifest
      skyhook.send(:write_manifest)

      # Simulate new Jekyll build with fresh Skyhook instance
      new_site = create_test_site
      create_test_image(new_site, 'assets/hero.jpg', 1200, 800) # Same image

      # Copy manifest to new site's cache
      FileUtils.cp_r(File.join(site.cache_dir, 'skyhook'), new_site.cache_dir)

      new_skyhook = Jekyll::Skyhook.instance(new_site)
      new_context = create_liquid_context(new_site)

      # Second build should use cached result
      tag2 = create_tag(Jekyll::Tags::ImageTransformTag, "#{image_path}[width=\"400\"][format=\"webp\"]")
      result2 = tag2.render(new_context)

      expect(result1).to eq(result2)

      FileUtils.rm_rf(new_site.source)
      FileUtils.rm_rf(new_site.dest)
      FileUtils.rm_rf(new_site.cache_dir)
    end
  end

  describe 'liquid template integration' do
    it 'processes liquid variables in image paths and transformations' do
      var_context = create_liquid_context(site, {
        'post_image' => 'assets/hero.jpg',
        'mobile_width' => '400',
        'target_format' => 'webp'
      })

      tag = create_tag(Jekyll::Tags::ImageTransformTag,
        '{{ post_image }}[width="{{ mobile_width }}"][format="{{ target_format }}"]')
      result = tag.render(var_context)

      expect(result).to include('hero-formatwebp-width400-')
      expect(result).to end_with('.webp')
    end
  end

  describe 'error handling' do
    it 'provides helpful error for missing images' do
      tag = create_tag(Jekyll::Tags::ImageTransformTag, 'assets/missing.jpg[width="400"]')

      expect { tag.render(context) }.to raise_error(/Image file not found: assets\/missing\.jpg/)
    end

    it 'handles malformed transformation syntax gracefully' do
      # Missing quotes
      tag = create_tag(Jekyll::Tags::ImageTransformTag, 'assets/hero.jpg[width=400]')
      path, transformations = tag.send(:parse_markup, 'assets/hero.jpg[width=400]')

      expect(path).to eq('assets/hero.jpg')
      expect(transformations).to eq({}) # Should not parse malformed syntax
    end
  end

  describe 'static file registration' do
    it 'registers all transformed images as Jekyll static files' do
      initial_count = site.static_files.size

      # Generate multiple transformations
      tag1 = create_tag(Jekyll::Tags::ImageTransformTag, 'assets/hero.jpg[width="400"]')
      tag1.render(context)

      tag2 = create_tag(Jekyll::Tags::ImageTransformTag, 'assets/hero.jpg[format="webp"]')
      tag2.render(context)

      tag3 = create_tag(Jekyll::Tags::SrcsetTag, 'assets/blog/featured.jpg 200 400')
      tag3.render(context)

      # Should have added 4 new static files (1 + 1 + 2)
      expect(site.static_files.size).to eq(initial_count + 4)
    end
  end
end
