module Jekyll
  module Tags
    class AssetTag < Liquid::Tag
      def initialize(tag_name, asset_name, tokens)
        super
        @asset_name = asset_name
      end

      def render(context)
        site = context.registers[:site]
        manifest_path = File.join(site.cache_dir, 'skyhook', 'assets-manifest.json')

        # Render any variables in the asset name
        asset_name = Liquid::Template.parse(@asset_name).render(context).strip

        manifest = JSON.parse(File.read(manifest_path))
        digested = manifest.fetch(asset_name)
        "/#{digested}"
      end
    end

    class SrcsetTag < Liquid::Tag
      def initialize(tag_name, markup, tokens)
        super
        @markup = markup.strip
      end

      def render(context)
        site = context.registers[:site]
        skyhook = Jekyll::Skyhook.instance(site)

        asset_path, format, widths = parse_srcset_markup(@markup)

        # Render any variables in the path
        asset_path = Liquid::Template.parse(asset_path).render(context).strip

        # Find the original file
        original_file_path = File.join(site.source, asset_path)
        unless File.exist?(original_file_path)
          raise "Image file not found: #{asset_path}"
        end

        srcset = widths.map do |width|
          transformations = { width: width.to_s }
          transformations[:format] = format if format
          digested_path = skyhook.process_image_transformation(original_file_path, transformations)
          "/#{digested_path} #{width}w"
        end.join(', ')

        "srcset=\"#{srcset}\""
      end

      private

      def parse_srcset_markup(markup)
        # Parse: path[format="webp"] 400 800 1200
        # Or: path 400 800 1200

        if markup.include?('[format="')
          match = markup.match(/^([^\[]+)\[format="([^"]+)"\](.*)$/)
          if match
            asset_path = match[1].strip
            format = match[2]
            widths_part = match[3].strip
            if widths_part.empty?
              # No widths provided - fall back to simple parsing
              return [asset_path, nil, []]
            else
              widths = widths_part.split.map(&:to_i)
              return [asset_path, format, widths]
            end
          end
        end

        # Fallback to original parsing - be careful with liquid variables
        # Look for numeric parts from the end
        parts = markup.split
        numeric_parts = []
        path_parts = []

        parts.reverse.each do |part|
          if part.match?(/^\d+$/)
            numeric_parts.unshift(part.to_i)
          else
            path_parts = parts[0...(parts.length - numeric_parts.length)]
            break
          end
        end

        asset_path = path_parts.join(' ')
        widths = numeric_parts
        [asset_path, nil, widths]
      end
    end

    class ImageTransformTag < Liquid::Tag
      def initialize(tag_name, markup, tokens)
        super
        @markup = markup.strip
      end

      def render(context)
        site = context.registers[:site]
        skyhook = Jekyll::Skyhook.instance(site)

        asset_path, transformations = parse_markup(@markup)

        # Render any variables in the asset path
        asset_path = Liquid::Template.parse(asset_path).render(context).strip

        # Convert transformation values using context
        parsed_transformations = {}
        transformations.each do |key, value|
          parsed_value = Liquid::Template.parse(value).render(context).strip
          parsed_transformations[key.to_sym] = parsed_value
        end

        # Find the original file
        original_file_path = File.join(site.source, asset_path)
        unless File.exist?(original_file_path)
          raise "Image file not found: #{asset_path}"
        end

        # Process the transformation or get original digested path
        if parsed_transformations.any?
          digested_path = skyhook.process_image_transformation(original_file_path, parsed_transformations)
          return "" unless digested_path
          "/#{digested_path}"
        else
          # No transformations - return original digested asset path
          manifest_path = File.join(site.cache_dir, 'skyhook', 'assets-manifest.json')
          if File.exist?(manifest_path)
            manifest = JSON.parse(File.read(manifest_path))
            digested_path = manifest[asset_path]
            digested_path ? "/#{digested_path}" : ""
          else
            ""
          end
        end
      end

      private

      def parse_markup(markup)
        # Parse syntax like: foo/bar/baz.jpg[format="png"][width="400"]
        match = markup.match(/^([^\[]+)(.*)$/)
        return [markup, {}] unless match

        asset_path = match[1].strip
        brackets_part = match[2]

        transformations = {}

        # Extract all [key="value"] pairs
        brackets_part.scan(/\[([^=]+)="([^"]+)"\]/) do |key, value|
          transformations[key.strip] = value
        end

        [asset_path, transformations]
      end
    end
  end
end

Liquid::Template.register_tag('asset', Jekyll::Tags::AssetTag)
Liquid::Template.register_tag('srcset', Jekyll::Tags::SrcsetTag)
Liquid::Template.register_tag('image_transform', Jekyll::Tags::ImageTransformTag)
