(ns auto-ap.query-params
  (:require [auto-ap.time :as atime]
            [auto-ap.ssr.svg :as svg]
            [clj-time.core :as time]
            [clojure.string :as str]))

;; TODO should be able to get rid of this
(defn wrap-copy-qp-pqp [handler]
  (fn [request]
    (handler (assoc request :parsed-query-params (:query-params request)))))

(defn parse-key [k parser]
  (fn [query-params]
    (if (contains? query-params k)
      (update query-params k #(some-> % not-empty parser))
      query-params)))

(defn parse-date [d]
  (atime/parse d atime/normal-date))

(defn parse-sort [grid-spec q]
  (if (not-empty q)
    (->>
     (str/split q #",")
     (map (fn [k]
            (let [[key asc?]      (str/split k #":")
                  matching-header (first (filter #(= (str key) (:sort-key %)) (:headers grid-spec)))]
              {:sort-key        (str key)
               :asc             (boolean (= "asc" asc?))
               :matching-header matching-header
               :name            (:name matching-header)
               :sort-icon       (if (= (boolean (= "asc" asc?)) true)
                                  svg/sort-down
                                  svg/sort-up)})))
     (filter :matching-header)
     (into []))
    []))

(defn parse-long [l]
  (try
    (Long/parseLong l)
    (catch Exception e
      nil)))

(defn parse-double [l]
  (try
    (Double/parseDouble l)
    (catch Exception e
      nil)))

(defn apply-date-range [source-key start-date-key end-date-key]
  (fn [query-params]
    (dissoc
     (condp = (source-key query-params)
       "week"
       (let [last-monday (atime/last-monday)]
         (assoc query-params
                start-date-key (time/plus last-monday (time/days -7))
                end-date-key last-monday))

       "month"
       (assoc query-params
              start-date-key (time/plus (time/now) (time/months -1))
              end-date-key (time/now))

       "year"
       (assoc query-params
              start-date-key (time/plus (time/now) (time/years -1))
              end-date-key (time/now))

       "all"
       (assoc query-params
              start-date-key (time/plus (time/now) (time/years -6))
              end-date-key (time/now))

       query-params)
     :date-range)))

(defn apply-toggle-sort [grid-spec]
  (fn toggle-sort [query-params]
    (if (:toggle-sort query-params)
      (let [key-to-toggle     (:toggle-sort query-params)
            current-sort      (:sort query-params)
            presently-sorted? ((set (map :sort-key current-sort)) key-to-toggle)
            new-sort          (if presently-sorted?
                                (mapv
                                 (fn [s]
                                   (if (= (:sort-key s)
                                          key-to-toggle)
                                     (-> s
                                         (update :asc
                                                 #(boolean (not %)))
                                         (update :sort-icon (fn [x]
                                                              (if (= x svg/sort-down)
                                                                svg/sort-up
                                                                svg/sort-down))))
                                     s))
                                 current-sort)
                                (conj current-sort {:sort-key  key-to-toggle
                                                    :asc       true
                                                    :name      (:name (first (filter #(= (str key-to-toggle) (:sort-key %)) (:headers grid-spec))))
                                                    :sort-icon svg/sort-down}))]
        (-> query-params
            (assoc :sort new-sort)
            (dissoc :toggle-sort)))
      query-params)))

(defn apply-remove-sort []
  (fn remove-sort [query-params]
    (if-let [remove-sort-key  (:remove-sort query-params)]
      (-> query-params
          (update :sort (fn [current-sort]
                          (filterv (comp (complement #{remove-sort-key}) :sort-key) current-sort)))
          (dissoc :remove-sort))
      query-params)))
