(ns auto-ap.integration.util
  (:require [datomic.api :as dc]
            [auto-ap.datomic :refer [conn transact-schema install-functions]]
            [clj-time.core :as time]))

(defn wrap-setup
  [f]
  (with-redefs [auto-ap.datomic/uri "datomic:mem://test"]
    (dc/create-database auto-ap.datomic/uri)
    (with-redefs [auto-ap.datomic/conn (dc/connect auto-ap.datomic/uri)]
      (transact-schema conn)
      (install-functions)
      (f)
      (dc/delete-database auto-ap.datomic/uri))))

(defn admin-token []
  {:user      "TEST ADMIN"
   :exp       (time/plus (time/now) (time/days 1))
   :user/role "admin"
   :user/name "TEST ADMIN"})

(defn user-token
  ([] (user-token 1))
  ([client-id]
                  {:user         "TEST USER"
                   :exp          (time/plus (time/now) (time/days 1))
                   :user/role    "user"
                   :user/name    "TEST USER"
                   :user/clients [{:db/id client-id}]}))





(defn test-client [& kwargs]
  (apply assoc {:db/id "client-id"
                :client/code (str "CLIENT" (rand-int 100000))
                :client/locations ["DT"]}
         kwargs))

(defn test-vendor [& kwargs]
  (apply assoc {:db/id            "vendor-id"
                :vendor/name      "Vendorson"
                :vendor/default-account "test-account-id"}
         kwargs))

(defn test-bank-account [& kwargs]
  (apply assoc {:db/id       "bank-account-id"
                :bank-account/code (str "CLIENT-" (rand-int 100000))
                :bank-account/type :bank-account-type/check}
         kwargs))

(defn test-transaction [& kwargs]
  (apply assoc {:db/id "transaction-id"
                :transaction/date #inst "2022-01-01"
                :transaction/client "test-client-id"
                :transaction/bank-account "test-bank-account-id"
                :transaction/id (str (java.util.UUID/randomUUID))
                :transaction/amount 100.0
                :transaction/description-original "original description"} kwargs))

(defn test-payment [& kwargs]
  (apply assoc {:db/id          "test-payment-id"
                :payment/date   #inst "2022-01-01"
                :payment/client "test-client-id"
                :payment/bank-account "test-bank-account-id"
                :payment/type :payment-type/check
                :payment/vendor "test-vendor-id"
                :payment/amount 100.0}
         kwargs))

(defn test-invoice [& kwargs]
  (apply assoc {:db/id                "test-invoice-id"
                :invoice/date         #inst "2022-01-01"
                :invoice/client       "test-client-id"
                :invoice/status :invoice-status/unpaid
                :invoice/import-status :import-status/imported
                :invoice/total         100.0
                :invoice/outstanding-balance 100.00
                :invoice/vendor "test-vendor-id"
                :invoice/invoice-number (str "INVOICE " (rand-int 1000000))
                :invoice/expense-accounts       [{:invoice-expense-account/account "test-account-id"
                                                  :invoice-expense-account/amount 100.0
                                                  :invoice-expense-account/location "DT"}]}
         kwargs))

(defn test-account [& kwargs]
  (apply assoc {:db/id                            "account-id"
                :account/name "Account"
                :account/type :account-type/asset}
         kwargs))

(defn test-transaction-rule [& kwargs]
  (apply assoc {:db/id        "test-transaction-rule-id"
                :transaction-rule/client "test-client-id"
                :transaction-rule/transaction-approval-status :transaction-approval-status/approved
                :transaction-rule/note "Test"}
         kwargs))

(defn dissoc-id [x]
  (dissoc x :id))

(defn setup-test-data [data]
  (:tempids @(dc/transact conn (into data
                                    [(test-account :db/id "test-account-id")
                                     (test-client :db/id "test-client-id"
                                                  :client/bank-accounts [(test-bank-account :db/id "test-bank-account-id")])
                                     (test-vendor :db/id "test-vendor-id")
                                     {:db/id                "accounts-payable-id"
                                      :account/name         "Accounts Payable"
                                      :db/ident             :account/accounts-payable
                                      :account/numeric-code 21000
                                      :account/account-set  "default"}]))))

(defn apply-tx [data]
  (:db-after @(dc/transact conn data)))
