(ns auto-ap.views.components.money-field
  (:require [reagent.core :as r]
            [auto-ap.views.utils :refer [->short$]]
            [clojure.string :as str]
            [react :as react]))
(def good-$ #"^\-?[0-9]+(\.[0-9][0-9])?$") 

(defn -money-field [{:keys [min max disabled on-blur on-change value class style placeholder]}]
  (let [[ parsed-amount set-parsed-amount] (react/useState {:parsed value
                                                            :raw    (cond
                                                                      (str/blank? value)
                                                                      ""

                                                                      (js/Number.isNaN (js/parseFloat value))
                                                                      ""

                                                                      :else
                                                                      (->short$ (js/parseFloat value)))})]
    (react/useEffect (fn []
                       ;; allow the controlling field to change the raw representation
                       ;; when the raw amount is a valid representation, so that 33.
                       ;; doesn't get unset
                       (when (or 
                               (and (:raw parsed-amount)
                                    (re-find good-$ (:raw parsed-amount)))
                               (str/blank? (:raw parsed-amount)))
                         (set-parsed-amount 
                           (assoc parsed-amount
                                  :parsed value
                                  :raw (cond
                                         (str/blank? value)
                                         ""

                                         (js/Number.isNaN (js/parseFloat value))
                                         ""

                                         :else
                                         (->short$ (js/parseFloat value))))))
                       nil))
    [:div.control.has-icons-left 
     [:input.input {:type      "text"
                    :disabled  disabled 
                    :placeholder placeholder
                    :class     class
                    :on-change (fn [e]
                                 (let [raw       (.. e -target -value)
                                       new-value (when (and raw
                                                            (not (str/blank? raw))
                                                            (re-find good-$ raw))
                                                   (js/parseFloat raw))]
                                   (set-parsed-amount {:raw    raw
                                                       :parsed new-value})
                                   (when (not= value new-value)
                                     (on-change new-value))))
                    :value     (or (:raw parsed-amount)
                                   "")
                    :on-blur (fn []
                               (when-not (re-find good-$ (:raw parsed-amount))
                                 
                                   (set-parsed-amount {:raw    ""
                                                       :parsed nil})
                                   (on-change nil))
                               (when on-blur
                                 (on-blur)))
                    :min       min
                    :max       max
                    :step      "0.01"
                    :style     (or style
                                   {:width "7em"})}]
     [:span.icon.is-left
      [:i.fa.fa-usd]]]))

(defn money-field []
  [:f> -money-field (r/props (r/current-component))])

(defn field []
  [:f> -money-field (r/props (r/current-component))])
