# frozen_string_literal: true

module Cryptum
  # This plugin is used to Submit a Limit Order
  # to Sell Crypto Currency

  module Event
    module Sell
      # Supported Method Parameters::
      # Cryptum::Event::Sell.crypto(
      # )
      public_class_method def self.crypto(opts = {})
        option_choice = opts[:option_choice]
        env = opts[:env]
        bot_conf = opts[:bot_conf]
        stuck_in_pos_status = opts[:stuck_in_pos_status]
        event_history = opts[:event_history]
        order_type = opts[:order_type]
        fiat_smallest_decimal = opts[:fiat_smallest_decimal]
        crypto_smallest_decimal = opts[:crypto_smallest_decimal]
        base_min_size = opts[:base_min_size]
        indicator_status = opts[:indicator_status]
        quote_increment = opts[:quote_increment]

        # Initialize some bot_conf variables
        pie_in_sky_sell_percent = bot_conf[:pie_in_sky_sell_percent].to_f

        crypto_currency = option_choice.symbol.to_s.upcase.split('_').first
        portfolio = event_history.order_book[:portfolio]
        symbol_portfolio = portfolio.select do |this_portfolio|
          this_portfolio if this_portfolio[:currency] == crypto_currency
        end

        symbol_balance_available = format(
          '%0.8f',
          symbol_portfolio.first[:available].to_f
        ).to_f

        # 2. Calculate Price, Size, Fees
        # Get the middle of last 3 ticker prices
        # to avoid over purcase blips.
        last_three_prices_arr = []
        last_ticker_price = event_history.order_book[:ticker_price].to_f
        second_to_last_ticker_price = event_history.order_book[:ticker_price_second_to_last].to_f
        third_to_last_ticker_price = event_history.order_book[:ticker_price_third_to_last].to_f
        last_three_prices_arr.push(last_ticker_price)
        last_three_prices_arr.push(second_to_last_ticker_price)
        last_three_prices_arr.push(third_to_last_ticker_price)
        # limit_price = last_three_prices_arr.min
        # limit_price = last_three_prices_arr.max

        # Obtain our Target Price based on TPM configurations
        target_symbol_price = stuck_in_pos_status[:target_symbol_price].to_f

        case order_type
        when :pie
          pie_in_sky_sell_percent_cast_as_decimal = format(
            '%0.2f',
            pie_in_sky_sell_percent * 0.01
          ).to_f

          target_profit = target_symbol_price * pie_in_sky_sell_percent_cast_as_decimal
          limit_price = target_symbol_price + target_profit

        when :tpm
          limit_price = target_symbol_price
          order_type = :tpm
        when :gtfo
          # Attempt to get in front of falling price.
          limit_price = last_three_prices_arr.sort[1]
          gtfo_price = limit_price -= quote_increment.to_f
          limit_price = gtfo_price if gtfo_price.positive?
        else
          raise "ERROR: Unknown order_type: #{order_type}"
        end

        price = format("%0.#{fiat_smallest_decimal}f", limit_price)

        # Selling Available Crytpo Balance in its Entirety
        # We Will Likely Want to Change this in the Future.
        size = format(
          "%0.#{crypto_smallest_decimal}f",
          symbol_balance_available.floor(crypto_smallest_decimal)
        )

        size = symbol_balance_available if base_min_size.to_i == 1

        if size.to_f >= base_min_size.to_f &&
           price.to_f.positive?

          # SUBMIT SELL ORDER
          event_history.order_submitted = true
          event_history.event_notes = "{ \"event_type\": \"#{event_history.event_type}\", \"cancel\": \"#{event_history.order_canceled}\", \"submitted\": \"#{event_history.order_submitted}\" }" if option_choice.proxy

          event_history = Cryptum::API.submit_limit_order(
            option_choice: option_choice,
            env: env,
            price: price,
            size: size,
            buy_or_sell: :sell,
            order_type: order_type,
            event_history: event_history,
            indicator_status: indicator_status
          )
        end

        event_history
      rescue StandardError => e
        raise e
      end

      # Display Usage for this Module
      public_class_method def self.help
        puts "USAGE:
         order_book = #{self}.crypto()
        "
      end
    end
  end
end