(ns auto-ap.routes.yodlee2
  (:require
   [auto-ap.datomic :refer [conn pull-attr]]
   [auto-ap.datomic.clients :as d-clients]
   [auto-ap.graphql.utils :refer [assert-admin assert-can-see-client]]
   [auto-ap.routes.utils :refer [wrap-secure]]
   [auto-ap.yodlee.core2 :as yodlee]
   [auto-ap.logging :as alog]
   [config.core :refer [env]]
   [datomic.api :as dc]))

(defn fastlink [{:keys [query-params identity]}]
  (assert-can-see-client identity (pull-attr (dc/db conn) :db/id [:client/code (get query-params "client")]))
  
  (let [token (if-let [client-id (get query-params "client-id")]
                (-> client-id
                    Long/parseLong
                    d-clients/get-by-id
                    :client/code
                    (yodlee/get-access-token))
                (yodlee/get-access-token (get query-params "client")))]
    {:status  200 
     :headers {"Content-Type" "application/edn"}
     :body    (pr-str {:token token
                       :url   (:yodlee2-fastlink env)}) }))
(defn refresh-provider-accounts [{:keys [identity edn-params]}]
  (assert-admin identity)
  (alog/info ::refreshing :params edn-params)
  (try 
    (yodlee/refresh-provider-account (-> (:client-id edn-params)
                                         Long/parseLong
                                         d-clients/get-by-id
                                         :client/code)
                                     (:provider-account-id edn-params))
    {:status  200 
     :headers {"Content-Type" "application/edn"}
     :body    "{}" }
    (catch Exception e
      (alog/error ::error :error e)
      {:status  400
       :headers {"Content-Type" "application/edn"}
       :body    (pr-str {:message (.getMessage e)
                         :error   (.toString e)})})))

(defn get-provider-account-detail [{:keys               [identity]
                                    {:keys [client id]} :route-params}]
  (assert-admin identity)
  (alog/info ::looking-up
             :client client
             :id id)
  (try 
    
    {:status  200 
     :headers {"Content-Type" "application/edn"}
     :body    (pr-str (yodlee/get-provider-account-detail (-> client
                                                              Long/parseLong
                                                              d-clients/get-by-id
                                                              :client/code)
                                                          id))}
    (catch Exception e
      (alog/error ::error :error e)
      {:status  400
       :headers {"Content-Type" "application/edn"}
       :body    (pr-str {:message (.getMessage e)
                         :error   (.toString e)})})))
(defn reauthenticate [{:keys [identity] {:keys [id]} :route-params
                       data  :edn-params}]
  (assert-admin identity)
  (try
    {:status  200
     :headers {"Content-Type" "application/edn"}
     :body    (pr-str (yodlee/reauthenticate-and-recache
                        (-> (:client-id data)
                            Long/parseLong
                            d-clients/get-by-id
                            :client/code)
                        (Long/parseLong id)
                        (dissoc data :client-id )))}
    (catch Exception e
      (alog/error ::error :error e)
      {:status  500
       :headers {"Content-Type" "application/edn"}
       :body    (pr-str {:message (.getMessage e)
                         :error   (.toString e)})})))

(defn delete-provider-account [{:keys [edn-params identity]}]
  (assert-admin identity)
  (try 
    (yodlee/delete-provider-account (-> (:client-id edn-params)
                                        Long/parseLong
                                        d-clients/get-by-id
                                        :client/code)
                                    (:provider-account-id edn-params))
    {:status  200 
     :headers {"Content-Type" "application/edn"}
     :body    (pr-str {}) }
    (catch Exception e
      (alog/error ::error  :error e)
      {:status  400
       :headers {"Content-Type" "application/edn"}
       :body    (pr-str {:message (.getMessage e)
                         :error   (.toString e)})})))

(defn valid-for [handler & methods]
  (let [methods (into #{} methods)]
    (fn [request]
      (if (methods (:request-method request))
        (handler request)
        {:status 404}))))

(def routes {"api" {"/yodlee2" {"/fastlink"                              :fastlink
                                "/provider-accounts/refresh/"            :refresh-provider-accounts
                                ["/provider-accounts/" :client "/" :id ] :get-provider-account-detail
                                ["/reauthenticate/" :id ]                :reauthenticate
                                "/provider-accounts/delete/"             :delete-provider-account}}})
(def match->handler {:fastlink (-> fastlink wrap-secure (valid-for :get))
                     :refresh-provider-accounts (-> refresh-provider-accounts wrap-secure (valid-for :post))
                     :get-provider-account-detail (-> get-provider-account-detail wrap-secure (valid-for :get))
                     :reauthenticate (-> reauthenticate wrap-secure (valid-for :post))
                     :delete-provider-account (-> delete-provider-account wrap-secure (valid-for :post))} )
