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

(def handwritten-check-schema
  (m/schema
    [:map
     [:bank-account-id schema/not-empty-string]
     [:date schema/date]
     [:check-number [:int {:min 1000 :max 99999}]]
     ]))

(defn form []
  (let [real-bank-accounts @(re-frame/subscribe [::subs/real-bank-accounts])
        {:keys [data]} @(re-frame/subscribe [::forms/form ::form])]
    [form-builder/builder {:submit-event [::save]
                           :can-submit   [::can-submit]
                           :id           ::form
                           :schema handwritten-check-schema}
     [form-builder/field-v2 {:field :bank-account-id}
      "Pay using"
      [com/select-field {:options    (for [{:keys [id name]} real-bank-accounts]
                                       [id name])
                         :allow-nil? true}]]

     [form-builder/field-v2 {:field :date}
      "Date"
      [date-picker {:type   "date"
                    :output :cljs-date}]]

     [form-builder/field-v2 {:field :check-number}
      "Check number"
      [com/number-input {:style {:width "8em"}}]]
     [:table.table.is-fullwidth
      [:thead
       [:tr
        [:th "Invoice ID"]
        [:th {:style {"width" "14em"}} "Payment"]]]
      [:tbody
       (doall  
         (for [{:keys [invoice-number id]} (:invoices data)]
           ^{:key id}
           [:tr
            [:td invoice-number]
            [:td
             [form-builder/raw-field-v2 {:field [:invoice-amounts id :amount]}
              [money-field {:style    {:max-width "9em"}}]]]]))]]
     [form-builder/hidden-submit-button]]))

(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 nil
                               :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 [_ _]
   {:dispatch [::modal/modal-closed]}))

