(ns auto-ap.parse.util
  (:require
   [clj-time.core :as time]
   [clj-time.format :as f]
   [clojure.string :as str]
   [auto-ap.logging :as alog]))

(defmulti parse-value (fn [method _ _]
                        method))


(defmethod parse-value :trim-commas
  [_ _ value]
  (str/replace value #"," "")
  )
(defmethod parse-value :trim-commas-and-remove-dollars
  [_ _ value]
  (str/replace (str/replace value #"," "") #"\$" ""))

(defmethod parse-value :trim-commas-and-remove-dollars-and-invert-parentheses
  [_ _ value]
  (let [v (str/replace (str/replace value #"," "") #"\$" "")]
    (if-let [[_ a ] (re-find #"\((.*)\)" v)]
      (str "-" a)
      v)))

(defmethod parse-value :trim-commas-and-negate
  [_ _ value]
  (let [[_ raw-value] (re-find #"([\d\.]+)"
                               (-> value
                                   (str/replace #"," "")
                                   (str/replace #"-" "")))]
    (if (or (str/includes? value "-")
            (str/includes? value "CR"))
      (str (- (Double/parseDouble raw-value)))
      (str raw-value))))

(defmethod parse-value :month-day-year
  [_ _ value]
  (let [format "yyyy-MM-dd"

        [month day year] (str/split (-> value 
                                        (str/replace #"\s+" " ")
                                        )
                                    #"\s")

        value (str "20" year "-" month "-" day) ]
    (try 
      (time/from-time-zone (f/parse (f/formatter format) value)
                           (time/time-zone-for-id "America/Los_Angeles"))
      (catch Exception e
        (alog/warn ::cant-parse-date :error e :raw-value (str value))
        nil))))

(defmethod parse-value :clj-time
  [_ format value]
  (let [format (if (sequential? format)
                 format
                 [format])]
    (reduce
     (fn [_ format]
       (try 
         (reduced (time/from-time-zone (f/parse (f/formatter format) value)
                                       (time/time-zone-for-id "America/Los_Angeles")))
         (catch Exception e
           (alog/warn ::cant-parse-date :error e :raw-value (str value))
           nil)))
     nil
     format)
    ))

(defmethod parse-value nil
  [_ _ value]
  value)

