(ns auto-ap.views.components.layouts
  (:require
   [reagent.core :as reagent]
   [re-frame.core :as re-frame]
   [bidi.bidi :as bidi]
   [auto-ap.routes :as routes]
   [auto-ap.subs :as subs]
   [auto-ap.events :as events]
   [auto-ap.views.utils :refer [active-when active-when= login-url dispatch-event appearing css-transition-group bind-field]]
   [auto-ap.views.components.modal :as modal]
   [auto-ap.entities.vendors :as vendor]
   [clojure.string :as str]
   [reagent.core :as r]
   [auto-ap.views.components.vendor-dialog :as vendor-dialog]
   [auto-ap.views.components.buttons :as buttons]))


(defn navbar-drop-down-contents [{:keys [id]} children ]
  (let [toggle-fn (fn [] (re-frame/dispatch [::events/toggle-menu id]))]
    (reagent/create-class {:component-did-mount (fn [] (.addEventListener js/document "click" toggle-fn))
                           :component-will-unmount (fn [] (.removeEventListener js/document "click" toggle-fn))
                           :reagent-render
                           (fn [children]
                             children)})))

(defn navbar-drop-down [{:keys [ header id class]} child]
  (let [menu-active? (re-frame/subscribe [::subs/menu-active? id])]
    (reagent/create-class
     {:reagent-render (fn [{:keys [header id]} child]
                        (let [menu-active? @(re-frame/subscribe [::subs/menu-active? id])]
                          [:div { :class (str "navbar-item has-dropdown " (when menu-active? "is-active " ) " " class)}
                           [:a {:class "navbar-link login" :on-click (fn [e]
                                                                       (.preventDefault e)
                                                                       (.stopPropagation e)
                                                                       (re-frame/dispatch [::events/toggle-menu id])
                                                                       true)} header]
                           [appearing {:visible? menu-active? :enter-class "appear" :exit-class "disappear" :timeout 200}
                            [:div {:class "navbar-dropdown"}
                             [navbar-drop-down-contents {:id id}
                              [:div child]]]]]))})))

(defn login-dropdown []
  (let [user (re-frame/subscribe [::subs/user])
        menu (re-frame/subscribe [::subs/menu])]
    (if @user
      [navbar-drop-down {:header [:span [:span.icon [:i.fa.fa-user] ]
                                  [:span (:user/name @user)]] :id ::account}
       [:div
        [:a {:class "navbar-item"} "My profile"]
        (when (= "admin" (:user/role @user))
          [:a {:class "navbar-item" :href (bidi/path-for routes/routes :admin)} "Administration"])
        [:hr {:class "navbar-divider"}]
        [:a.navbar-item {:on-click (fn [e] (.preventDefault e) (re-frame/dispatch [::events/logout]))} "Logout"]]] 
      [:a.navbar-item {:href login-url} "Login"])))

(re-frame/reg-sub
 ::client-search
 (fn [db]
   (::client-search db)))

(re-frame/reg-sub
 ::matching-clients
 :<- [::subs/clients]
 :<- [::client-search]
 (fn [[clients {client-search :value}]]
   (if (empty? client-search) 
     clients
     (if-let [exact-match (first (filter
                                  (fn [client]
                                    (= (str/lower-case (:code client)) (str/lower-case client-search)))
                                  clients))]
       [exact-match]
       (filter
        (fn [client]
          (or 
           (str/includes? (str/lower-case (:code client)) (str/lower-case client-search))
           (str/includes? (str/lower-case (:name client)) (str/lower-case client-search))))
        clients)))))

(re-frame/reg-event-db
 ::client-search-changed
 [(re-frame/path [::client-search])]
 (fn [client-search [_ path value]]
   (assoc-in client-search path value)))

(defn navbar [ap]
  (let [navbar-menu-shown? (r/atom false)]
    (fn [ap]
      (let [user (re-frame/subscribe [::subs/user])
            client (re-frame/subscribe [::subs/client])
            clients (re-frame/subscribe [::subs/clients])
            matching-clients @(re-frame/subscribe [::matching-clients])
            menu (re-frame/subscribe [::subs/menu])
            client-search @(re-frame/subscribe [::client-search])
            is-initial-loading @(re-frame/subscribe [::subs/is-initial-loading?])]
        [:nav {:class "navbar has-shadow is-fixed-top is-grey"}
         
         [:div {:class "container"}
          [:div {:class "navbar-brand"}
           [:a {:class "navbar-item", :href "../"}
            [:img {:src "/img/logo.png"}]]
           [:div {:class "navbar-burger burger", :data-target "navMenu" :on-click (fn [] (swap! navbar-menu-shown? #(not %)))}
            [:span]
            [:span]
            [:span]]]
          [:div.navbar-menu {:id "navMenu" :class (if @navbar-menu-shown?
                                                    "is-active"
                                                    "")}
           (when-not is-initial-loading 
             [:div.navbar-start
              [:a.navbar-item {:class [(active-when ap = :index)]
                               :href (bidi/path-for routes/routes :index)}
               "Home" ]
              [:a.navbar-item {:class [(active-when ap #{:unpaid-invoices :paid-invoices})]
                               :href (bidi/path-for routes/routes :unpaid-invoices)}
               "Invoices" ]
              [:a.navbar-item {:class [(active-when ap = :payments)]
                               :href (bidi/path-for routes/routes :payments)}
               "Payments" ]
              (when (= "admin" (:user/role @user))
                [:a.navbar-item {:class [(active-when ap = :sales-orders)]
                                 :href (bidi/path-for routes/routes :sales-orders)}
                 "POS" ])
              [:a.navbar-item {:class [(active-when ap = :transactions)]
                               :href (bidi/path-for routes/routes :transactions)}
               "Transactions" ]
              
              (when (not= "manager" (:user/role @user))
                [:a.navbar-item {:class [(active-when ap = :ledger)]
                                 :href (bidi/path-for routes/routes :ledger)}
                 "Ledger" ])])
           
           (when-not is-initial-loading
             [:div.navbar-end
              [:div.navbar-item
               [buttons/new-button {:event [::vendor-dialog/started {}]
                                    :name "Vendor"
                                    :class "is-primary"}]]
              

              (when (> (count @clients) 1)
                [navbar-drop-down {:header (str "Company: " (if @client (:name @client)
                                                                "All"))
                                   :id ::select-client}
                 [:div
                  [:a {:class "navbar-item"
                       :on-click (fn []
                                   (re-frame/dispatch [::events/swap-client nil]))} "All" ]
                  [:hr {:class "navbar-divider"}]
                  [bind-field 
                   [:input.input.navbar-item {:placeholder "Company name"
                                              :auto-focus true
                                              :field [:value]
                                              :on-key-up (fn [k]
                                                           (when (= 13 (.-which k))
                                                             (do 
                                                               (re-frame/dispatch [::events/swap-client (first matching-clients)])
                                                               (re-frame/dispatch [::events/toggle-menu ::select-client])
                                                               (re-frame/dispatch [::client-search-changed [:value] nil])))
                                                           )
                                              :event [::client-search-changed]
                                              :subscription client-search}]]
                  (for [{:keys [name id] :as client} matching-clients]
                    ^{:key id }
                    [:a {:class "navbar-item"
                         :on-click (fn []
                                     (re-frame/dispatch [::events/swap-client client]))
                         } name])]])])]
          (when-not is-initial-loading
            [login-dropdown])]
         
         
         ]))))


(defn footer []
  [:footer {:style {:padding "1em"}}
   [:div {:class "content has-text-centered"}
    [:p  
     [:strong "Integreat"] ]]])

(defn appearing-side-bar [{:keys [visible?]} ]
  [appearing {:visible? visible? :enter-class "slide-in-right" :exit-class "slide-out-right" :timeout 500}
   [:aside  {:class "column is-4 aside menu" :style {:height "calc(100vh - 46px)" :overflow "auto"}}
    (into [:div.sub-main {} ]
          (r/children (r/current-component)))]])

(defn side-bar-layout [{:keys [side-bar main ap bottom right-side-bar]}]
  (let [ap @(re-frame/subscribe [::subs/active-page])
        client @(re-frame/subscribe [::subs/client])
        is-initial-loading @(re-frame/subscribe [::subs/is-initial-loading?])]
    [:div 
     [modal/global-modal]
     [navbar ap]
     [:div {:class "columns has-shadow", :style {:margin-bottom "0px" :height "calc(100vh - 46px)" } :id "mail-app" }
      [:aside {:class "column aside menu is-2 " }
       [:div.main.left-nav 
        [:div side-bar
         ]]]
      [:div {:class "column messages hero " :style { :overflow "auto" }, :id "message-feed"}
       ^{:key (str "active-page-" (:name client))}
       [:div.inbox-messages
        (when-let [error  @(re-frame/subscribe [::subs/page-failure])]
          [:div.notification.is-warning.animated.fadeInUp
           error])
        main]]
      (when right-side-bar
        right-side-bar)
      ]
     #_[footer]
     [:div 
      bottom]
     [:div#dz-hidden]]))


(defn side-bar [{:keys [on-close]} children]
  [:div [:a.delete.is-pulled-right {:on-click on-close}] [:div children]])

(defn loading-layout []
  [side-bar-layout 
   {:main [:div.has-text-centered.hero.is-fullheight.is-vertically-centered.is-centered 
           [:div.hero-body
            [:div.container 
             [:div.column.is-4.is-offset-4.has-text-centered
              [:div.loader.is-loading.is-active.big.is-centered]]]]]}])

