defmodule ZoeyscomputerWeb.GistController do
  use ZoeyscomputerWeb, :controller

  alias Zoeyscomputer.Gists
  alias Zoeyscomputer.Gists.Gist

  action_fallback ZoeyscomputerWeb.FallbackController

  def index(conn, _params) do
    gists = Gists.list_gists()
    IO.inspect(gists)
    render(conn, :index, gists: gists)
  end

  def create(conn, params) do
    gist_params = decode_params(params)

    with {:ok, %Gist{} = gist} <- Gists.create_gist(conn.assigns.current_user, gist_params) do
      conn
      |> put_status(:created)
      |> put_resp_header("location", ~p"/api/gists/#{gist}")
      |> render(:show, gist: gist)
    end
  end

  # Private function to handle param decoding
  defp decode_params(params) when is_map(params) do
    cond do
      # Handle regular JSON params
      Map.has_key?(params, "title") and
        Map.has_key?(params, "desc") and
        Map.has_key?(params, "code") and
          Map.has_key?(params, "language") ->
        params

      # Handle params wrapped in "gist" key
      Map.has_key?(params, "gist") ->
        params["gist"]

      # Handle string JSON that needs parsing
      Enum.any?(params, fn {k, _v} -> String.starts_with?(k, "{") end) ->
        params
        |> Map.keys()
        |> List.first()
        |> Jason.decode!()

      true ->
        params
    end
  end

  def show(conn, %{"id" => id}) do
    gist = Gists.get_gist!(id)
    render(conn, :show, gist: gist)
  end

  def update(conn, %{"id" => id, "gist" => gist_params}) do
    gist = Gists.get_gist!(id)

    with {:ok, %Gist{} = gist} <- Gists.update_gist(gist, gist_params) do
      render(conn, :show, gist: gist)
    end
  end

  def delete(conn, %{"id" => id}) do
    gist = Gists.get_gist!(id)

    with {:ok, %Gist{}} <- Gists.delete_gist(gist) do
      send_resp(conn, :no_content, "")
    end
  end
end
