(ns auto-ap.views.pages.admin.users.form
  (:require [re-frame.core :as re-frame]
            [reagent.core :as reagent]
            [clojure.string :as str]
            [auto-ap.subs :as subs]
            [auto-ap.events :as events]
            [auto-ap.entities.clients :as entity]
            [auto-ap.views.components.address :refer [address-field]]
            [auto-ap.views.components.admin.side-bar :refer [admin-side-bar]]
            [auto-ap.views.components.layouts :refer [side-bar-layout]]
            [auto-ap.views.utils :refer [login-url dispatch-value-change bind-field horizontal-field dispatch-event with-user]]
            [auto-ap.views.components.grid :as grid]
            [auto-ap.utils :refer [by replace-if]]
            [cljs.reader :as edn]
            [auto-ap.routes :as routes]
            [bidi.bidi :as bidi]
            [auto-ap.status :as status]
            [auto-ap.forms :as forms]
            [auto-ap.views.components.modal :as modal]))

(re-frame/reg-sub
 ::can-submit
 (fn [db]
   true))

(re-frame/reg-event-db
 ::changed
 (forms/change-handler ::form
                       (fn  [data field value]
                         [])))



(re-frame/reg-event-db
 ::add-client
 [(forms/in-form ::form)]
 (fn [form [_ d]]
   (let [client (get @(re-frame/subscribe [::subs/clients-by-id])
                 (get-in form [:data :adding-client]))]
     (update-in form [:data :clients] conj client ))))

(re-frame/reg-event-db
 ::remove-client
 [(forms/in-form ::form)]
 (fn [form [_ d]]
   (update-in form [:data :clients]  #(filter (fn [c] (not= (:id c) d)) %))))

(re-frame/reg-event-fx
 ::saving
 [with-user (forms/in-form ::form)]
 (fn [{:keys [db user]} [_]]
   {:graphql
    {:token user
     :owns-state {:single ::form}
     :query-obj {:venia/operation {:operation/type :mutation
                                   :operation/name "EditUser"}
                 :venia/queries [{:query/data [:edit-user
                                               {:edit-user (-> (:data db)
                                                               (update :clients #(map :id %))
                                                               (select-keys #{:id :name :clients :role}))}
                                               [:id :name :role [:clients [:id :name]]]]}]}  
     :on-success [::saved]}}))

(re-frame/reg-event-fx
 ::saved
 (forms/triggers-stop ::form)
 (fn [{:keys [db]} [_ {:keys [edit-user]}]]
   {:dispatch [::modal/modal-closed]}))

(def user-form (forms/vertical-form {:submit-event [::saving]
                                     :change-event [::changed]
                                     :can-submit [::can-submit]
                                     :id ::form}))

(defn form []
  (let [{:keys [data active? error id]} @(re-frame/subscribe [::forms/form ::form])
        {:keys [form-inline field raw-field error-notification submit-button]} user-form]
    (form-inline {}
                 [:<>
                  (field "Name"
                         [:input.input {:type "text"
                                        :field [:name]
                                        :spec ::entity/name}])
                  [:div.field
                   [:p.help  "Role"]
                   [:div.control
                    [:div.select
                     [raw-field
                      [:select {:type "select"
                                :field [:role]}
                       [:option {:value ":none"} "None"]
                       [:option {:value ":user"} "User"]
                       [:option {:value ":manager"} "Manager"]
                       [:option {:value ":power_user"} "Power User"]
                       [:option {:value ":admin"} "Admin"]]]]]]
                  (when (#{":user" ":manager" ":power_user"} (:role data))
                    [:div.field
                     [:p.help "Clients"]
                     [:div.control
                      [:div.field.has-addons
                       [:div.control
                        [:div.select
                         [raw-field
                          [:select {:type "select"
                                    :field [:adding-client]}
                           [:option]
                           (let [used-clients (set (map :id (:clients data)))]
                             (for [{:keys [id name] :as client} @(re-frame/subscribe [::subs/clients])
                                   :when (not (used-clients id))]
                               ^{:key id} [:option {:value id} name]))]]]]
                       [:p.control
                        [:button.button.is-primary {:on-click (dispatch-event [::add-client])} "Add"]]]

                      [:ul
                       (for [{:keys [id name]} (:clients data)]
                         ^{:key id} [:li  name [:a.icon {:on-click (dispatch-event [::remove-client id])} [:i.fa.fa-times ]]])]]])])))
(re-frame/reg-event-fx
 ::editing
 (fn [{:keys [db]} [_ d]]
   {:db (-> db
            (forms/start-form ::form d))
    :dispatch [::modal/modal-requested {:title (str "Edit user " (:name d))
                                               :body [form]
                                               :cancel? false
                                        :confirm {:value "Save"
                                                  :status-from [::status/single ::form]
                                                  :class "is-primary"
                                                  :on-click (dispatch-event [::saving])
                                                  :close-event [::status/completed ::form]}}]}))
