require "faraday"
require "json"

class GameApiClient
  BASE_URL = "http://0.0.0.0:8000"

  def initialize
    @connection = Faraday.new(url: BASE_URL) do |f|
      f.request :json # リクエストをJSON形式にする
      f.response :json # レスポンスをJSONとしてパースする
      f.adapter Faraday.default_adapter
    end
  end

  # GET リクエスト: 初期状態の取得
  def api_game_initial_state(map_name = "standard")
    response = @connection.get("/game/initial-state", { map_name: map_name })
    handle_response(response, "game/initial-state")
  end

  # POST リクエスト: ゲームのみを強制終了 (Draw) にする
  def api_game_draw(game_state, winners: nil)
    response = @connection.post("/game/draw") do |req|
      body = { game_state: game_state }
      body[:winners] = winners if winners
      req.body = body
    end
    handle_response(response, "game/draw")
  end

  # GET リクエスト: 利用可能なマップの取得
  def api_maps
    response = @connection.get("/maps")
    handle_response(response, "maps")
  end

  # GET /maps/{map_name}
  def api_maps_data(map_name)
    response = @connection.get("/maps/#{map_name}")
    handle_response(response, "maps/#{map_name}")
  end

  # POST リクエスト: 可能な命令の計算
  def api_calculate_possible_orders(game_state, power_name: "", by_power: false)
    response = @connection.post("/calculate/possible-orders") do |req|
      req.params["power_name"] = power_name
      req.params["by_power"] = by_power
      req.body = { game_state: game_state }
    end
    handle_response(response, "calculate/possible-orders")
  end

  # POST リクエスト: 命令を処理して次のフェーズへ進める
  def api_calculate_process(game_state, orders)
    normalized_orders = normalize_orders(orders)
    response = @connection.post("/calculate/process") do |req|
      req.body = { game_state: game_state, orders: normalized_orders }
    end
    handle_response(response, "calculate/process")
  end

  # POST リクエスト: 命令の妥当性を検証する
  def api_calculate_validate(game_state, orders)
    normalized_orders = normalize_orders(orders)
    response = @connection.post("/calculate/validate") do |req|
      req.body = { game_state: game_state, orders: normalized_orders }
    end
    handle_response(response, "calculate/validate")
  end

  # POST リクエスト: 特定勢力の命令を自動生成する
  def api_calculate_auto_orders(game_state, power_name)
    response = @connection.post("/calculate/auto-orders") do |req|
      req.params["power_name"] = power_name
      req.body = { game_state: game_state }
    end
    handle_response(response, "calculate/auto-orders")
  end

  # POST リクエスト: マップをSVGとしてレンダリングする
  def api_render(game_state, orders: nil, incl_orders: true, incl_abbrev: true)
    # ordersのキーを文字列に変換し、値を配列に変換して正規化
    normalized_orders = normalize_orders(orders)

    body = {
      game_state: game_state,
      orders: normalized_orders,
      incl_orders: incl_orders,
      incl_abbrev: incl_abbrev
    }
    Rails.logger.debug "API Render Request Body: #{body.inspect}"

    response = @connection.post("/render") do |req|
      req.body = body
    end
    handle_response(response, "render")
  end

  private

  def normalize_orders(orders)
    return nil unless orders

    normalized_orders = {}
    orders.each do |power, power_orders|
      # power_ordersがハッシュの場合、値の配列に変換
      if power_orders.is_a?(Hash)
        normalized_orders[power.to_s] = power_orders.values
      elsif power_orders.is_a?(Array)
        normalized_orders[power.to_s] = power_orders
      else
        normalized_orders[power.to_s] = power_orders
      end
    end
    normalized_orders
  end

  def handle_response(response, endpoint)
    if response.success?
      response.body
    else
      Rails.logger.error "API Error (#{endpoint}): #{response.status} - #{response.body}"
      nil
    end
  end
end
