(ns auto-ap.views.pages.admin.clients
  (:require
   [auto-ap.routes :as routes]
   [auto-ap.status :as status]
   [auto-ap.subs :as subs]
   [auto-ap.shared-views.admin.side-bar :refer [admin-side-bar]]
   [auto-ap.views.components.grid :as grid]
   [auto-ap.views.components.layouts :refer [side-bar-layout]]
   [auto-ap.views.pages.admin.clients.form :as form]
   [auto-ap.views.pages.admin.clients.side-bar :as side-bar]
   [auto-ap.views.pages.admin.clients.table :as table]
   [auto-ap.views.pages.page-stack :as page-stack]
   [auto-ap.views.utils :refer [with-user]]
   [bidi.bidi :as bidi]
   [clojure.string :as str]
   [re-frame.core :as re-frame]
   [vimsical.re-frame.fx.track :as track]))

(re-frame/reg-event-db
 ::received-intuit-bank-accounts
 (fn [db [_ result]]
   (assoc db ::subs/intuit-bank-accounts (:intuit-bank-accounts result))))

(re-frame/reg-event-fx
 ::mounted
 [with-user]
 (fn  [{:keys [user]} _]
   {::track/register {:id ::params
                      :subscription [::params]
                      :event-fn (fn [params] [::params-change params])}
    :graphql {:token user
              :query-obj {:venia/queries [[:intuit_bank_accounts [:external_id :id :name]]]}
              :owns-state {:single [::load-intuit-bank-accounts]}
              :on-success [::received-intuit-bank-accounts]} }))

(re-frame/reg-event-fx
 ::unmounted
 (fn [{:keys [db]} _]
   {:db (dissoc db ::table/params ::side-bar/filter-params)
    ::track/dispose {:id ::params}}))

(re-frame/reg-sub
 ::params
 :<- [::table/params]
 :<- [::side-bar/filter-params]
 (fn [[table-params filter-params]]
   (cond-> {}
     (seq filter-params) (merge filter-params)
     (seq table-params) (merge table-params))))

(re-frame/reg-event-fx
 ::params-change
 (fn [_ [_ params]]
   {:set-uri-params params}))

(re-frame/reg-sub
 ::page
 :<- [::params]
 :<- [::subs/clients]
 (fn [[params all-clients]]
   (let [matching-clients (cond->> all-clients
                            (not-empty (:name params)) (filter #(str/includes? (str/lower-case (or (:name %) ""))
                                                                               (str/lower-case (:name params))))
                            (not-empty (:code params)) (filter #(= (str/lower-case (or (:code %) ""))
                                                                   (str/lower-case (:code params)))))]
     (assoc (grid/virtual-paginate-controls (:start params ) (:per-page params) matching-clients)
            :data (grid/virtual-paginate (:start params) (:per-page params) matching-clients)))))

(def admin-clients-content 
  (with-meta
    (fn []
      [:div
       [page-stack/page-stack
        {:active @(re-frame/subscribe [::subs/active-route])
         :pages [{:key :admin-clients
                  :breadcrumb "Clients"
                  :content [:<>
                            [:div.is-pulled-right
                             [:a.button.is-primary.is-outlined {:href (bidi/path-for routes/routes :admin-specific-client :id "new")} "New client"]]
                            [table/clients-table {:page   @(re-frame/subscribe [::page])
                                                     :status @(re-frame/subscribe [::status/single ::page])}]]}

                 {:key        :admin-specific-client
                  :breadcrumb [:span [:a {:href (bidi/path-for routes/routes :admin-clients)}
                                      "Clients"]
                               " / "
                               (or (:name @(re-frame/subscribe [::form/client]))
                                   [:i "New client"])]
                  :content    [form/new-client-form]}
                 ]}]])
    {:component-did-mount    #(re-frame/dispatch [::mounted])
     :component-will-unmount #(re-frame/dispatch-sync [::unmounted])}))


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

