# frozen_string_literal: true

module I18nJS
  require "i18n-js/plugin"

  class ExportFilesPlugin < I18nJS::Plugin
    def setup
      I18nJS::Schema.root_keys << config_key
    end

    def validate_schema
      valid_keys = %i[enabled files]

      schema.expect_required_keys(keys: valid_keys, path: [config_key])
      schema.reject_extraneous_keys(keys: valid_keys, path: [config_key])
      schema.expect_array_with_items(path: [config_key, :files])

      config[:files].each_with_index do |_exports, index|
        export_keys = %i[template output]

        schema.expect_required_keys(
          keys: export_keys,
          path: [config_key, :files, index]
        )

        schema.reject_extraneous_keys(
          keys: export_keys,
          path: [config_key, :files, index]
        )

        schema.expect_type(
          path: [config_key, :files, index, :template],
          types: String
        )

        schema.expect_type(
          path: [config_key, :files, index, :output],
          types: String
        )
      end
    end

    def after_export(files:)
      require "erb"
      require "digest/md5"
      require "json"

      files.each do |file|
        dir = File.dirname(file)
        name = File.basename(file)
        extension = File.extname(name)
        base_name = File.basename(file, extension)

        config[:files].each do |export|
          translations = JSON.load_file(file)
          template = Template.new(
            file:,
            translations:,
            template: export[:template]
          )

          contents = template.render

          output = format(
            export[:output],
            dir:,
            name:,
            extension:,
            digest: Digest::MD5.hexdigest(contents),
            base_name:
          )

          File.open(output, "w") do |io|
            io << contents
          end
        end
      end
    end

    class Template
      attr_accessor :file, :translations, :template

      def initialize(**kwargs)
        kwargs.each do |key, value|
          public_send(:"#{key}=", value)
        end
      end

      def banner(comment: "// ", include_time: true)
        [
          "#{comment}File generated by i18n-js",
          include_time ? " on #{Time.now}" : nil
        ].compact.join
      end

      def render
        ERB.new(File.read(template)).result(binding)
      end
    end
  end

  I18nJS.register_plugin(ExportFilesPlugin)
end
