require "json"

class Articles::Show < BrowserAction
  fallback do
    post_id = maybe_post_id(context.request)
    case post_id
    in Monads::Just
      response = client_class.post_data(post_id.value!)
      page = PageConverter.new.convert(response.data)
      html ShowPage, page: page
    in Monads::Nothing, Monads::Maybe
      html(
        Errors::ShowPage,
        message: "Error parsing the URL",
        status_code: 500,
      )
    end
  end

  def maybe_post_id(request : HTTP::Request)
    from_params = post_id_from_params(request.query_params)
    from_path = post_id_from_path(request.path)
    from_path.or(from_params)
  end

  def post_id_from_path(request_path : String)
    Monads::Try(Regex::MatchData)
      .new(->{ request_path.match(/([0-9a-f]+)$/i) })
      .to_maybe
      .fmap(->(matches : Regex::MatchData) { matches[1] })
  end

  def post_id_from_params(params : URI::Params)
    maybe_uri = Monads::Try(String)
      .new(->{ params["redirectUrl"] })
      .to_maybe
      .fmap(->(url : String) { URI.parse(url) })
      .bind(->(uri : URI) { post_id_from_path(uri.path) })
  end

  def client_class
    if use_local?
      LocalClient
    else
      MediumClient
    end
  end

  def use_local?
    ENV.fetch("USE_LOCAL", "false") == "true"
  end
end
