(ns auto-ap.views.pages.admin.jobs
  (:require
   [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.layouts :refer [side-bar-layout]]
   [auto-ap.views.pages.admin.jobs.table :as table]
   [auto-ap.views.components.modal :as modal]
   [auto-ap.views.components :as com]
   [auto-ap.views.pages.data-page :as data-page]
   [auto-ap.views.utils :refer [dispatch-event with-user]]
   [clojure.set :as set]
   [re-frame.core :as re-frame]
   [vimsical.re-frame.fx.track :as track]
   [auto-ap.forms.builder :as form-builder]
   [vimsical.re-frame.cofx.inject :as inject]
   [auto-ap.forms :as forms]
   [clojure.string :as str]))

(def a 1)


(def default-read [:name :start-date :end-date :status])

(re-frame/reg-event-fx
 ::params-change
 [with-user ]
 (fn [{:keys [user]} [_ params]]
   {:graphql {:token user
              :owns-state {:single [::data-page/page ::page]}
              :query-obj {:venia/queries [{:query/data [:jobs_page
                                                        {:filters {:sort (:sort params)
                                                                   :start (:start params 0)
                                                                   :per-page (:per-page params)}}
                                                        [[:data default-read]
                                                         :total
                                                         :start
                                                         :end]]
                                           :query/alias :result}]} 
              :on-success (fn [result]
                            [::data-page/received ::page
                             (set/rename-keys (:result result)
                                              {:jobs :data})])}}))

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

(re-frame/reg-event-fx
 ::success
 (fn [{:keys [db]} [_ n]]
   {:db (assoc db ::msg (:message (:request-job n)))
    :dispatch-n [[::params-change]
                 [::modal/modal-closed]]}))

(re-frame/reg-event-fx
 ::saving
 [with-user
  (re-frame/inject-cofx ::inject/sub [::forms/form ::form])
  ]
 (fn [{:keys [user] ::forms/keys [form]} [_ which]]
   (let [which (:job (:data form))]
     
     {:graphql {:token      user
                :owns-state {:single which}
                :query-obj
                {:venia/operation {:operation/type :mutation
                                   :operation/name "RequestJob"}
                 :venia/queries   [{:query/data
                                    [:request-job
                                     {:which (str which)
                                      :args  (-> (cond (= which :bulk-journal-import)
                                                       (select-keys (:data form) [:ledger-url])

                                                       (= which :register-invoice-import)
                                                       (select-keys (:data form) [:invoice-url])

                                                       (= which :load-historical-sales)
                                                       {:days (-> form :data :days)
                                                        :client (-> form :data :client :id)}

                                                       :else
                                                       nil
                                                       )
                                                pr-str
                                                (str/escape  {\" "\\\""}))}
                                     [:message]]}]}
                :on-success [::success]}})))

(re-frame/reg-event-fx
 ::mounted
 (fn [_]
   {::track/register {:id           ::params
                      :subscription [::data-page/params ::page]
                      :event-fn     (fn [params]
                                  [::params-change params])}}))

(re-frame/reg-event-fx
 ::unmounted
 (fn [{:keys [db]}]
   {:dispatch-n [[::data-page/dispose ::page]]
    ::track/dispose {:id ::params}
    :db (dissoc db ::msg)}))

(defn job-button [{:keys [which]} content]
  (let [status @(re-frame/subscribe [::status/single which])]
    (println status)
    [:button.button.is-primary.is-small {:type     "button"
                                    :on-click (dispatch-event [::request which])
                                    :disabled (status/disabled-for status)
                                    :class    (status/class-for status)}
     content]))

(defn notification []
  (let [state @(re-frame/subscribe [::status/single ::form])]
    [:<> 
     (when-let [msg @(re-frame/subscribe [::msg])]
       [:div.notification.is-info.is-light msg])
     [:div
      (cond (:info state)
            [:div.notification.is-info.is-light (:info state)]

            (seq (:error state))
            [:div.notification.is-info.is-warning.is-light (:message (first (:error state)))]

            :else
            nil)]]))

(defn new-job-form []
  (let [{:keys [data]} @(re-frame/subscribe [::forms/form ::form])
        clients        @(re-frame/subscribe [::subs/clients])]
    [:<>
     [form-builder/builder {:submit-event [::saving]
                            :id           ::form}
      [form-builder/field-v2 {:required? true
                              :field     :job}
       "Job Type"
       [com/select-field {:options     [[:yodlee2 "Yodlee Import"]
                                        [:yodlee2-accounts "Yodlee Account Import"]
                                        [:intuit "Intuit import"]
                                        [:plaid "Plaid import"]
                                        [:bulk-journal-import "Bulk Journal Import"]
                                        [:square2-import-job "Square2 Import"]
                                        [:register-invoice-import "Register Invoice Import "]
                                        [:ezcater-upsert "Upsert recent ezcater orders"]
                                        [:load-historical-sales "Load Historical Square Sales"]]
                          :allow-nil?  true
                          :keywordize? true}]]
      (cond (= :bulk-journal-import (:job data))
            [:<> 
             [:label.label "Url"]
             [:p.field.has-addons
              [:p.control
               [:a.button.is-static
                "s3://data.prod.app.integreatconsult.com/bulk-import/"]]
              [:p.control
               [form-builder/raw-field-v2 {:field :ledger-url}
                [:input.input {:placeholder "ledger-data.csv"}]]]]]

            (= :register-invoice-import (:job data))
            [:<> 
             [:label.label "Url"]
             [:p.field.has-addons
              [:p.control
               [:a.button.is-static
                "s3://data.prod.app.integreatconsult.com/bulk-import/"]]
              [:p.control
               [form-builder/raw-field-v2 {:field :invoice-url}
                [:input.input {:placeholder "invoice-data.csv"}]]]]]

            (= :load-historical-sales (:job data))
            [:<>
             [form-builder/field-v2 {:required? true
                                     :field     [:client]}
              "Client"
              [com/entity-typeahead {:entities     @(re-frame/subscribe [::subs/clients])
                                     :entity->text :name}]]

             [form-builder/field-v2 {:field :days}
              "Days to load (recommended 60)"
              [com/number-input {:placeholder "60"
                                 :style       {:width "7em"}}]]]
            :else
            nil)
      
      [form-builder/hidden-submit-button]]]))



;; VIEWS
(def jobs-content
  (with-meta
    (fn []
      (let [user                                   @(re-frame/subscribe [::subs/user])]
        [:div 
         [:h1.title "Jobs"]
         [notification]
         
         (when (= "admin" (:user/role user))
           [:div 
            [:div.is-pulled-right
             [:button.button.is-primary.is-small {:type     "button"
                                                  :on-click (dispatch-event [::modal/modal-requested
                                                                             {:title   "Start a new job"
                                                                              :body    [new-job-form]
                                                                              :cancel? false
                                                                              :confirm {:value       "Submit"
                                                                                        :status-from [::status/single ::form]
                                                                                        :class       "is-primary"
                                                                                        :on-click    (dispatch-event [::saving])
                                                                                        :close-event [::status/completed ::form]}}])}
              "Run new job"]
             ]
            [table/table {:id        :jobs
                          :data-page ::page}]])]))
    {:component-did-mount (dispatch-event [::mounted ])
     :component-will-unmount #(re-frame/dispatch-sync [::unmounted])}))

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

