defmodule ApiWeb.StudyController do
  use ApiWeb, :controller
  alias Api.Study
  alias Api.Repo
  require Logger

  # Manejar solicitudes GET con hash no encriptado
  def index(conn, %{"fromportal" => "true"}) do
    conn
    |> send_resp(404, "Estudio no encontrado.")
  end

  # Acción para manejar solicitudes GET con un hash encriptado
  def index(conn, params) do
    hash = params["hash"]
    Logger.info("Hash ----> #{inspect(hash)}")

    results = if String.length(hash) > 50 do
      case Base.decode64(hash) do
        {:ok, decoded_hash} ->
          query = """
          SELECT convert_from(decrypt(concat('#{decoded_hash}')::bytea, '1nf0rm3', 'aes'), 'UTF8')::text
          """

          decrypted_data = Repo.query!(query).rows |> hd() |> hd()
          Logger.info("decrypted ---> #{inspect(decrypted_data)}")

          case Jason.decode(decrypted_data) do
            {:ok, json} ->
              # Convertir las claves del JSON a átomos
              json_with_atoms = Enum.into(json, %{}, fn {k, v} -> {String.to_atom(k), v} end)

              # Verificar si la fecha actual es antes de la fecha de vencimiento
              case DateTime.from_iso8601(json_with_atoms[:vencimiento]) do
                {:ok, vencimiento, _} ->
                  if DateTime.compare(DateTime.utc_now(), vencimiento) == :lt do
                    get_study(json_with_atoms)
                  else
                    %{error: "El enlace ha expirado"}
                  end
                {:error, _} ->
                  %{error: "Formato de fecha inválido"}
              end
            {:error, _} ->
              %{error: "Datos desencriptados inválidos"}
          end

        :error ->
          %{error: "Error al decodear Base64"}
      end
    else
      query = """
        SELECT convert_from(decrypt(concat('\\x', '#{hash}')::bytea, 'gea', 'aes'), 'UTF8')::integer;
      """
      decrypted_data = Repo.query!(query).rows |> hd() |> hd()
      Logger.info("decrypted hash viejo ---> #{inspect(decrypted_data)}")
      study = Study.open_study(decrypted_data)
      Logger.info("#{inspect(study)}")
      study
    end

    json(conn, results)
  end

  # Función privada para obtener el estudio usando el número de acceso
  defp get_study(json_study) do
    # Determinar si usar idstudy o accessionnumber
    Envar.load(".env")
    Envar.require_env_file(".env")

    Logger.info("get study -------> #{inspect(Envar.get("IDENTIFIERFIELD"))}")
    value_to_use = if Envar.get("IDENTIFIERFIELD") == "ACCESSIONNUMBER" do

      Logger.debug("Usando clave :accession con valor #{inspect(json_study[:accessionnumber])}")
      json_study[:accessionnumber]
    else
      Logger.debug("Usando clave :idstudy con valor #{inspect(json_study[:idstudy])}")
      json_study[:idstudy]
    end

    # key_to_use =
    #   cond do
    #     json_study[:idstudy] -> :idstudy
    #     json_study[:accessionnumber] -> :accessionnumber
    #     true ->
    #       Logger.error("No se encontró idstudy ni accessionnumber en el JSON: #{inspect(json_study)}")
    #       raise ArgumentError, "Faltan parámetros: idstudy o accessionnumber"
    #   end

    # Paso 5: Obtener el estudio usando el valor correspondiente
    array_study = Study.open_study(value_to_use)
    Logger.info("#{inspect(array_study)}")
    array_study
  end

end
