(ns auto-ap.views.pages.admin.accounts
  (:require [auto-ap.forms :as forms]
            [auto-ap.subs :as subs]
            [auto-ap.utils :refer [replace-by]]
            [auto-ap.views.components.admin.side-bar :refer [admin-side-bar]]
            [auto-ap.views.pages.admin.accounts.side-bar :as side-bar]
            [auto-ap.views.utils :refer [dispatch-event action-cell-width]]
            [auto-ap.views.components.layouts
             :refer
             [appearing-side-bar side-bar-layout]]
            [auto-ap.views.pages.admin.accounts.form :as account-form]
            [re-frame.core :as re-frame]
            [auto-ap.views.components.grid :as grid]
            [auto-ap.status :as status]
            [auto-ap.views.components.buttons :as buttons]
            [reagent.core :as reagent]
            [clojure.string :as str]
            [vimsical.re-frame.fx.track :as track]))

(re-frame/reg-event-db
 ::edit-completed
 (fn [db [_ edit-account]]
   (-> db
       (update :accounts replace-by :id  (assoc  edit-account :class "live-added")))))
(re-frame/reg-event-db
 ::table-params-changed
 (fn [db [_ p]]
   (assoc db ::table-params p)))

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

(re-frame/reg-sub
 ::table-params
 (fn [db]
   (-> db ::table-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
 ::unmounted
 (fn [{:keys [db]} _]
   {:db (dissoc db ::table-params ::side-bar/filter-params)
    ::track/dispose {:id ::params}}))

(re-frame/reg-event-fx
 ::mounted
 (fn  [{:keys [db]} _]
   {::track/register {:id ::params
                      :subscription [::params]
                      :event-fn (fn [params] [::params-change params])}}))
(re-frame/reg-sub
 ::account-page
 :<- [::params]
 :<- [::subs/all-accounts]
 (fn [[params all-accounts]]
   (let [matching-accounts (cond->> all-accounts
                            (:name-like params) (filter #(str/includes? (str/lower-case (or (:name %) ""))
                                                                        (str/lower-case (:name-like params))))
                            (not-empty  (:code-like params)) (filter #(str/starts-with? (str (or (:numeric-code %) ""))
                                                                        (str/lower-case (:code-like params)))))]
     (assoc (grid/virtual-paginate-controls (:start params ) (:per-page params) matching-accounts)
            :data (grid/virtual-paginate (:start params)
                                         (:per-page params)
                                         (sort-by :numeric-code matching-accounts))))))

(defn accounts-table [{:keys [accounts]}]
  (let [status @(re-frame/subscribe [::status/single ::page])
        opc (fn [p]
              (re-frame/dispatch [::table-params-changed p]))
        params @(re-frame/subscribe [::params])]

    [:div
     [grid/grid {:status status
                 :on-params-change opc
                 :params params
                 :column-count 5}
      [grid/controls accounts]
      [grid/table {:fullwidth true}
       [grid/header
        [grid/row {}
         [grid/header-cell {} "Code"]
         [grid/header-cell {} "Name"]
         [grid/header-cell {} "Type"]
         [grid/header-cell {} "Location"]
         [grid/header-cell {:style {:width (action-cell-width 1)}} ]]]
       [grid/body
        (for [{:keys [id numeric-code name type location class] :as account} (:data accounts)]
          ^{:key id}
          [grid/row {:class (:class account) :id id}
           [grid/cell {} numeric-code]
           [grid/cell {} name]
           [grid/cell {} type]
           [grid/cell {} location]
           [grid/cell {}
            [buttons/fa-icon {:event [::account-form/editing account [::edit-completed]]
                              :icon "fa-pencil"}]]])]]]]))

(defn admin-accounts-content []
  [:div
   [:h1.title "Accounts"]
   [:div.is-pulled-right
    [buttons/new-button {:name "Account"
                         :class "is-primary"
                         :event [::account-form/editing
                                 {:type :asset
                                  :account-set "default"}
                                 [::edit-completed]]}]]
   [accounts-table {:accounts @(re-frame/subscribe [::account-page])}]])

(defn admin-accounts-page []
  (reagent/create-class
   {:display-name "accounts-page"
    :component-will-unmount #(re-frame/dispatch [::unmounted])
    :component-did-mount #(re-frame/dispatch [::mounted])
    :reagent-render
    (fn []
      (let [{:keys [active?]} @(re-frame/subscribe [::forms/form ::account-form/form])]
        [side-bar-layout {:side-bar [admin-side-bar {}
                                     [side-bar/accounts-side-bar]]
                          :main [admin-accounts-content]
                          :right-side-bar [appearing-side-bar {:visible? active?} [account-form/form ]]}]))}))
