# frozen_string_literal: true

require_relative '../api_resource'

module ErpIntegration
  module Fulfil
    module Resources
      class SalesOrder < ApiResource
        self.model_name = 'sale.sale'

        # Allows cancelling the entire sales order in Fulfil.
        # @param id [Integer|String] The ID of the to be cancelled order.
        # @return [boolean] Whether the sales order was cancelled successfully or not.
        def cancel(id)
          client.put("model/sale.sale/#{id}/cancel")
          true

        # Fulfil will return an 400 (a.k.a. "Bad Request") status code when a sales order couldn't
        # be cancelled. If a sales order isn't cancellable by design, no exception should be raised.
        #
        # See the Fulfil's documentation for more information:
        # https://developers.fulfil.io/rest_api/model/sale.sale/#cancel-a-sales-order
        rescue ErpIntegration::HttpError::BadRequest
          false
        # Workaround: Fulfil api does not return a json when status code is 200 (a.k.a. "Ok")
        # and faraday is having an error when trying to parse it. Let's skip the parse error
        # and move on.
        rescue Faraday::ParsingError
          true
        end

        def return!(id, options)
          client.put("model/sale.sale/#{id}/return_order", options)
        rescue ErpIntegration::HttpError::BadRequest
          false
        end

        # Allows duplicating the entire sales order in Fulfil.
        # @param id [Integer|String] The ID of the to be duplicated order.
        # @return [Array|boolean] Whether the sales order was duplicated successfully or not.
        def duplicate(id)
          duplicated_order_id = client.put("model/sale.sale/#{id}/copy").first
          ErpIntegration::SalesOrder.new(id: duplicated_order_id)

        # Fulfil will return an 400 (a.k.a. "Bad Request") status code when a sales order couldn't
        # be duplicated.
        rescue ErpIntegration::HttpError::BadRequest
          false
        end

        # Confirm the order on Fulfil.
        # @param id [Integer|String] The ID of the to be confirmed order.
        # @return [boolean] Whether the sales order was confirmed successfully or not.
        def confirm(id)
          client.put("model/sale.sale/#{id}/confirm")
          true

        # Fulfil will return an 400 (a.k.a. "Bad Request") status code when a sales order couldn't
        # be confirmed.
        rescue ErpIntegration::HttpError::BadRequest
          false
        # Workaround: Fulfil api does not return a json when status code is 200 (a.k.a. "Ok")
        # and faraday is having an error when trying to parse it. Let's skip the parse error
        # and move on.
        rescue Faraday::ParsingError
          true
        end

        # Process the order on Fulfil.
        # @param id [Integer|String] The ID of the to be processed order.
        # @return [boolean] Whether the sales order was processed successfully or not.
        def process(id)
          client.put("model/sale.sale/#{id}/process")
          true

        # Fulfil will return an 400 (a.k.a. "Bad Request") status code when a sales order couldn't
        # be processed.
        rescue ErpIntegration::HttpError::BadRequest
          false
        # Workaround: Fulfil api does not return a json when status code is 200 (a.k.a. "Ok")
        # and faraday is having an error when trying to parse it. Let's skip the parse error
        # and move on.
        rescue Faraday::ParsingError
          true
        end
      end
    end
  end
end