(ns auto-ap.views.utils
  (:require [re-frame.core :as re-frame]
            [clojure.spec.alpha :as s]
            [auto-ap.events :as events]
            [auto-ap.subs :as subs]
            [cljs-time.format :as format]))

(defn active-when= [active-page candidate]
  (when (= active-page candidate) " active"))

(def login-url
  (let [client-id "264081895820-0nndcfo3pbtqf30sro82vgq5r27h8736.apps.googleusercontent.com"
        redirect-uri (js/encodeURI (str (.-origin (.-location js/window)) "/api/oauth"))]
    (str "https://accounts.google.com/o/oauth2/auth?access_type=online&client_id=" client-id "&redirect_uri=" redirect-uri "&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile")))

(defn dispatch-value-change [event]
  (fn [e]
    (.preventDefault e)
    (re-frame/dispatch (conj event (.. e -target -value)))))

(defn dispatch-event [event]
  (fn [e]
    (when (.-stopPropagation e)
      (.stopPropagation e)
      (.preventDefault e))
    (re-frame/dispatch event)))

(def pretty-long (format/formatter "MM/dd/yyyy HH:mm:ss"))
(def pretty (format/formatter "MM/dd/yyyy"))

(defn date->str [d]
  (when d
    (format/unparse pretty d)))

(defn date-time->str [d]
  (when d
    (format/unparse pretty-long d)))

(defmulti do-bind (fn [a {:keys [type] :as x}]
                    type))

(defn with-keys [children]
  (map-indexed (fn [i c] ^{:key i} c) children))

(defmethod do-bind "select" [dom {:keys [field subscription event class value spec] :as keys} & rest]
  (let [field (if (keyword? field) [field] field)
        event (if (keyword? event) [event] event)
        keys (assoc keys
                    :on-change (dispatch-value-change (conj event field))

                    :value (get-in subscription field)
                    :class (str class
                                (when (and spec (not (s/valid? spec (get-in subscription field))))
                                  " is-danger")))
        keys (dissoc keys :field :subscription :event :spec)]
    (into [dom keys] (with-keys rest))))


(defmethod do-bind "radio" [dom {:keys [field subscription event class value spec] :as keys} & rest]
  (let [field (if (keyword? field) [field] field)
        event (if (keyword? event) [event] event)
        keys (assoc keys
                    :on-change (dispatch-value-change (conj event field))
                    :checked (= (get-in subscription field) value)
                    :class (str class
                                (when (and spec (not (s/valid? spec (get-in subscription field ))))
                                  " is-danger")))
        keys (dissoc keys :field :subscription :event :spec)]
    (into [dom keys] (with-keys rest))))

(defmethod do-bind "typeahead" [dom {:keys [field event subscription class spec] :as keys} & rest]
  (let [field (if (keyword? field) [field] field)
        event (if (keyword? event) [event] event)
        keys (assoc keys
                    :on-change (fn [selected]
                                 (re-frame/dispatch (conj (conj event field) selected)))
                    :value (get-in subscription field)
                    :class (str class
                                (when (and spec (not (s/valid? spec (get-in subscription field))))
                                  " is-danger")))
        keys (dissoc keys :field :subscription :event :spec)]
    (into [dom keys] (with-keys rest))))

(defmethod do-bind :default [dom {:keys [field event subscription class spec] :as keys} & rest]
  (let [field (if (keyword? field) [field] field)
        event (if (keyword? event) [event] event)
        keys (assoc keys
                    :on-change (dispatch-value-change (conj event field))
                    :value (get-in subscription field)
                    :class (str class
                                (when (and spec (not (s/valid? spec (get-in subscription field))))
                                  " is-danger")))
        keys (dissoc keys :field :subscription :event :spec)]
    (into [dom keys] (with-keys rest))))

(defn bind-field [all]
   (apply do-bind all))



(defn horizontal-field [label & controls]
  [:div.field.is-horizontal
   [:div.field-label
    label
    ]
   (into
    [:div.field-body]
    (with-keys (map (fn [x] [:div.field x]) controls)))])



