(ns auto-ap.import.yodlee2
  (:require [auto-ap.datomic :refer [conn random-tempid]]
            [auto-ap.import.common :refer [wrap-integration]]
            [auto-ap.import.transactions :as t]
            [auto-ap.logging :as alog]
            [auto-ap.time :as atime]
            [auto-ap.utils :refer [allow-once]]
            [auto-ap.yodlee.core2 :as client2]
            [clj-time.coerce :as coerce]
            [clojure.string :as str]
            [com.unbounce.dogstatsd.core :as statsd]
            [datomic.api :as dc]
            [digest :as di]))

#_{:clj-kondo/ignore [:unresolved-var]}
(defn yodlee->transaction [transaction use-date-instead-of-post-date?]
  (let [{post-date :postDate
         account-id :accountId
         date :date
         id :id
         {amount :amount} :amount
         {description-original :original
          description-simple :simple} :description
         base-type :baseType
         type :type
         status :status} transaction
        amount (if (= "DEBIT" base-type)
                 (-  amount)
                 amount)
        date (atime/parse date "YYYY-MM-dd")]
    #:transaction
     {:post-date (coerce/to-date (atime/parse post-date "YYYY-MM-dd"))
      :id (di/sha-256 (str id))
      :db/id (random-tempid)
      :raw-id (str id)
      :account-id account-id
      :date (if use-date-instead-of-post-date?
              (coerce/to-date (atime/parse post-date "YYYY-MM-dd"))
              (coerce/to-date date))
      :amount (double amount)
      :description-original (some-> description-original (str/replace #"\s+" " "))
      :description-simple (some-> description-simple (str/replace #"\s+" " "))
      :type type
      :status status}))

(defn import-yodlee2-int []
  (statsd/event {:title    "Yodlee2 import started"
                 :text     "Starting"
                 :priority :low}
                nil)
  (alog/info ::starting-yodlee-import)
  (let [import-batch (t/start-import-batch :import-source/yodlee2 "Automated yodlee2 user")]
    (try
      (let [account-lookup (dc/q '[:find ?ya ?ba ?cd ?ud ?y
                                   :in $
                                   :where
                                   [?ba :bank-account/yodlee-account ?y]
                                   [(get-else $ ?ba :bank-account/use-date-instead-of-post-date? false) ?ud]
                                   [?c :client/bank-accounts ?ba]
                                   [?c :client/code ?cd]
                                   [?y :yodlee-account/id ?ya]]
                                 (dc/db conn))]
        (doseq [[yodlee-account bank-account client-code use-date-instead-of-post-date?] account-lookup
                :let [_ (alog/info ::getting-transactions-for :code client-code)]
                transaction                                                              (wrap-integration #(client2/get-specific-transactions client-code yodlee-account)
                                                                                                           bank-account)]

          (alog/info ::importing-single-transaction)
          (t/import-transaction! import-batch (assoc (yodlee->transaction transaction use-date-instead-of-post-date?)
                                                     :transaction/bank-account bank-account
                                                     :transaction/client [:client/code client-code])))

        (alog/info ::finished-import)
        (t/finish! import-batch)
        (doseq [[_ bank-account _ _ ya] account-lookup]
          (try 
            @(dc/transact auto-ap.datomic/conn
                         [{:db/id ya
                           :yodlee-account/pending-balance (t/get-pending-balance import-batch bank-account)}])
            (catch Exception e
              (alog/error ::cant-persist-yodlee-account-pending-balance
                          :error e)))))
      (statsd/event {:title    "Yodlee2 import Finished"
                     :text     (pr-str (t/get-stats import-batch))
                     :priority :low}
                    nil)

      (catch Exception e
        (alog/error ::failed-import :error e)
        (t/fail! import-batch e)
        (statsd/event {:title      "Yodlee2 import failed"
                       :text       (str e)
                       :alert-type :warning
                       :priority   :normal}
                      nil)
        (Thread/sleep 10000)))))


(def import-yodlee2 (allow-once import-yodlee2-int))
