(ns auto-ap.graphql.import-batch
  (:require
   [auto-ap.datomic
    :refer [add-sorter-fields
            apply-pagination
            apply-sort-3
            conn
            merge-query
            pull-many-by-id
            query2]]
   [auto-ap.graphql.utils
    :refer [<-graphql
            assert-admin
            attach-tracing-resolvers
            ident->enum-f
            result->page]]
   [clj-time.coerce :as coerce]
   [datomic.api :as dc]))

(def default-read '[:db/id
                    :import-batch/external-id
                    :import-batch/date
                    :import-batch/imported
                    :import-batch/suppressed
                    :import-batch/extant
                    :import-batch/user-name
                    {:import-batch/source [:db/ident]}
                    {:import-batch/status [:db/ident]}])

(defn raw-graphql-ids [db args]
  (let [query (cond-> {:query {:find []
                               :in ['$]
                               :where []}
                       :args [db]}

                (:sort args) (add-sorter-fields {"date" ['[?e :import-batch/date ?sort-date]]}
                                                args)

                true
                (merge-query {:query {:find ['?e]
                                      :where ['[?e :import-batch/date]]}}))]

    
    (cond->> (query2 query)
      true (apply-sort-3 args)
      true (apply-pagination args))))

(defn graphql-results [ids db _]
  (let [results (pull-many-by-id db default-read ids)]
    (->> ids
         (map results))))

(defn get-graphql [args]
  (let [db (dc/db conn)
        {ids-to-retrieve :ids matching-count :count} (raw-graphql-ids db args)]
    [(graphql-results ids-to-retrieve db args)
     matching-count]))

(defn get-import-batch-page [context args _]
  (let [_ (assert-admin (:id context))
        args (assoc (:filters args) :id (:id context))
        [values matching-count] (get-graphql (<-graphql args))]
    (result->page (->> values
                       (map (ident->enum-f :import-batch/source))
                       (map (ident->enum-f :import-batch/status))
                       (map #(update % :import-batch/date coerce/to-date-time)))
                  matching-count :data args)))


(defn attach [schema]
  (-> 
   (merge-with merge schema
               {:objects {:import_batch {:fields {:user_name {:type 'String}
                                                  :id {:type :id}
                                                  :date {:type :iso_date_time}
                                                  :imported {:type 'Int}
                                                  :extant {:type 'Int}
                                                  :suppressed {:type 'Int}
                                                  :status {:type :import_batch_status}
                                                  :source {:type :import_batch_source}}}

                          :import_batch_page {:fields {:data {:type '(list :import_batch)}
                                                       :count {:type 'Int}
                                                       :total {:type 'Int}
                                                       :start {:type 'Int}
                                                       :end {:type 'Int}}}

}
                :queries {:import_batch_page {:type :import_batch_page
                                              :args {:filters {:type :import_batch_filters}}
                                              
                                              :resolve :get-import-batch-page}}
                :mutations {}
                :input-objects {:import_batch_filters {:fields {:start {:type 'Int}
                                                                :per_page {:type 'Int}
                                                                :sort {:type '(list :sort_item)}}}}
                :enums {:import_batch_status {:values [{:enum-value :started}
                                                       {:enum-value :completed}]}
                        :import_batch_source {:values [{:enum-value :intuit}
                                                       {:enum-value :yodlee}
                                                       {:enum-value :yodlee2}
                                                       {:enum-value :plaid}
                                                       {:enum-value :manual}]}}})
   (attach-tracing-resolvers {:get-import-batch-page get-import-batch-page})))
