defmodule Api.EmailToSendContext do

  require Logger
  import Ecto.Query, warn: false
  alias Api.Repo
  alias Api.Emailtosend
  alias Api.Pagination


  def mark_sent(idemailtosend, attrs)do
    from(e in Emailtosend, where: e.idemailtosend == ^idemailtosend)
    |> Repo.one
    |> Emailtosend.changeset(attrs)
    |> Repo.update()
  end

  defp list_emails({filter, sort}) do
    filter_conditions =
      Enum.reduce(filter, true, fn v, filter_conditions ->
        case v["field"] do
          "idstudy" ->
            dynamic([e], e.idstudy == ^v["value"] and ^filter_conditions)

          "patientemail" ->
            dynamic([e], ilike(e.patientemail, ^"#{v["value"]}%") and ^filter_conditions)

          "sent" ->
            dynamic([e], e.sent == ^v["value"] and ^filter_conditions)

          "hasreport" ->
            dynamic([e], e.hasreport == ^v["value"] and ^filter_conditions)

          "retries" ->
            dynamic([e], e.retries == ^v["value"] and ^filter_conditions)

          "errormsg" ->
            dynamic([e], ilike(e.errormsg, ^"#{v["value"]}%") and ^filter_conditions)

          "forcereprocess" ->
            dynamic([e], e.send == ^v["forcereprocess"] and ^filter_conditions)

          "sentdatetime" ->
            dynamic([e], e.send == ^v["sentdatetime"] and ^filter_conditions)

          "accessionnumber" ->
            dynamic([s], ilike(s.accessionnumber, ^"#{v["value"]}%") and ^filter_conditions)

          "errormsg" ->
            dynamic([p], ilike(p.patientname, ^"#{v["value"]}%") and ^filter_conditions)

          "errormsg" ->
            dynamic([p], ilike(p.patientid, ^"#{v["value"]}%") and ^filter_conditions)

          "errormsg" ->
            dynamic([s], ilike(s.studydate, ^"#{v["value"]}%") and ^filter_conditions)

          _ ->
          filter_conditions
        end
      end)

    sort_values =
      case sort do
        [] -> [desc: :idstudy]
        _ -> Enum.reduce(sort, [], fn v, acc ->
          IO.inspect(v)
          case v["field"] do
            "patientname" ->
              if v["dir"] == "asc" do
                [asc: dynamic([_,_,p], p.patientname)]
              else
                [desc: dynamic([_,_,p], p.patientname)]
              end
            "patientid" ->
              if v["dir"] == "asc" do
                [asc: dynamic([_,_,p], p.patientid)]
              else
                [desc: dynamic([_,_,p], p.patientid)]
              end
            "accessionnumber" ->
              if v["dir"] == "asc" do
                [asc: dynamic([_,s], s.accessionnumber)]
              else
                [desc: dynamic([_,s], s.accessionnumber)]
              end
            "studydate" ->
              if v["dir"] == "asc" do
                [asc: dynamic([_,s], s.studydate)]
              else
                [desc: dynamic([_,s], s.studydate)]
              end
            _ ->
              if v["dir"] == "asc" do
                Enum.concat( acc, asc: String.to_existing_atom(v["field"]))
              else
                Enum.concat( acc, desc: String.to_existing_atom(v["field"]))
              end
          end
        end)
      end
    queryable = from(
      e in Emailtosend,
      where: ^filter_conditions,
      join: s in "study", on: s.idstudy == e.idstudy,
      join: p in "patient", on: p.idpatient == s.idpatient,
      order_by: ^sort_values,
      select: %{
        idemailtosend: e.idemailtosend,
        idstudy: e.idstudy,
        patientemail: e.patientemail,
        sent: e.sent,
        hasreport: e.hasreport,
        retries: e.retries,
        errormsg: e.errormsg,
        forcereprocess: e.forcereprocess,
        sentdatetime: e.sentdatetime,
	      accessionnumber: s.accessionnumber,
	      patientname: p.patientname,
	      patientid: p.patientid,
        studydate: s.studydate
      }
      )

    queryable
  end

  def list_emails(:paged, params, page, per_page) do
    list_emails(params)
    |> Pagination.page(page, per_page: per_page)
  end

  def get_email_by_id(id) do
    from(e in Emailtosend, where: e.idemailtosend == ^id)
    |> Repo.one()
  end

  def update_emailtosend(attrs) do
    get_email_by_id(attrs["idemailtosend"])
    |> Emailtosend.changeset(attrs)
    |> Repo.update()
  end

  def get_next_email() do
      # one_day_ago = NaiveDateTime.utc_now() |> NaiveDateTime.add(-86400, :second)

      from(
        e in Emailtosend,
        join: s in "study", on: s.idstudy == e.idstudy,
        join: p in "patient", on: p.idpatient == s.idpatient,
        where:
               (
                e.patientemail != "notiene@notiene.com" and
                e.patientemail != "" and
                not is_nil(e.patientemail) and
                e.forcereprocess == true
               ) or
               (
                e.patientemail != "notiene@notiene.com" and
                e.patientemail != "" and
                not is_nil(e.patientemail) and
                e.hasreport == true and
                e.sent != true and
                e.retries < 10
               ),
              # and e.registered >= ^one_day_ago,
        limit: 1,
        select: %{
	         idemailtosend: e.idemailtosend,
           retries: e.retries,
	         idstudy: s.idstudy,
	         accessionnumber: s.accessionnumber,
	         patientemail: e.patientemail,
	         patientname: p.patientname,
	         patientid: p.patientid,
           studydate: s.studydate
        }
      )
    |> Repo.one()
    |> IO.inspect(label: "CONTEXTO")
  end

end
