(ns auto-ap.graphql.expected-deposit
  (:require
   [auto-ap.datomic.expected-deposit :as d-expected-deposit]
   [auto-ap.graphql.utils
    :refer [->graphql <-graphql assert-admin ident->enum-f result->page]]
   [com.walmartlabs.lacinia.util :refer [attach-resolvers]]
   [auto-ap.graphql.utils :refer [attach-tracing-resolvers]]))

(def status->graphql (ident->enum-f :expected-deposit/status))

(defn get-all-expected-deposits [context args _]
  (assert-admin (:id context))
  (map
    (comp ->graphql status->graphql)
   (first (d-expected-deposit/get-graphql (assoc (<-graphql args) :count Integer/MAX_VALUE)))))

(defn get-expected-deposit-page [context args _]
  (let [args (assoc args :clients (:clients context))
        [expected-deposits expected-deposit-count] (d-expected-deposit/get-graphql  (<-graphql args))
        expected-deposits (map status->graphql expected-deposits)]

    (result->page expected-deposits expected-deposit-count :expected_deposits args)))

(def objects
  {:expected_deposit_total {:fields {:date   {:type :iso_date}
                                     :count  {:type 'Int}
                                     :amount {:type :money}}}
   :expected_deposit       {:fields {:id          {:type :id}
                                     :location    {:type 'String}
                                     :external_id {:type 'String}
                                     :total       {:type :money}
                                     :transaction {:type :transaction}
                                     :status      {:type :expected_deposit_status}
                                     :fee         {:type :money}
                                     :client      {:type :client}
                                     :date        {:type 'String}
                                     :totals      {:type '(list :expected_deposit_total)}}}

   :expected_deposit_page {:fields {:expected_deposits {:type '(list :expected_deposit)}
                                    :count             {:type 'Int}
                                    :total             {:type 'Int}
                                    :start             {:type 'Int}
                                    :end               {:type 'Int}}}})

(def queries
  {:expected_deposit_page {:type :expected_deposit_page
                           :args {:client_id      {:type :id}
                                  :exact_match_id {:type :id}
                                  :date_range     {:type :date_range}
                                  :total_lte      {:type :money}
                                  :total_gte      {:type :money}
                                  :start          {:type 'Int}
                                  :per_page       {:type 'Int}
                                  :sort           {:type '(list :sort_item)}}

                           :resolve :get-expected-deposit-page}
   :all_expected_deposits {:type    '(list :expected_deposit)
                           :args    {:client_id   {:type :id}
                                     :client_code {:type 'String}}
                           :resolve :get-all-expected-deposits}})

(def enums
  {:expected_deposit_status {:values [{:enum-value :cleared}
                                      {:enum-value :pending}]}})

(def resolvers
  {:get-all-expected-deposits get-all-expected-deposits
   :get-expected-deposit-page get-expected-deposit-page})

(defn attach [schema]
  (->
   (merge-with merge schema
               {:objects       objects
                :queries       queries
                :enums         enums})
   (attach-tracing-resolvers resolvers)))
