(ns auto-ap.views.pages.admin.clients.form
  (:require
   [auto-ap.events :as events]
   [auto-ap.forms :as forms]
   [auto-ap.forms.builder :as form-builder]
   [auto-ap.routes :as routes]
   [auto-ap.subs :as subs]
   [auto-ap.views.components.address :refer [address2-field]]
   [react-signature-canvas]
   [auto-ap.views.components.typeahead :refer [typeahead-v3]]
   [auto-ap.views.components.level :refer [left-stack] :as level]
   [auto-ap.views.components :as com]
   [auto-ap.views.components.typeahead.vendor
    :refer [search-backed-typeahead]]
   [auto-ap.views.utils
    :refer [date-picker
            dispatch-event]]
   [bidi.bidi :as bidi]
   [cljs-time.coerce :as coerce]
   [cljs-time.core :as t]
   [re-frame.core :as re-frame]
   [reagent.core :as r]
   [vimsical.re-frame.cofx.inject :as inject]
   [auto-ap.schema :as schema]
   [malli.core :as m]))

(def signature-canvas (r/adapt-react-class (.-default react-signature-canvas)))

(def location-schema (m/schema [:map
                                [:location schema/not-empty-string]]))

(def feature-flag-schema (m/schema [:map
                                    [:feature-flag schema/not-empty-string]]))

(def square-location-schema (m/schema [:map
                                       [:square-location schema/reference]
                                       [:client-location schema/not-empty-string]]))

(def ezcater-schema (m/schema [:map
                                       [:caterer schema/reference]
                                       [:client-location schema/not-empty-string]]))

(def name-match-schema (m/schema [:map
                                  [:match schema/not-empty-string]]))
(def location-match-schema (m/schema [:map
                                      [:match schema/not-empty-string]
                                      [:location schema/not-empty-string]]))
(def email-schema [:map
                   [:email schema/not-empty-string]
                   [:description schema/not-empty-string]])

(def client-schema [:map
                    [:name schema/not-empty-string]
                    [:code schema/code-string]
                    [:locations [:sequential location-schema]]
                    [:feature-flags [:sequential feature-flag-schema]]
                    [:emails {:optional true}
                     [:maybe [:sequential email-schema]]]
                    [:matches {:optional true}
                     [:maybe [:sequential name-match-schema]]]
                    [:location-matches {:optional true}
                     [:maybe [:sequential location-match-schema]]]
                    [:selected-square-locations {:optional true}
                     [:maybe [:sequential square-location-schema]]]])

(defn upload-replacement-button [{:keys [on-change]} text]
  (let [button (atom nil)]
    (r/create-class {:display-name "Upload button"
                     :reagent-render 
                     (fn []
                       [:<> 
                        [:label.button {:for "upload_replacement_signature"} text]
                        [:input.button {:type "file" :id "upload_replacement_signature"
                                        :style {:display "none"}
                                        :on-change (fn []
                                                     (let [fr (js/FileReader.)]
                                                       (.addEventListener fr "load" (fn []
                                                                                      (on-change (.-result fr))))

                                                       (.readAsDataURL fr (aget (.-files @button) 0)))
                                                     )
                                        :ref (fn [i] (reset! button i))} ]])})))

(defn signature [_]
  (let [canvas (atom nil)
        edit-mode? (r/atom false)
        w (* 1.5 464)
        h (* 1.5 174)]
    (fn [{:keys [signature-file signature-data on-change]}]
      [:div 
       (if @edit-mode?
         [:div
          [signature-canvas {"canvasProps" {"width" w
                                            "height" h
                                            "style" #js {"border" "1px solid #CCC"
                                                         "border-radius" "10px"}}
                             "backgroundColor" "#FFF"
                             :ref (fn [el]
                                    (reset! canvas el))}]
          [:div.buttons 
           [:a.button.is-primary.is-outlined  {:on-click (fn []
                                                           (on-change (.toDataURL @canvas "image/jpeg"))
                                                           (reset! edit-mode? false))}
            "Accept"]
           [:a.button.is-warning.is-outlined  {:on-click (fn []
                                    (.clear @canvas)
                                    (reset! edit-mode? false))}
            "Cancel"]]]
         (if (or signature-data signature-file)
           [:div 
            [:img {:src (or signature-data signature-file)
                   :style {:width w
                           :height h
                           :border "1px solid #CCC"
                           :border-radius "10px"}}]
            [:div.buttons 
             [:a.button {:on-click (fn []
                                     (reset! edit-mode? true))}
              "Replace Signature"]

             [upload-replacement-button {:on-change on-change} "Upload replacement"]]]
           [:div
            [:div.has-text-centered.is-vcentered {:style {:width w
                                                          :height h
                                                          :margin-bottom "8px"
                                                          :border "1px solid #CCC"
                                                          :border-radius "10px"
                                                          :background "#EEE"
                                                          }}
             "No signature"]
            [:div.buttons 
             [:a.button.is-primary.is-outlined {:on-click (fn []
                                     (reset! edit-mode? true))}
              "New Signature"]

             [upload-replacement-button {:on-change on-change} "Upload signature"]]]))
       ])))

(re-frame/reg-sub
 ::new-client-request
 :<- [::forms/form ::form]
 (fn [{new-client-data :data} _]
   (cond-> 
       {:id (:id new-client-data),
        :name (:name new-client-data)
        :code (:code new-client-data) ;; TODO add validation can't change
        :emails (map #(select-keys % [:id :email :description])
                     (:emails new-client-data))
        :square-auth-token (:square-auth-token new-client-data)
        :square-locations (map
                            (fn [x]
                              {:id (:id (:square-location x))
                               :client-location (:client-location x)})
                            (:selected-square-locations new-client-data))

        :ezcater-locations (map
                             (fn [x]
                               {:id              (:id x)
                                :caterer         (:id (:caterer x))
                                :location (:location x)})
                             (:ezcater-locations new-client-data))

        :locked-until (:locked-until new-client-data)
        :locations (mapv :location (:locations new-client-data))
        :feature-flags (mapv :feature-flag (:feature-flags new-client-data))
        :matches (mapv :match (:matches new-client-data))
        :location-matches (:location-matches new-client-data)
        :week-a-credits (:week-a-credits new-client-data)
        :week-a-debits (:week-a-debits new-client-data)
        :week-b-credits (:week-b-credits new-client-data)
        :week-b-debits (:week-b-debits new-client-data)
        :address {:id (:id (:address new-client-data))
                  :street1 (:street1 (:address new-client-data))
                  :street2 (:street2 (:address new-client-data)),
                  :city (:city (:address new-client-data))
                  :state (:state (:address new-client-data))
                  :zip (:zip (:address new-client-data))}
        :signature-data (:signature-data new-client-data)
        :forecasted-transactions (map (fn [{:keys [id day-of-month identifier amount]}]
                                        {:id id
                                         :day-of-month (js/parseInt day-of-month)
                                         :identifier identifier
                                         :amount amount})
                                      (:forecasted-transactions new-client-data))
        :bank-accounts (map-indexed (fn [i {:keys [number name check-number plaid-account intuit-bank-account include-in-reports type id code numeric-code start-date bank-name routing bank-code new? visible locations yodlee-account use-date-instead-of-post-date]}]
                              {:number number
                               :name name
                               :check-number check-number
                               :numeric-code numeric-code
                               :include-in-reports include-in-reports
                               :start-date start-date
                               :type type
                               :id id
                               :sort-order i
                               :visible visible
                               :locations (mapv :location locations)
                               :use-date-instead-of-post-date use-date-instead-of-post-date
                               :yodlee-account (:id yodlee-account)
                               :plaid-account (:id plaid-account)
                               :intuit-bank-account (:id intuit-bank-account)
                               :code (if new?
                                       (str (:code new-client-data) "-" code)
                                       code)
                               :bank-name bank-name
                               :routing routing
                               :bank-code bank-code})
                            (:bank-accounts new-client-data))})))

(re-frame/reg-sub
  ::client
  :<- [::subs/route-params]
  :<- [::subs/clients-by-id]
  (fn [[rp clients-by-id]]
    (or (get  clients-by-id (:id rp))
        {})))

(re-frame/reg-event-fx
 ::mounted
 [(re-frame/inject-cofx ::inject/sub [::client])]
 (fn  [{:keys [db] ::keys [client]} _]
   {:db (-> db
            (forms/stop-form ::form)
            (forms/start-form ::form (-> client
                                         (assoc :selected-square-locations (->> (:square-locations client)
                                                                                (filter :client-location )
                                                                                (mapv (fn [sl]
                                                                                        {:id              (:id sl)
                                                                                         :square-location sl
                                                                                         :client-location (:client-location sl)}))))
                                         (update :locations #(mapv (fn [l] {:location l
                                                                            :id (random-uuid)}) %))

                                         (update :feature-flags #(mapv (fn [l] {:feature-flag l
                                                                                :id       (random-uuid)}) %))
                                         (update :matches #(mapv (fn [l] {:match l
                                                                          :id (random-uuid)}) %))
                                         (update :bank-accounts
                                                 (fn [bas]
                                                   (mapv (fn [ba]
                                                           (update ba :locations (fn [ls]
                                                                                   (map (fn [l] {:location l
                                                                                                 :id (random-uuid)})
                                                                                        ls))))
                                                         bas))))))}))

(re-frame/reg-event-fx
 ::save-new-client
 [(forms/in-form ::form)]
 (fn  [_ _]

   (let [new-client-req @(re-frame/subscribe [::new-client-request])
         user @(re-frame/subscribe [::subs/token])]
     
     {:graphql
      {:token user
       :owns-state {:single ::form}
       :query-obj {:venia/operation {:operation/type :mutation
                                     :operation/name "EditClient"}
                   :venia/queries [{:query/data [:edit-client
                                                 {:edit-client new-client-req}
                                                 (events/client-query user)]}]}
       :on-success [::save-complete]
       :on-error [::forms/save-error ::form]}})))

(re-frame/reg-event-fx
 ::save-complete
 (fn  [{:keys [db]} [_ client]]
   {:db 
    (-> db
        #_(forms/stop-form ::form)
        
        (assoc-in [:clients (:id (:edit-client client))] (update (:edit-client client) :bank-accounts (fn [bas] (->> bas (sort-by :sort-order) vec)))))
    :redirect (bidi/path-for routes/routes :admin-clients)}))



(re-frame/reg-event-db
 ::add-new-bank-account
 [(forms/in-form ::form) (re-frame/path [:data])]
 (fn [client [_ type]]
   (update client :bank-accounts conj {:type type :active? true :new? true :visible true :sort-order (count (:bank-accounts client))})))

(re-frame/reg-event-db
 ::bank-account-activated
 [(forms/in-form ::form) (re-frame/path [:data :bank-accounts])]
 (fn [bank-accounts [_ index]]
   (update (vec (sort-by :sort-order bank-accounts)) index assoc :active? true)))

(re-frame/reg-event-db
 ::bank-account-deactivated
 [(forms/in-form ::form) (re-frame/path [:data :bank-accounts])] 
 (fn [bank-accounts [_ index]]
   (update (vec (sort-by :sort-order bank-accounts)) index assoc :active? false)))

(re-frame/reg-event-db
 ::bank-account-removed
 [(forms/in-form ::form) (re-frame/path [:data :bank-accounts])]
 (fn [bank-accounts [_ index]]
   (vec (concat (take index bank-accounts)
                (drop (inc index) bank-accounts)))))

(re-frame/reg-event-db
 ::sort-swapped
 [(forms/in-form ::form) (re-frame/path [:data :bank-accounts])]
 (fn [bank-accounts [_ source dest]]
   (->> (-> bank-accounts
            (assoc-in [source :sort-order] (get-in bank-accounts [dest :sort-order]))
            (assoc-in [dest :sort-order] (get-in bank-accounts [source :sort-order]))

            )
        (sort-by :sort-order)
        vec)))

(re-frame/reg-event-db
 ::toggle-visible
 [(forms/in-form ::form) (re-frame/path [:data :bank-accounts])]
 (fn [bank-accounts [_ account]]
   (-> (->> bank-accounts
            (sort-by :sort-order)
            vec)
       (update-in [account :visible] #(not %)))))





(def first-week-a (coerce/to-date-time #inst "1999-12-27T00:00:00.000-07:00"))

(defn is-week-a? [d]
  (= 0 (mod (t/in-weeks (t/interval first-week-a d)) 2)))


(re-frame/reg-sub
 ::yodlee-accounts
 :<- [::subs/clients-by-id]
 (fn [clients [_ id]]
   
   (if id
     (mapcat :accounts (:yodlee-provider-accounts (get clients id) ))
     [])))

(re-frame/reg-sub
 ::plaid-accounts
 :<- [::subs/clients-by-id]
 (fn [clients [_ id]]
   
   (if id
     (mapcat :accounts (:plaid-items (get clients id) ))
     [])))


(defn bank-account-card [new-client {:keys [active? new? type visible code name sort-order]} first? last?]
  [:div.card {:style {:margin-bottom "1em"
                      :width         "600px"}}
   [:header.card-header.has-background-primary-light
    [:div.card-header-title {:style {:text-overflow "ellipsis"}}
     [:div.level {:style {:width "100%"}}
      [:div.level-left
       [:div.level-item 
        [:span.icon.inline
         (cond
           (#{:check ":check"} type) [:span.icon-check-payment-sign]

           (#{:credit ":credit"} type) [:span.icon-credit-card-1]

           :else [:span.icon-accounting-bill])]]
       [:div.level-item code ": " name]]
      [:div.level-right
       [:div.level-item
        [:div.buttons
         [:a.button {:on-click (dispatch-event [::toggle-visible sort-order])} [:span.icon (if visible
                                                                                             [:span.fa.fa-eye]
                                                                                             [:span.fa.fa-eye-slash]
                                                                                             )]]
         (when-not last?
           [:a.button {:on-click (dispatch-event [::sort-swapped sort-order (inc sort-order)])} [:span.icon [:span.fa.fa-sort-down]]])
         (when-not first?
           [:a.button {:on-click (dispatch-event [::sort-swapped sort-order (dec sort-order)])} [:span.icon [:span.fa.fa-sort-up]]])]]]]]
    (if active?
      [:a.card-header-icon
       {:on-click (dispatch-event [::bank-account-deactivated sort-order])}
       [:span.icon
        [:span.fa.fa-angle-up]]]
      [:a.card-header-icon
       {:on-click (dispatch-event [::bank-account-activated sort-order])}
       [:span.icon
        [:span.fa.fa-angle-down]]])]
   (when active?
     [:div.card-content  
      [:label.label "General"]
      [level/left-stack
       [:div.control
        [:p.help "Account Code"]
        (if new?
          [:div.field.has-addons
           [:p.control [:a.button.is-static (:code new-client) "-" ]]
           [:p.control
            [form-builder/raw-field-v2 {:field :code}
             [:input.input {:type  "text"}]]]]
          [:div.field [:p.control code]])] 

       [form-builder/field-v2 {:field :name}
        "Nickname"
        [:input.input {:placeholder "BOA Checking #1"
                       :type        "text"}]]
       [form-builder/field-v2 {:field :numeric-code}
        "Numeric Code"
        [com/number-input {:placeholder "20101"
                           :style {:width "8em"}}]]
       [form-builder/field-v2 {:field :start-date}
        "Start date"
        [date-picker {:output :cljs-date}]]]

      (when (#{:check ":check"} type )
        [:div

         [:label.label "Bank"]
         [level/left-stack
          [form-builder/field-v2 {:field :bank-name}
           "Bank Name"
           [:input.input {:placeholder "Bank of America"
                          :type        "text"}]]
          [form-builder/field-v2 {:field       [:routing]}
           "Routing #"
           [:input.input {:placeholder "104819123"
                          :style       {:width "9em"}
                          :type        "text"}]]
          [form-builder/field-v2 {:field       :bank-code}
           "Bank code"
           [:input.input {:placeholder "12/10123"
                          :type        "text"}]]]

         [level/left-stack
          [form-builder/field-v2 {:field :number}
           "Account #"
           [:input.input {:placeholder "123456789"
                          :type        "text"
                          :style       {:width "20em"}}]]

          [form-builder/field-v2 {:field :check-number}
           "Check Number"
           [com/number-input {:style {:width "8em"}
                              :placeholder "10000"}]]]
         
         [form-builder/field-v2 {:field :yodlee-account}
          "Yodlee Account (new)"
          [typeahead-v3 {:entities     @(re-frame/subscribe [::yodlee-accounts (:id new-client)])
                         :entity->text (fn [m] (str (:name m) " - " (:number m)))}]]


         [form-builder/raw-field-v2 {:field :use-date-instead-of-post-date}
          [com/checkbox {:label " (Yodlee only) Use 'date' instead of 'postDate'"}]]

         [form-builder/field-v2 {:field :intuit-bank-account}
          "Intuit Bank Account"
          [typeahead-v3 {:entities     @(re-frame/subscribe [::subs/intuit-bank-accounts])
                         :entity->text (fn [m] (str (:name m)))}]]
         [form-builder/field-v2 {:field :plaid-accounti}
          "Plaid Account"
          [typeahead-v3 {:entities     @(re-frame/subscribe [::plaid-accounts (:id new-client)])
                         :entity->text (fn [m] (str (:name m)))}]]])

      (when (#{:credit ":credit"} type )
        [:div

         
         [:label.label "Account"]
         [form-builder/field-v2 {:field :bank-name}
          "Bank Name"
          [:input.input {:placeholder "Bank of America"
                         :type        "text"}]]

         [form-builder/field-v2 {:field :number}
          "Account #"
          [:input.input {:placeholder "123456789"
                         :type        "text"
                         :style       {:width "20em"}}]]

         [form-builder/field-v2 {:field :yodlee-account}
          "Yodlee Account (new)"
          [typeahead-v3 {:entities     @(re-frame/subscribe [::yodlee-accounts (:id new-client)])
                         :entity->text (fn [m] (str (:name m) " - " (:number m)))}]]

         [form-builder/raw-field-v2 {:field :use-date-instead-of-post-date}
          [com/checkbox {:label "(Yodlee only) Use 'date' instead of 'postDate'"}]
          [:input {:type  "checkbox"
                   :field [:use-date-instead-of-post-date]}]]

         [form-builder/field-v2 {:field :intuit-bank-account}
          "Intuit Bank Account"
          [typeahead-v3 {:entities     @(re-frame/subscribe [::subs/intuit-bank-accounts])
                         :entity->text (fn [m] (str (:name m)))}]]

         [form-builder/field-v2 {:field :plaid-account}
          "Plaid Account"
          [typeahead-v3 {:entities     @(re-frame/subscribe [::plaid-accounts (:id new-client)])
                         :entity->text (fn [m] (str (:name m)))}]]])
      [:div.field
       [:label.label "Locations"]
       [:div.control
        [:p.help "If this account is location-specific, add the valid locations"]
        [form-builder/raw-field-v2 {:field :locations}
         [com/multi-field-v2 {:template [[form-builder/raw-field-v2 {:field :location}
                                          [com/select-field {:options    (map (fn [l]
                                                                             [(:location l) (:location l)])
                                                                           (get-in new-client [:locations]))
                                                             :allow-nil? true
                                                             :style      {:width "7em"}
                                                             }]]]
                              :schema [:sequential location-schema]
                              :key-fn :id}]]]]

      


      [form-builder/raw-field-v2 {:field :include-in-reports}
       [com/checkbox {:label "Include in reports"}]
       ]
      ])

   (when active?
     [:footer.card-footer
      [:a.card-footer-item {:href "#" :on-click (dispatch-event [::bank-account-deactivated sort-order])} "Done"]
      (when new?
        [:a.card-footer-item.is-warning {:href "#" :on-click (dispatch-event [::bank-account-removed sort-order])} "Remove"])])])


(defn general-section []
  (let [{new-client :data} @(re-frame/subscribe [::forms/form ::form])]
    [form-builder/section {:title "General"}
     [form-builder/field-v2 {:field :name}
      "Name"
      [:input.input {:type  "text"
                     :style {:width "20em"}}]]
     [form-builder/field-v2 {:field :code}
      "Client code"
      [:input.input {:type     "code"
                     :style    {:width "5em"}
                     :disabled (boolean (:id new-client))}]]
     [:div.field
      [:label.label "Feature Flags"]
      [:div.control
       [:p.help "These are specific new features that can be enabled or disabled on a per-client basis"]
       [form-builder/raw-field-v2 {:field :feature-flags}
        [com/multi-field-v2 {:allow-change? true
                             :template      [[form-builder/raw-field-v2 {:field :feature-flag}
                                              [com/select-field {:options    [[nil nil]
                                                                              ["new-square" "New Square+Ezcater"]]
                                                                 :allow-nil? false
                                                                 :style      {:width "18em"}}]]]
                             :key-fn        :id
                             :schema        [:sequential feature-flag-schema]
                             :next-key      (random-uuid)}]]]]

     [form-builder/field-v2 {:field :locations}
      "Locations"
      [com/multi-field-v2 {:allow-change? false
                           :template      [[form-builder/raw-field-v2 {:field :location}
                                            [:input.input {:max-length 2
                                                           :style      { :width "4em"}}]]]
                           :disable-remove? true
                           :key-fn :id
                           :schema [:sequential location-schema]
                           :next-key (random-uuid)}]]

     [form-builder/vertical-control 
      "Signature"
      [signature {:signature-file (:signature-file new-client)
                  :signature-data (:signature-data new-client)
                  :on-change      (fn [uri]
                                    (re-frame/dispatch [::forms/change ::form [:signature-data] uri]))}]]

     [form-builder/field-v2 {:field :locked-until}
      "Locked Until"
      [date-picker {:output :cljs-date
                    :style  {:width "15em"}}]]]))

(defn contacts-section []
  [form-builder/section {:title "Contacts"}

   [form-builder/field-v2 {:field :emails}
    "Emails (address/description)"
    [com/multi-field-v2 {:template [[form-builder/raw-field-v2 {:field :email}
                                     [:input.input {:type        "email"
                                                    :placeholder "tom@myspace.com"}]]
                                    [form-builder/raw-field-v2 {:field :description}
                                     [:input.input {:type        "text"
                                                    :placeholder "Manager"}]]]
                         :key-fn :id
                         :schema [:sequential email-schema]
                         :next-key (random-uuid)}]]
   
   [form-builder/vertical-control 
    "Address"
    [:div {:style {:width "30em"}}
     [form-builder/raw-field-v2 {:field :address}
      [address2-field]]]]])

;; TODO Name matches, locations, bank account locations are all "single field multis", and require weird mounting and
;; unmounting. A new field could sort that out easily
(defn matching-section []
  [form-builder/section {:title "Matching"}
   [form-builder/field-v2 {:field :matches}
    "Name matches"
    [com/multi-field-v2 {:template [[form-builder/raw-field-v2 {:field [:match]}
                                     [:input.input {:placeholder "Harry's burger joint"
                                                    :style       { :width "15em"}}]]]
                         :key-fn   :id
                         :next-key (random-uuid)
                         :schema   [:sequential name-match-schema]}]]


   [form-builder/field-v2 {:field :location-matches}
    "Location Matches"
    [com/multi-field-v2 {:template [[form-builder/raw-field-v2 {:field :match}
                                     [:input.input {:placeholder "Downtown"
                                                    :style       { :width "15em"}}]]
                                    [form-builder/raw-field-v2 {:field :location}
                                     [:input.input {:placeholder "DT"
                                                    :max-length  2
                                                    :style       { :width "4em"}}]]]
                         :schema   [:sequential location-match-schema]
                         :next-key (random-uuid)
                         :key-fn   :id}]]])

(defn bank-accounts-section []
  (let [{new-client :data} @(re-frame/subscribe [::forms/form ::form])]
    [form-builder/section {:title "Bank Accounts"}
     (for [bank-account (sort-by :sort-order (:bank-accounts new-client))]
       ^{:key (:sort-order bank-account)}
       [form-builder/with-scope {:scope [:bank-accounts (:sort-order bank-account)]}
        [bank-account-card new-client bank-account (= 0 (:sort-order bank-account)) (= (:sort-order bank-account) (dec (count (:bank-accounts new-client))))]])

     [:div.buttons
      [:a.button.is-primary.is-outlined {:on-click (dispatch-event [::add-new-bank-account :credit])} "Add Credit Account"]
      [:a.button.is-primary.is-outlined {:on-click (dispatch-event [::add-new-bank-account :check])} "Add Checking Account"]
      [:a.button.is-primary.is-outlined {:on-click (dispatch-event [::add-new-bank-account :cash])} "Add Cash Account"]]]))

(defn cash-flow-section []
  (let [next-week-a (if (is-week-a? (t/now))
                                   "This week"
                                   "Next week")
        next-week-b (if (is-week-a? (t/now))
                                   "Next week"
                                   "This week")]

    
    [form-builder/section {:title "Cash Flow"}
     [:label.label (str "Week A (" next-week-a ")")]
     [left-stack 
      [form-builder/field-v2 {:field :week-a-credits}
       "Regular Credits"
       [com/money-input]]
      [form-builder/field-v2 {:field :week-a-debits}
       "Regular Debits"
       [com/money-input]]]
     [:label.label (str "Week B (" next-week-b ")")]
     [left-stack 
      [form-builder/field-v2 {:field :week-b-credits}
       "Regular Credits"
       [com/money-input]]
      [form-builder/field-v2 {:field :week-b-debits}
       "Regular Debits"
       [com/money-input]]]

     [form-builder/field-v2 {:field :forecasted-transactions}
      "Forecasted transactions"

      [com/multi-field-v2 {:template [[form-builder/raw-field-v2 {:field :identifier}
                                       [:input.input {:type        "text"
                                                      :placeholder "Identifier"
                                                      :style       {:width "10em"}}]]
                                      [form-builder/raw-field-v2 {:field :day-of-month}
                                       [com/number-input {:placeholder "DOM"}]]
                                      [form-builder/raw-field-v2 {:field :amount
                                                                  :placeholder "AMT"}
                                       [com/money-input]]]
                           :key-fn :id}]]]))

(defn square-section []
  (let [{new-client :data} @(re-frame/subscribe [::forms/form ::form])]
    [form-builder/section {:title "Square Integration"}
     [form-builder/field-v2 {:field :square-auth-token}
      "Square Authentication Token"
      [:input.input {:type  "text"
                     :style {:width "40em"}}]]
     [form-builder/field-v2 {:field :selected-square-locations}
      "Square Locations"
      [com/multi-field-v2 {:template        [[form-builder/raw-field-v2 {:field :square-location}
                                              [typeahead-v3  {:entities     (:square-locations new-client)
                                                              :entity->text :name
                                                              :style        {:width "15em"}}]]
                                             [form-builder/raw-field-v2 {:field :client-location}
                                              [com/select-field {:options    (map (fn [l]
                                                                                    [(:location l) (:location l)])
                                                                                  (get-in new-client [:locations]))
                                                                 :allow-nil? true
                                                                 :style      {:width "7em"}
                                                                 }]]]
                           :disable-remove? true
                           :key-fn          :id
                           :schema          [:sequential square-location-schema]}]]]))

(defn ezcater-section []
  (let [{new-client :data} @(re-frame/subscribe [::forms/form ::form])]
    [form-builder/section {:title "EZCater integration"}

     [form-builder/field-v2 {:field :ezcater-locations}
      "EZCater Locations"
      [com/multi-field-v2 {:template        [[form-builder/raw-field-v2 {:field :caterer}
                                              [search-backed-typeahead {:search-query (fn [i]
                                                                                        [:search_ezcater_caterer
                                                                                         {:query i}
                                                                                         [:name :id]])
                                                                        :entity->text :name
                                                                        :style        {:width "20em"}}]]
                                             [form-builder/raw-field-v2 {:field [:location]}
                                              [com/select-field {:options    (map (fn [l]
                                                                                    [(:location l) (:location l)])
                                                                                  (get-in new-client [:locations]))
                                                                 :allow-nil? true
                                                                 :style      {:width "7em"}}]]]
                           :key-fn :id
                           :schema [:sequential ezcater-schema]
                           :disable-remove? true}]]]))


(defn form-content []
  (let [_                  @(re-frame/subscribe [::client])
        {new-client :data} @(re-frame/subscribe [::forms/form ::form])]

    ^{:key (or (:id new-client)
               "new")}
    [form-builder/builder {:submit-event [::save-new-client ]
                           :id           ::form
                           :fullwidth?   false
                           :schema client-schema}

     [general-section]
     [contacts-section]
     [matching-section]
     [bank-accounts-section]
     [cash-flow-section]
     [square-section]
     [ezcater-section]
     [form-builder/error-notification]
     [form-builder/submit-button "Save"]]))

(def new-client-form
  (with-meta
    (fn []
      [form-content])
    {:component-did-mount    #(re-frame/dispatch [::mounted])}))
