(ns auto-ap.yodlee.import)


;; This buffer is for Clojure experiments and evaluation.

;; Press C-j to evaluate the last expression.

;; You can also press C-u C-j to evaluate the expression and pretty-print its result.

(def t (auto-ap.yodlee.core/get-specific-transactions 24249175))
(def all-ts (auto-ap.yodlee.core/get-transactions))

(filter  all-ts)

(first all-ts)


(def g (auto-ap.yodlee.import/get-existing))
(first 
 (let [all-bank-accounts (auto-ap.yodlee.import/get-all-bank-accounts)
       transaction->bank-account (comp (by :bank-account/yodlee-account-id all-bank-accounts) :accountId)
       all-rules (tr/get-all)]
   (transactions->txs all-ts transaction->bank-account (rm/rule-applying-fn all-rules) (get-existing))))

(count g)
(with-open [writer (java.io.StringWriter.)]
  (clojure.data.csv/write-csv writer
                              (->> 
                               (let [all-bank-accounts (auto-ap.yodlee.import/get-all-bank-accounts)
                                     all-clients (by :db/id (d-clients/get-all))
                                     transaction->bank-account (comp (by :bank-account/yodlee-account-id all-bank-accounts) :accountId)
                                     all-bank-accounts (by :db/id all-bank-accounts)
                                     all-rules (tr/get-all)]
                                 (->> (transactions->txs all-ts transaction->bank-account (rm/rule-applying-fn all-rules) (get-existing))
                                      (map (fn [r]
                                             [(:transaction/id r) (:transaction/amount r)
                                              (coerce/to-date-time (:transaction/date r))
                                              (:transaction/description-original r)
                                              (:bank-account/code (all-bank-accounts (:transaction/bank-account r)))
                                              (:client/code (all-clients (:transaction/client r)))]))))))
  (println (.toString writer)))

(g (digest/sha-256 (str 2553824503)))

(require '[clojure.java.io :as io])


(with-open [writer (java.io.StringWriter.)]
  (clojure.data.csv/write-csv writer
                              (->> 
                               (d/query {:query {:find ['?e '?e2]
                                                 :in ['$]
                                                 :where ['[?e :transaction/id ?tid]
                                                         '[?e :transaction/date ?d]
                                                         '[?e :transaction/type]
                                                         '[?e :transaction/bank-account ?ba]
                                                         '[?e2 :transaction/date ?d]
                                                         '[(not= ?e2 ?e)]
                                                         '[?e :transaction/amount ?a1]
                                                         '[?e2 :transaction/amount ?a2]
                                                         '[?e2 :transaction/bank-account ?ba]
                                                         '[(auto-ap.utils/dollars= ?a1 ?a2)]
                                                         '(not [?e2 :transaction/type])]}
                                         :args [(d/since (d/db (d/connect uri)) #inst "2020-04-01")]})
                               vec
                               (map (fn [[e1 e2]]
                                      [
                                       (d/pull (d/db (d/connect uri))
                                               [:db/id
                                                :transaction/date :transaction/id :transaction/amount
                                                :transaction/description-original
                                                {:transaction/client [:client/code]}
                                                {:transaction/bank-account [:bank-account/code]}]
                                               e1)
                                       (d/pull (d/db (d/connect uri))
                                               [:db/id
                                                :transaction/date :transaction/id :transaction/amount
                                                :transaction/description-original
                                                {:transaction/client [:client/code]}
                                                {:transaction/bank-account [:bank-account/code]}]
                                               e2)
                                       ]))
                               
                               (map (fn [[r1 r2]]
                                      [(:transaction/id r1)
                                       (:db/id r1 )
                                       (:transaction/amount r1)
                                       (coerce/to-date-time (:transaction/date r1))
                                       (:transaction/description-original r1)
                                       (:bank-account/code (:transaction/bank-account r1))
                                       (:client/code (:transaction/client r1))

                                       (:transaction/id r2)
                                       (:db/id r2)
                                       (:transaction/amount r2)
                                       (coerce/to-date-time (:transaction/date r2))
                                       (:transaction/description-original r2)
                                       (:bank-account/code (:transaction/bank-account r2))
                                       (:client/code (:transaction/client r2))])))

                              )
  (println (.toString writer)))



(def matches-to-repair2
  (->> 
   (d/query {:query {:find ['?e '?e2]
                     :in ['$]
                     :where ['[?e :transaction/id ?tid]
                             '[?e :transaction/date ?d]
                             '[?e :transaction/type]
                             '[?e :transaction/bank-account ?ba]
                             '[?e2 :transaction/date ?d]
                             '[(not= ?e2 ?e)]
                             '[?e :transaction/amount ?a1]
                             '[?e2 :transaction/amount ?a2]
                             '[?e2 :transaction/bank-account ?ba]
                             '[(auto-ap.utils/dollars= ?a1 ?a2)]
                             '[?e2 :transaction/type]]}
             :args [(d/since (d/db (d/connect uri)) #inst "2020-04-01")]})
   vec
   (map (fn [[e1 e2]]
          [
           (d/pull (d/db (d/connect uri))
                   [:db/id
                    :transaction/date :transaction/id :transaction/amount
                    :transaction/description-original
                    :transaction/approval-status
                    :transaction/type
                    {:transaction/client [:client/code]}
                    {:transaction/bank-account [:bank-account/code]}
                    #_{:journal-entry/_original-entity ['*]}]
                   e1)
           (d/pull (d/db (d/connect uri))
                   [:db/id
                    :transaction/date :transaction/id :transaction/amount
                    :transaction/description-original
                    :transaction/type
                    :transaction/approval-status
                    {:transaction/client [:client/code]}
                    {:transaction/bank-account [:bank-account/code]}
                    #_{:journal-entry/_original-entity ['*]}]
                   e2)
           ]))
   ))

(count (filter #(= "SCSJ" (:client/code (:transaction/client (first %)))) matches-to-repair2))

(sha-256 (str "2020-05-08" "-" "SCSJ-USBMAIN2974" "-" "CHECK-5075" "-" "5000.0" "-"  "0" "-" "SCSJ"))

(defn repair-transaction [[t-auto t-manual]]
  (into 
   [{:db/id "datomic.tx"
     :db/doc "Deletes a transaction that was added manually and automatically"}
    [:db/retractEntity (:db/id t-auto)]]
   (mapv
    (fn [j]
      [:db/retractEntity (:db/id j)])
    (:journal-entry/_original-entity t-auto))))

(defn map-new-transaction-id [[t-auto t-manual]]
  [[:db/add (:db/id t-manual) :transaction/id (:transaction/id t-auto)]])

#_(map-new-transaction-id (first matches-to-repair))

#_(doseq [t matches-to-repair]
  @(d/transact (d/connect uri) (map-new-transaction-id t)))



#_(comment

  (get-accounts)

(get-provider-accounts)

(update-provider-account 18611904)

(get-provider-account-detail 11194727)

(get-specific-transactions 24370737)

[{"field" [
           {"id" "SQandA--QUESTION_1-12370368"
            "value" "Oprah"}

           {"id" "SQandA--QUESTION_1-12369757"
            "value" "Betelgeuse"}] }]

(perform-additional-authentication 18611904 {"loginForm" {"row"
                                                          [{"field" [{"id" "SQandA--txtAlphaNum--1"
                                                                       "value" "Christian"}]}]}})

{"field" [{"id" "SQandA--QUESTION_1-12370368"
           "value" "Oprah"}

          {"id" "SQandA--QUESTION_1-12369757"
           "value" "Betelgeuse"}]}

(json/write-str )

*e


(get-provider-accounts-with-accounts)
(get-provider-account-detail 18611901)


@(d/transact (d/connect uri) (fix-transactions-without-locations "NGE1" "UC"))

(->> (d/query {:query {:find ['?e '?tx '?yai '?d]
                       :in ['$]
                       :where ['[?e :bank-account/yodlee-account-id ?yai ?tx true]
                               '[?tx :db/txInstant ?d]]}
               :args [(d/history (d/db (d/connect uri)))]})
     (filter (fn [[_ _ y]]
               (not= y 0)))
     (group-by first)
     (filter (fn [[k v]]
               (> (count v) 1)))

     (map (fn [[k vs]]
            (let [[yodlee-id & old] (->> vs
                                         (sort-by second)
                                         (map (fn [[_ _ yodlee-id date]]
                                                [yodlee-id date]))
                                         
                                         (reverse))]
              [k {:new-yodlee-id yodlee-id
                  :defunct-yodlee-ids (clojure.set/difference (set old) #{yodlee-id})}])))

     (mapv (fn [[bank-account history]]
             (d/query {:query {:find '[?t] #_['(pull $2 ?t [*]) '(pull $2 ?t2 [*])]
                               :in ['$ '$2 '?bank-account '?before]
                               :where ['[?t :transaction/bank-account ?bank-account]
                                       '[?t :transaction/date ?date]
                                       '[?t :transaction/amount ?tx-amount ?tx true]
                                       '[?tx :db/txInstant ?tx-date]
                                       '[(< ?tx-date ?before)]
                                       '[?t2 :transaction/bank-account ?bank-account]
                                       '[?t2 :transaction/amount ?tx-amount2 ?tx2 true]
                                       '[?tx2 :db/txInstant ?tx2-date]
                                       '[?t2 :transaction/date ?date]
                                       '[(auto-ap.utils/dollars= ?tx-amount ?tx-amount2)]
                                       '[(not= ?t ?t2)]
                                       '[(> ?tx2-date ?before)]
                                       ]}
                       :args [(d/history (d/db (d/connect uri))) (d/db (d/connect uri)) bank-account (second (:new-yodlee-id history))]})))
     
     )


20186866  24265567 24370736
(auto-ap.yodlee.core/get-specific-transactions 24265567)


(def bad-account-ids (->> (d/query {:query {:find ['?e '?tx '?yai '?d]
                                            :in ['$]
                                            :where ['[?e :bank-account/yodlee-account-id ?yai ?tx true]
                                                    '[?tx :db/txInstant ?d]]}
                                    :args [(d/history (d/db (d/connect uri)))]})
                          (filter (fn [[_ _ y]]
                                    (not= y 0)))
                          (group-by first)
                          (filter (fn [[k v]]
                                    (> (count v) 1)))
                          (keys)))

(count 
 (->> (d/query {:query {:find ['?bank-account '?date '?tx-amount '?tx-account]
                        :in ['$]
                        :where ['[?t :transaction/client [:client/code "NGO"]]
                                '[?t :transaction/bank-account ?bank-account]
                                '[?t :transaction/date ?date]
                                '[?t :transaction/amount ?tx-amount ]
                                '[?t :transaction/account-id ?tx-account ]
                                ]}
                :args [(d/db (d/connect uri))]})
      (group-by (fn [[ba date amount _]]
                  [ba date amount]))
      (mapv (fn [[k v]]
              [k (set (map last v))]))
      (filter (fn [[k v]]
                (> (count v) 1)))))

;; FINDS TRANSACTIONS THAT COME FROM DIFFERENT YODLEE IDS

(reduce 
 (fn [acc [k v]]
   (update acc k conj v)
   )
 {}
 (mapcat (fn [ba]
           (->> (d/query {:query {:find ['?code '?date '?tx-amount '?t '?tx-account ]
                                  :in ['$ '?bank-account]
                                  :where ['[?t :transaction/bank-account ?bank-account]
                                          '[?bank-account :bank-account/code ?code]
                                          '[?t :transaction/date ?date]
                                          '[?t :transaction/amount ?tx-amount ]
                                          '[?t :transaction/account-id ?tx-account ]
                                          '[(>= ?date #inst "2020-01-01")]
                                          ]}
                          :args [(d/db (d/connect uri) ) ba]})
                (group-by (fn [[ba date amount _]]
                            [ba date amount]))
                (filter (fn [[k v]]
                          (> (count (set (map last v))) 1)))
                (map second)
                (mapcat identity)
                (map (fn [[ba _ _ id act]]
                       [[ba act] id]))
                
                #_(map (fn [[_ []]]))
                #_(mapv (fn [[k v]]
                          [k (reduce
                              (fn [acc [_ _ _ act id]]
                                (assoc acc act id ))
                              {}
                              v)]))
                
                #_(map second)
                ))
         bad-account-ids))

;; delete
(->> (d/pull-many (d/db (d/connect uri)) '[:db/id {:journal-entry/_original-entity [:db/id]}] '(17592232564344))
     (mapcat (fn [x]
               [[:db/retractEntity (:db/id x)]
                [:db/retractEntity (:db/id (first (:journal-entry/_original-entity x)))]]))
     (d/transact (d/connect uri) )
     deref))
