(ns auto-ap.routes.reminders
  (:require 
            [auto-ap.db.reminders :as reminders]
            [auto-ap.db.vendors :as vendors]
            [auto-ap.routes.utils :refer [wrap-secure]]
            [config.core :refer [env]]
            [clj-http.client :as http]
            [clj-time.coerce :as c]
            [clj-time.core :as time]
            [clj-time.periodic :as p]
            [clj-time.predicates :as pred]
            [clojure.data.json :as json]
            [compojure.core :refer [GET PUT POST context defroutes
                                    wrap-routes]])
  (:import (org.joda.time DateTime)))

(defn next-sunday []
  (let [sunday (->> (p/periodic-seq (time/plus (time/today) (time/days 1)) (time/days 1))
                    (filter pred/sunday?)
                    first)]
    (time/from-time-zone (time/date-time (time/year sunday) (time/month sunday) (time/day sunday))
                         (time/time-zone-for-id "America/Los_Angeles"))))

(defn schedule-reminders []
  (let [vendors (vendors/find-with-reminders)
        future-reminders (reminders/find-future (map :id vendors))
        has-reminder-scheduled? (set (map :vendor-id future-reminders))
        vendors-without-scheduled (filter #(not (has-reminder-scheduled? (:id %))) vendors)]
    (println "Reminders already scheduled:" future-reminders)
    (println "Reminders will happen at" (next-sunday))
    (println "Reminders to schedule" vendors-without-scheduled)

    (doseq [{:keys [id primary-email invoice-reminder-schedule]} vendors-without-scheduled]
      (reminders/insert (assoc (reminders/template)
                               :vendor-id id
                               :email primary-email
                               :scheduled (next-sunday))))))

(defn find-ready-reminders []
  (let [vendors (vendors/get-all)
        ready-reminders (reminders/get-ready)]
    ready-reminders))



(defn replace-joda [x]
  (into {}  (map (fn [[k v]]
                   [k (if (instance? DateTime v)
                        (c/to-date v)
                        v)])
                 x)))

(defroutes routes
  (context "/reminders" []
           
           (POST "/send" {:keys [query-params headers body] :as x}
                 (let [notification-type (get headers "x-amz-sns-message-type")]
                   (println "Received notification " notification-type)
                   (if (= "SubscriptionConfirmation" notification-type)
                     (do
                       (println "Responding to confirmation" )
                       (let [json (json/read-str (slurp body))]
                         (println json)
                         (http/get (get json "SubscribeURL"))))
                     (do
                       (println "Scheduling")
                       (schedule-reminders)
                       (-> (reminders/get-ready)
                           (reminders/send-emails)))))
                 
                 {:status 200
                  :body "{}"
                  :headers {"Content-Type" "application/edn"}})
           (wrap-routes
            (PUT "/:id" {:keys [ edn-params] {:keys [id] } :route-params}
                 (let [id (if (int? id)
                            id
                            (Integer/parseInt id))]
                   (assert (not (:sent (reminders/get-by-id id))))
                   (reminders/update! id edn-params)
                   {:status 200
                    :body "{}"
                    :headers {"Content-Type" "application/edn"}})) 
            wrap-secure)))
