# frozen_string_literal: true

require 'optparse'
require 'yaml'

module Cryptum
  # Cryptum::UI Module used for Presenting the
  # Cryptum Curses Interface
  module Option
    require 'cryptum/option/choice'
    # autoload :Choice, 'cryptum/option/choice'

    # Options for cryptum Driver
    public_class_method def self.parser(opts = {})
      option_choice = Option::Choice.new
      option_choice.driver_name = opts[:driver_name]

      OptionParser.new do |options|
        options.banner = "USAGE: #{option_choice.driver_name} [opts]"

        options.on(
          '-sSYMBOL',
          '--symbol=SYMBOL',
          '<Required - Crypto Symbol.(e.g. btc-usd, eth-usd, etc.)'
        ) { |s| option_choice.symbol = s.to_s.gsub('-', '_').downcase.to_sym }

        options.on(
          '-A',
          '--[no-]autotrade',
          '<Optional - Automatically Buy and Sell Crypto>'
        ) { |a| option_choice.autotrade = a }

        options.on(
          '-l',
          '--[no-]list-products',
          '<Optional - List Supported Crypto Currency Products and Exit>'
        ) { |l| option_choice.list_products = l }

        options.on(
          '-pPROXY',
          '--proxy=PROXY',
          '<Optional - HTTP Proxy e.g. "http://127.0.0.1:8080">'
        ) { |p| option_choice.proxy = p }

        options.on(
          '-R',
          '--[no-]reset-session-countdown',
          '<Optional - Reset Timers / Market Trend Stats at Session Init (Defaults to false)>'
        ) { |t| option_choice.reset_session_countdown = t }

        options.on(
          '-rPATH',
          '--session-root=PATH',
          '<Optional - Directory with etc && order_books (Defaults to ~/cryptum)>'
        ) { |r| option_choice.session_root = r }

        options.on(
          '-S',
          '--[no-]sandbox',
          '<Optional - Use Coinbase Sandbox Environment for Testing Ideas>'
        ) { |n| option_choice.sandbox = n }

        options.on(
          '-tSECONDS',
          '--time-between-market-trend-reset=SECONDS',
          '<Optional - Seconds Between Market Trend Reset (Default 60 i.e. 1 hour)>'
        ) { |t| option_choice.market_trend_reset = t.to_i }
      end.parse!

      input_validation(option_choice: option_choice)

      option_choice
    rescue OptionParser::InvalidOption => e
      # Print Usage if unsupported flags are passed
      puts "ERROR: #{e.message}\n\n"
      puts `#{option_choice.driver_name} --help`
      exit 1
    rescue StandardError => e
      raise e
    end

    # Validate Options for cryptum Driver
    public_class_method def self.input_validation(opts = {})
      option_choice = opts[:option_choice]

      # Conditions to display cryptum usage
      if option_choice.symbol.nil? && option_choice.list_products.nil?
        usage = true
        reason = :symbol
      end

      option_choice.session_root = "#{Dir.home}/cryptum" if option_choice.session_root.nil?

      unless Dir.exist?(option_choice.session_root)
        usage = true
        reason = :session_root
      end

      option_choice.market_trend_reset = 86_400 if option_choice.market_trend_reset.to_i.zero?
      unless option_choice.market_trend_reset.to_i >= 60 &&
             option_choice.market_trend_reset <= 604_800
        usage = true
        reason = :market_trend_reset
      end

      case option_choice.market_trend_reset
      when 604_800
        option_choice.market_trend_reset_label = '1W'
      when 86_400
        option_choice.market_trend_reset_label = '1D'
      when 14_400
        option_choice.market_trend_reset_label = '4h'
      when 10_800
        option_choice.market_trend_reset_label = '3h'
      when 7_200
        option_choice.market_trend_reset_label = '2h'
      when 3_600
        option_choice.market_trend_reset_label = '1h'
      when 2_700
        option_choice.market_trend_reset_label = '45m'
      when 1_800
        option_choice.market_trend_reset_label = '30m'
      when 900
        option_choice.market_trend_reset_label = '15m'
      when 300
        option_choice.market_trend_reset_label = '5m'
      when 180
        option_choice.market_trend_reset_label = '3m'
      when 60
        option_choice.market_trend_reset_label = '1m'
      else
        usage = true
        reason = :market_trend_reset
      end

      if usage
        case reason
        when :symbol
          puts "ERROR: --symbol Flag is Required.\n\n"
        when :session_root
          puts "ERROR: #{option_choice.session_root} does not exist.\n\n"
        when :market_trend_reset
          puts "ERROR: #{option_choice.market_trend_reset} - Possible values are: 604_800 || 86_400 || 14_400 || 10_800 || 7_200 || 3_600 || 2_700 || 1_800 || 900 || 300 || 180 || 60\n\n"
        end

        puts `#{option_choice.driver_name} --help`
        exit 1
      end
    rescue StandardError => e
      raise e
    end

    # List Supported Cryptum Products and Exit
    public_class_method def self.list_products_and_exit(opts = {})
      option_choice = opts[:option_choice]
      env = opts[:env]

      puts "\n#{option_choice.driver_name} Supports the Following Products:"
      products = Cryptum::API.get_products(
        option_choice: option_choice,
        env: env
      )

      products.map do |product|
        puts product[:id].downcase
      end

      exit 0
    rescue StandardError => e
      raise e
    end

    # Initialize Cryptum Session Environment
    public_class_method def self.get_env(opts = {})
      option_choice = opts[:option_choice]

      yaml_conf_file = "#{option_choice.session_root}/etc/coinbase_pro.yaml"
      yaml_conf = YAML.load_file(
        yaml_conf_file,
        symbolize_names: true
      )

      env = yaml_conf[:prod]
      env[:env] = :prod
      env = yaml_conf[:sandbox] if option_choice.sandbox
      env[:env] = :sandbox if option_choice.sandbox

      env
    rescue StandardError => e
      raise e
    end

    # Display a List of Every UI Module
    public_class_method def self.help
      constants.sort
    end
  end
end