# frozen_string_literal: true

require 'logger'

module Cryptum
  # This plugin is used to parse Coinbase Pro Web Socket Events in the HTTP Response
  module Event
    autoload :BotConf, 'cryptum/event/bot_conf'
    autoload :Buy, 'cryptum/event/buy'
    autoload :Cancel, 'cryptum/event/cancel'
    autoload :Exit, 'cryptum/event/exit'
    autoload :GTFO, 'cryptum/event/gtfo'
    autoload :History, 'cryptum/event/history'
    autoload :KeyPress, 'cryptum/event/key_press'
    autoload :OrderBook, 'cryptum/event/order_book'
    autoload :Pane, 'cryptum/event/pane'
    autoload :Scroll, 'cryptum/event/scroll'
    autoload :Sell, 'cryptum/event/sell'

    # Supported Method Parameters::
    # Cryptum::Event.parse(
    # )

    public_class_method def self.parse(opts = {})
      option_choice = opts[:option_choice]
      env = opts[:env]
      terminal_win = opts[:terminal_win]
      event_history = opts[:event_history]
      indicator_status = opts[:indicator_status]
      # indicator_history = opts[:indicator_history]
      bot_conf = opts[:bot_conf]
      # ai_enabled = opts[:ai_enabled]

      # candles = event_history.order_book[:candles]
      # order_history = event_history.order_book[:order_history]
      this_product = event_history.order_book[:this_product]
      fiat = this_product[:quote_currency]
      fiat_portfolio_file = "#{option_choice.repo_root}/order_books/#{fiat}_PORTFOLIO.json"

      # Determine if Summary UI needs updated data
      event_history = Cryptum::Portfolio::Balance.refresh(
        env: env,
        option_choice: option_choice,
        terminal_win: terminal_win,
        event_history: event_history,
        fiat_portfolio_file: fiat_portfolio_file
      )

      # If the Terminal Window has been Resized, Resize the UI
      if Curses.cols != terminal_win.cols
        terminal_win.cols = Curses.cols
        terminal_win.ticker_ui_resize = true
        terminal_win.market_trend_ui_resize = true
      end

      event_history = Cryptum::UI::Portfolio.refresh(
        option_choice: option_choice,
        portfolio_win: terminal_win.portfolio_section,
        event_history: event_history,
        key_press_event: terminal_win.key_press_event,
        indicator_status: indicator_status,
        bot_conf: bot_conf,
        fiat_portfolio_file: fiat_portfolio_file
      )

      if event_history.event_type == :ticker ||
         terminal_win.ticker_ui_resize

        ticker_event = event_history.ticker_event = event_history.event if event_history.event_type == :ticker
        ticker_event = event_history.ticker_event if terminal_win.ticker_ui_resize
        Cryptum::UI::Ticker.refresh(
          option_choice: option_choice,
          start_time: event_history.start_time,
          ticker_win: terminal_win.ticker_section,
          key_press_event: terminal_win.key_press_event,
          order_book: event_history.order_book,
          event: ticker_event
        )
      end

      # order_countdown = Cryptum::UI::OrderTimer.refresh(
      #   option_choice: option_choice,
      #   event_history: event_history,
      #   order_timer_win: terminal_win.order_timer_section,
      #   indicator_status: indicator_status,
      #   key_press_event: terminal_win.key_press_event
      # )

      if event_history.event_type == :l2update ||
         terminal_win.market_trend_ui_resize

        market_trend_event = event_history.market_trend_event = event_history.event if event_history.event_type == :l2update
        market_trend_event = event_history.market_trend_event if terminal_win.market_trend_ui_resize
        event_history = Cryptum::UI::MarketTrend.refresh(
          option_choice: option_choice,
          market_trend_win: terminal_win.market_trend_section,
          event_history: event_history,
          key_press_event: terminal_win.key_press_event,
          event: market_trend_event,
          indicator_status: indicator_status,
          bot_conf: bot_conf
        )
      end

      indicator_status = Cryptum::UI::SignalEngine.refresh(
        option_choice: option_choice,
        signal_engine_win: terminal_win.signal_engine_section,
        event_history: event_history,
        key_press_event: terminal_win.key_press_event,
        indicator_status: indicator_status,
        bot_conf: bot_conf,
        fiat_portfolio_file: fiat_portfolio_file
      )

      unless event_history.order_plan_details_win_active
        event_history = Cryptum::UI::OrderPlan.refresh(
          option_choice: option_choice,
          order_plan_win: terminal_win.order_plan_section,
          env: env,
          event_history: event_history,
          key_press_event: terminal_win.key_press_event,
          indicator_status: indicator_status,
          bot_conf: bot_conf,
          fiat_portfolio_file: fiat_portfolio_file
        )
        recalc_op = event_history.recalculate_order_plan
        order_plan = event_history.order_book[:order_plan]
        terminal_win.key_press_event.key_w = true if (recalc_op || order_plan.empty?) &&
                                                     !event_history.red_pill
        event_history.recalculate_order_plan = false
      end

      if event_history.order_plan_details_win_active
        event_history = Cryptum::UI::OrderPlanDetails.refresh(
          option_choice: option_choice,
          order_plan_details_win: terminal_win.order_plan_details_section,
          event_history: event_history,
          key_press_event: terminal_win.key_press_event
        )
      end

      unless event_history.order_execute_details_win_active
        event_history = Cryptum::UI::OrderExecution.refresh(
          option_choice: option_choice,
          order_execute_win: terminal_win.order_execute_section,
          env: env,
          event_history: event_history,
          key_press_event: terminal_win.key_press_event,
          indicator_status: indicator_status,
          bot_conf: bot_conf,
          fiat_portfolio_file: fiat_portfolio_file
        )
      end

      if event_history.order_execute_details_win_active
        event_history = Cryptum::UI::OrderExecuteDetails.refresh(
          option_choice: option_choice,
          order_execute_details_win: terminal_win.order_execute_details_section,
          event_history: event_history,
          key_press_event: terminal_win.key_press_event
        )
      end

      # Refresh Command Section for Cryptum Session Usage
      Cryptum::UI::Command.refresh(
        command_win: terminal_win.command_section,
        key_press_event: terminal_win.key_press_event
      )

      # 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

      event_history
    rescue LoadError => e
      # This happens when autoloading modules fail.
      File.open('/tmp/cryptum-errors.txt', 'a') do |f|
        f.puts Time.now.strftime('%Y-%m-%d %H:%M:%S.%N %z')
        f.puts "Module: #{self}"
        f.puts "#{e}\n\n\n"
      end

      retry
    rescue Interrupt
      # Exit Gracefully if CTRL+C is Pressed During Session
      Cryptum.exit_gracefully(which_self: self)
    rescue StandardError => e
      raise e
    ensure
      $stdout.flush
    end

    # Display Usage for this Module

    public_class_method def self.help
      constants.sort
    end
  end
end