(ns auto-ap.integration.routes.invoice-test
  (:require
   [auto-ap.datomic :refer [conn]]
   [auto-ap.datomic.clients :refer [rebuild-search-index]]
   [auto-ap.integration.util :refer [admin-token wrap-setup]]
   [auto-ap.routes.invoices :as sut]
   [clj-time.coerce :as coerce]
   [clojure.test :as t]
   [datomic.api :as dc]))

(t/use-fixtures :each wrap-setup)

(def user (admin-token))

(def client {:client/code      "ABC"
             :client/name      "ABC"
             :client/locations "MH"})

(def vendor {:vendor/name      "Sysco"
             :vendor/default-account "expense-account"})

(def expense-account {:db/id        "expense-account"
                      :account/type :account-type/expense
                      :account/name "Food"})

(defn invoice-count-for-client [c]
  (or 
    (first (first (dc/q '[:find (count ?i)
                         :in $ ?c
                         :where [?i :invoice/client ?c]]
                       (dc/db conn) c)))
    0))

(def invoice {:customer-identifier "ABC"
              :date                (coerce/to-date-time #inst "2021-01-01")
              :invoice-number      "123"
              :vendor-code         "Sysco"
              :total               "123.45"})

(t/deftest import-uploaded-invoices
  (t/testing "It should import one"
    @(dc/transact conn [client expense-account vendor])
    (rebuild-search-index)

    (t/is (= 0 (invoice-count-for-client [:client/code "ABC"])))
    (sut/import-uploaded-invoice user  [(assoc invoice :customer-identifier "ABC")])

    (t/is (= 1 (invoice-count-for-client [:client/code "ABC"]))))

  (t/testing "Should only import the same invoice once"
    (t/is (thrown? Exception (sut/import-uploaded-invoice user  [(assoc invoice :customer-identifier "ABC")])))
    
    
    (t/is (thrown? Exception (sut/import-uploaded-invoice user  [(assoc invoice
                                                                                   :customer-identifier "ABC"
                                                                                   :total "456.32")]))))

  (t/testing "Should override location"
    (sut/import-uploaded-invoice user [(assoc invoice
                                              :location-override "DE"
                                              :customer-identifier "ABC"
                                              :invoice-number "789")])
    (t/is (= #{["DE"]} (dc/q '[:find ?l
                              :where [?i :invoice/invoice-number "789"]
                              [?i :invoice/expense-accounts ?ea]
                              [?ea :invoice-expense-account/location ?l]]
                            (dc/db conn)))))

  (t/testing "Should code invoice"
    (let [{{:strs [my-default-account coded-vendor]} :tempids} @(dc/transact conn
                                                                            [{:vendor/name            "Coded"
                                                                              :db/id                  "coded-vendor"
                                                                              :vendor/terms           12
                                                                              :vendor/default-account "my-default-account"}
                                                                             {:db/id        "my-default-account"
                                                                              :account/name "My default-account"}])]
      (sut/import-uploaded-invoice user  [(assoc invoice
                                                            :invoice-number "456"
                                                            :customer-identifier "ABC"
                                                            :vendor-code "Coded")])
      (let [[[result]] (dc/q  '[:find (pull ?i [*])
                             :where [?i :invoice/invoice-number "456"]]
                           (dc/db conn))]
        (t/is (= coded-vendor (:db/id (:invoice/vendor result))))
        (t/is (= [my-default-account]
                 (map (comp :db/id :invoice-expense-account/account)  (:invoice/expense-accounts result))))
        (t/is (:invoice/due result))))))

