module GiftCards
  class BalanceController < GiftCards::BaseController
    before_action :set_user, only: [:index, :modify, :wallet_status]

    SUPPORTED_CURRENCIES = [
      %w[USD USD],
      %w[EUR EUR]
    ].freeze

    ACTIONS = [
      ["Add Amount", "add_amount"],
      ["Deduct Amount", "deduct_amount"]
    ].freeze

    WALLET_STATUSES = [
      ["Active", "active"],
      ["Freeze", "freeze"]
    ].freeze

    CURRENCY_EXPONENTS = {
        USD: 2,
        EUR: 2
    }.freeze

    ACTION_MAP = {
        add_amount: Twitch::Fulton::Example::Twitchnami::Operation::ADD,
        deduct_amount: Twitch::Fulton::Example::Twitchnami::Operation::DEDUCT
    }.freeze

    STATUS_MAP = {
        freeze: Twitch::Fulton::Example::Twitchnami::WalletStatus::FROZEN,
        active: Twitch::Fulton::Example::Twitchnami::WalletStatus::ACTIVE
    }.freeze

    def set_user
      user_id = params[:id].presence || params[:balance_id].presence

      if user_id.present?
        @twitch_user = Twitch::User.find(user_id)
      elsif params[:search_query].present?
        @twitch_user = Twitch::User.all({
          :where => {
            :text => params[:search_query],
            :skip_pagination => true,
          },
        }).first
      end
    end

    def index
      authorize TwitchZuko::RedemptionsHistory
      authorize TwitchNami::Balance

      if @twitch_user.present?
        begin
          @balance = TwitchNami::Balance.call(@twitch_user.id.to_s)
          @balance_history = Mulan::GetBalanceHistory.call(@twitch_user.id)
        rescue StandardError => e
          flash[:error] = "Failed to fetch balance information #{e.message}"
        end
      end
    end

    def modify
      authorize TwitchNami::Transact
      amount = params[:amount]
      currency = params[:currency]
      exponent = CURRENCY_EXPONENTS[currency.to_sym]
      unless exponent.present?
        flash[:error] = "Invalid currency #{currency}"
        return redirect_back(gift_cards_balance_index_path)
      end

      true_amount = (amount.to_f * (10**exponent)).floor
      if true_amount <= 0
        flash[:error] = "Invalid amount #{amount}"
        return redirect_back(gift_cards_balance_index_path)
      end

      action = ACTION_MAP[params[:balance_action].to_sym]
      unless action.present?
        flash[:error] = "Invalid action #{params[:balance_action]}"
        return redirect_back(gift_cards_balance_index_path)
      end

      request_amount = Twitch::Fulton::Example::Twitchnami::Balance.new(
        exponent: exponent,
        amount: true_amount,
        currency: currency
      )

      resp = TwitchNami::Transact.call(current_user, @twitch_user.id.to_s, action, request_amount)
      if resp.failure.present? && !resp.failure.equal?(:NONE)
        flash[:error] = "Transaction failed: #{resp.failure}"
      else
        flash[:success] = "Updated #{@twitch_user.login} balance"
      end

      redirect_back(gift_cards_balance_index_path)
    end

    def wallet_status
      authorize TwitchNami::WalletStatus
      action = STATUS_MAP[params[:status_action].to_sym]

      unless action.present?
        flash[:error] = "Invalid status action #{params[:status_action]}"
        return redirect_back(gift_cards_balance_index_path)
      end

      resp = TwitchNami::WalletStatus.call(@twitch_user.id.to_s, action)
      if resp.failure.present? && !resp.failure.equal?(:NONE)
        flash[:error] = "updating wallet status failed: #{resp.failure}"
      else
        flash[:success] = "Updated #{@twitch_user.login} wallet status"
      end

      redirect_back(gift_cards_balance_index_path)
    end
  end
end
