(ns auto-ap.views.pages.invoices.handwritten-checks
  (:require [auto-ap.entities.invoice :as invoice]
            [auto-ap.forms :as forms]
            [auto-ap.status :as status]
            [auto-ap.subs :as subs]
            [auto-ap.utils :refer [by]]
            [auto-ap.views.components.modal :as modal]
            [auto-ap.views.pages.data-page :as data-page]
            [auto-ap.views.pages.invoices.common
             :refer
             [does-amount-exceed-outstanding? invoice-read]]
            [auto-ap.views.pages.invoices.form :as form]
            [auto-ap.views.utils
             :refer
             [date-picker dispatch-event horizontal-field with-user]]
            [clojure.string :as str]
            [re-frame.core :as re-frame]))

(def handwrite-checks-form (forms/vertical-form {:submit-event [::save]
                                                 :change-event [::forms/change ::form]
                                                 :can-submit [::can-submit]
                                                 :id ::form}))

(defn form []
  (let [real-bank-accounts @(re-frame/subscribe [::subs/real-bank-accounts])
        {:keys [data active? error id]} @(re-frame/subscribe [::forms/form ::form])
        {:keys [form-inline horizontal-field field raw-field error-notification submit-button]} handwrite-checks-form]
    (form-inline {}
                 [:<>
                  [:div.field
                   [:label.label  "Pay using"]
                   [:div.control 
                    [:span.select
                     [raw-field
                      [:select {:type "select"
                                :field :bank-account-id}
                       (for [{:keys [id number name]} real-bank-accounts]
                         ^{:key id} [:option {:value id} name])]]]]]
                  (field "Date"
                         [date-picker {:class-name "input"
                                       :class "input"
                                       :format-week-number (fn [] "")
                                       :previous-month-button-label ""
                                       :placeholder "mm/dd/yyyy"
                                       :next-month-button-label ""
                                       :next-month-label ""
                                       :type "date"
                                       :field [:date]
                                       :spec ::invoice/date}])
                  (field "Check number"
                         [:input.input {:type "number"
                                        :field [:check-number]}])
                  [:table.table.is-fullwidth
                   [:thead
                    [:tr
                     [:th "Invoice ID"]
                     [:th {:style {"width" "14em"}} "Payment"]]]
                   [:tbody
                    (doall  
                     (for [{:keys [payment outstanding-balance invoice-number id] :as i} (:invoices data)]
                       ^{:key id}
                       [:tr
                        [:td invoice-number]
                        [:td  [:div.field.has-addons.is-extended
                               [:p.control [:a.button.is-static "$"]]
                               [:p.control

                                (raw-field 
                                 [:input.input.has-text-right {:type "number"
                                                :field [:invoice-amounts id :amount]
                                                #_#_:max outstanding-balance
                                                :step "0.01"}])]]]]))]]])))

(re-frame/reg-sub
 ::can-submit
 :<- [::forms/form ::form]
 (fn [{ {:keys [check-number date invoices invoice-amounts]} :data}]
   (boolean (cond (seq (filter
                        (fn [{:keys [id outstanding-balance]}]
                          (does-amount-exceed-outstanding? (get-in invoice-amounts [id :amount]) outstanding-balance ))
                        invoices))
                  false

                  :else
                  (and (not (str/blank? check-number))
                       (not (str/blank? date)))))))

(re-frame/reg-event-fx
 ::show
 (fn [{:keys [db]} [_ invoices]]
   {:dispatch [::modal/modal-requested {:title "Handwrite checks"
                                        :body [form]
                                        :confirm {:value "Save handwritten check"
                                                  :status-from [::status/single ::form]
                                                  :class "is-primary"
                                                  :on-click (dispatch-event [::save])
                                                  :can-submit [::can-submit]
                                                  :close-event [::status/completed ::form]}}]
    :db (-> db
            (forms/start-form ::form
                              {:bank-account-id (:id (first @(re-frame/subscribe [::subs/real-bank-accounts])))
                               :invoices invoices
                               :invoice-amounts (into {}
                                                      (map (fn [i] [(:id i)
                                                                    {:amount (:outstanding-balance i)}])
                                                           invoices))}))}))



(re-frame/reg-event-fx
 ::save
 [with-user (forms/in-form ::form)]
 (fn [{:keys [db user]} _]
   (let [{:keys [date invoices invoice-amounts check-number bank-account-id]} (:data db)]
     {:graphql
      {:token user
       :owns-state {:single ::form}
       :query-obj {:venia/operation {:operation/type :mutation
                                     :operation/name "AddHandwrittenCheck"}
                   :venia/queries [{:query/data [:add-handwritten-check
                                                 {:date date
                                                  :invoice_payments (map (fn [x]
                                                                           {:invoice-id (:id x)
                                                                            :amount (get-in invoice-amounts [(:id x) :amount])})
                                                                         invoices)
                                                  :check-number check-number
                                                  :bank-account-id bank-account-id}
                                                 [[:invoices invoice-read]]]}]}  
       :on-success (fn [result]
                     [::succeeded (:invoices (:add-handwritten-check result))])}})))

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

