(ns auto-ap.views.pages.admin.yodlee
  (:require-macros [cljs.core.async.macros :refer [go]])
  (:require [re-frame.core :as re-frame]
            [reagent.core :as reagent]
            [clojure.string :as str]
            [auto-ap.subs :as subs]
            [auto-ap.events.admin.clients :as events]
            [auto-ap.entities.clients :as entity]
            [auto-ap.views.components.layouts :refer [side-bar-layout]]
            [auto-ap.views.components.admin.side-bar :refer [admin-side-bar]]
            [auto-ap.views.components.address :refer [address-field]]
            [auto-ap.views.utils :refer [login-url dispatch-event dispatch-value-change bind-field horizontal-field]]
            [auto-ap.views.components.modal :refer [action-modal]]
            [cljs.reader :as edn]
            [auto-ap.routes :as routes]
            [bidi.bidi :as bidi]))



(re-frame/reg-sub
 ::authentication
 (fn [db]
   (-> db ::yodlee :authentication)))

(re-frame/reg-sub
 ::loading?
 (fn [db]
   (-> db ::yodlee :loading?)))

(re-frame/reg-sub
 ::accounts
 (fn [db]
   (-> db ::yodlee :accounts)))

(re-frame/reg-sub
 ::accounts-loading?
 (fn [db]
   (-> db ::yodlee :accounts-loading?)))

(re-frame/reg-event-fx
 ::authenticate-with-yodlee
 (fn [{:keys [db]} _]
   {:db (assoc-in db [::yodlee :loading?] true)
    :http {:token (:user db)
           :method :get 
           :headers {"Content-Type" "application/edn"}
           :uri (str "/api/yodlee/fastlink")
           :on-success [::authenticated]
           :on-error [::save-error]}}))

(re-frame/reg-event-fx
 ::mounted
 (fn [{:keys [db]} _]
   {:db (assoc-in db [::yodlee] {:accounts-loading? true})
    :http {:token (:user db)
           :method :get 
           :headers {"Content-Type" "application/edn"}
           :uri (str "/api/yodlee/accounts")
           :on-success [::got-accounts]
           :on-error [::save-error]}}))

(re-frame/reg-event-fx
 ::kicked
 (fn [{:keys [db]} [_ id state]]
   {:db (update-in db [::yodlee :accounts]
                   (fn [as]
                     (map (fn [a]
                            (if (= (:id a) id)
                              (assoc a :status state)
                              a))
                          as)))}))


(re-frame/reg-event-fx
 ::kick
 (fn [{:keys [db]} [_ id]]
   {:db (update-in db [::yodlee :accounts]
                   (fn [as]
                     (map (fn [a]
                            (if (= (:id a) id)
                              (assoc a :status :kicking)
                              a))
                          as)))
    :http {:token (:user db)
           :method :post 
           :headers {"Content-Type" "application/edn"}
           :uri (str "/api/yodlee/accounts/" id)
           :on-success [::kicked id :kicked]
           :on-error [::kicked id :errored]}}))

(re-frame/reg-event-fx
 ::got-accounts
 (fn [{:keys [db]} [_ accounts]]
   {:db (-> db
            (assoc-in [::yodlee :accounts] accounts)
            (assoc-in [::yodlee :accounts-loading?] false))}))

(re-frame/reg-event-fx
 ::authenticated
 (fn [{:keys [db]} [_ authentication]]
   {:db (-> db
            (assoc-in [::yodlee :authentication] authentication)
            (assoc-in [::yodlee :loading?] false))}))



(defn yodlee-link-button []
  [:div
   (let [authentication @(re-frame/subscribe [::authentication])
         loading? @(re-frame/subscribe [::loading?])]
     
     (if authentication
       [:div
        "Authentication successful!"
        [:form {:action (:url authentication) :method "POST"}
         [:input {:type "hidden"
                  :name "rsession"
                  :value (:session authentication)}]
         [:input {:type "hidden"
                  :name "token"
                  :value (:token authentication)}]
         [:input {:type "hidden"
                  :name "app"
                  :value (:app authentication)}]

         [:input {:type "hidden"
                  :name "redirectReq"
                  :value "true"}]
         [:button.button.is-primary [:span [:span.icon [:i.fa.fa-external-link]] " Go to yodlee"]]]]
       
       [:button.button.is-primary {:class (if loading? "is-loading" "") :on-click (dispatch-event [::authenticate-with-yodlee])} "Authenticate with Yodlee"]))])

(defn yodlee-accounts-table []
  
  [:div
   [:table.table
    [:thead
     [:tr
      [:th "Account Name"]
      [:th "Account Number"]
      [:th "Yodlee Account Number"]
      [:th "Yodlee Last updated"]
      [:th "Yodlee Status"]
      [:th]]]

    (if @(re-frame/subscribe [::accounts-loading?])
      [:tr [:td {:col-span "6"} "Loading..."]
       ]
      (for [account @(re-frame/subscribe [::accounts])]
        ^{:key (:id account)} [:tr
         [:td (:accountName account)]
         [:td (:accountNumber account)]
         [:td (:id account)]
         [:td (str/join ", " (map :lastUpdated (:dataset account)))]
         [:td (str/join ", " (map :additionalStatus (:dataset account)))]
         [:td
          (cond (= (:status account) :kicking)
                [:button.button.is-success.is-loading {:disabled "disabled"}  "Kick."]

                (= (:status account) :kicked)
                [:button.button {:disabled "disabled"}  "In progress..."]

                (= (:status account) :errored)
                [:button.button.is-danger {:disabled "disabled"}  "Error."]

                :else
                [:button.button.is-success {:on-click (dispatch-event [::kick (:id account)] )} "Kick." ])]]))]])


(defn admin-yodlee-content []
  [(with-meta
     (fn []
       [:div
        [:h1.title "Yodlee"]
        
        [yodlee-accounts-table]
        [yodlee-link-button]])
     {:component-did-mount (fn []
                             (re-frame/dispatch [::mounted]))})])

(defn admin-yodlee-page []
  [side-bar-layout {:side-bar [admin-side-bar {}]
                    :main [admin-yodlee-content]}])
