(ns auto-ap.views.pages.admin.vendors
  (:require [re-frame.core :as re-frame]
            [reagent.core :as reagent]
            [clojure.string :as str]
            [auto-ap.views.components.buttons :as buttons]
            [auto-ap.views.pages.admin.vendors.side-bar :as side-bar]
            [auto-ap.subs :as subs]
            [auto-ap.events :as events]
            [auto-ap.forms :as forms]
            [auto-ap.utils :refer [by]]
            [auto-ap.entities.vendors :as entity]
            [auto-ap.views.components.address :refer [address-field]]
            [auto-ap.views.components.grid :as grid]             
            [auto-ap.views.components.admin.side-bar :refer [admin-side-bar]]
            [auto-ap.views.components.layouts :refer [side-bar-layout]]
            [clojure.spec.alpha :as s]
            [auto-ap.views.utils :refer [login-url dispatch-value-change dispatch-event bind-field horizontal-field action-cell-width]]
            [auto-ap.views.pages.admin.vendors.table :as table]
            [auto-ap.views.pages.admin.vendors.merge-dialog :as merge-dialog]
            [cljs.reader :as edn]
            [auto-ap.routes :as routes]
            [bidi.bidi :as bidi]
            [auto-ap.status :as status]
            [vimsical.re-frame.fx.track :as track]
            [auto-ap.effects.forward :as forward])
  (:require-macros [cljs.core.async.macros :refer [go]]
                   [auto-ap.entities.vendors :as vendor]))


(re-frame/reg-event-fx
 ::invalidated
 (fn [{:keys [db]}]
   {:graphql {:token (:user db)
              :owns-state {:single ::vendor-page}
              :query-obj {:venia/queries [[:vendor events/vendor-query]]} 
              :on-success [::received-vendors]}}))

(re-frame/reg-event-fx
 ::mounted
 (fn  [{:keys [db]} _]
   {:dispatch [::invalidated]
    ::track/register {:id ::params
                      :subscription [::params]
                      :event-fn (fn [params] [::params-change params])}
    ::forward/register {:id ::merge-complete
                        :events #{::merge-dialog/complete}
                        :event-fn (fn [_]
                                    [::invalidated])}}))

(re-frame/reg-event-db
 ::received-vendors
 (fn  [db [_ vendors]]
   (assoc db :vendors (by :id (:vendor vendors )))))


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

(re-frame/reg-sub
 ::params
 :<- [::side-bar/filter-params]
 :<- [::table/params]
 (fn [[filter-params table-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
 ::vendor-page
 :<- [::params]
 :<- [::subs/sorted-all-vendors]
 (fn [[params all-vendors]]
   (let [matching-vendors (cond->> all-vendors
                            (:name-like params) (filter #(str/includes? (str/lower-case (or (:name %) ""))
                                                                        (str/lower-case (:name-like params)))))]
     (assoc (grid/virtual-paginate-controls (:start params ) (:per-page params) matching-vendors)
            :data (grid/virtual-paginate (:start params) (:per-page params) matching-vendors)))))





(defn admin-vendors-content []
  [(with-meta
     (fn []
       [:div.inbox-messages
        (when-let [banner (:banner @(re-frame/subscribe [::subs/admin]))]
          [:div.notification banner])
        (let [vendors (re-frame/subscribe [::subs/vendors])
              editing-vendor (:vendor @(re-frame/subscribe [::subs/admin]))]
          [:div
           [:h1.title "Vendors"]
           [:div.is-pulled-right [:a.button.is-primary.is-outlined {:on-click (dispatch-event [::merge-dialog/show])} "Merge vendors"]]
           [table/vendors-table {:page @(re-frame/subscribe [::vendor-page])
                                 :status @(re-frame/subscribe [::status/single ::vendor-page])}]])])
     {:component-did-mount #(re-frame/dispatch [::mounted])
      :component-will-unmount #(re-frame/dispatch-sync [::unmounted])})])

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