# frozen_string_literal: true

module WhatsappSdk
  module Resource
    class Component
      class InvalidField < StandardError
        attr_reader :field, :message

        def initialize(field, message)
          @field = field
          @message = message
          super(message)
        end
      end

      module Type
        HEADER = "header"
        BODY = "body"
        BUTTON = "button"
      end

      module Subtype
        QUICK_REPLY = "quick_reply"
        URL = "url"
      end

      # Returns the Component type.
      #
      # @returns type [String]. Supported Options are header, body and button.
      attr_accessor :type

      # Returns the parameters of the component. For button type, it's required.
      #
      # @returns parameter [Array<ButtonParameter, ParameterObject>] .
      attr_accessor :parameters

      # Returns the Type of button to create. Required when type=button. Not used for the other types.
      # Supported Options
      # quick_reply: Refers to a previously created quick reply button
      # that allows for the customer to return a predefined message.
      # url: Refers to a previously created button that allows the customer to visit the URL generated by
      # appending the text parameter to the predefined prefix URL in the template.
      #
      # @returns subtype [String]. Valid options are quick_reply and url.
      attr_accessor :sub_type

      # Required when type=button. Not used for the other types.
      # Position index of the button. You can have up to 3 buttons using index values of 0 to 2.
      #
      # @returns index [Integer].
      attr_accessor :index

      def add_parameter(parameter)
        @parameters << parameter
      end

      def initialize(type:, parameters: [], sub_type: nil, index: nil)
        @parameters = parameters
        @type = type
        @sub_type = sub_type
        @index = index.nil? && type == Type::BUTTON ? 0 : index
        validate_fields
      end

      def to_json
        json = {
          type: type,
          parameters: parameters.map(&:to_json)
        }
        json[:sub_type] = sub_type if sub_type
        json[:index] = index if index
        json
      end

      private

      def validate_fields
        return if type == Type::BUTTON

        raise InvalidField.new(:sub_type, 'sub_type is not required when type is not button') if sub_type

        raise InvalidField.new(:index, 'index is not required when type is not button') if index
      end
    end
  end
end
