(ns yenu.layout
  (:require [selmer.parser :as parser]
            [selmer.filters :as filter]
            [ring.util.http-response :refer [content-type ok]]
            [ring.util.anti-forgery :refer [anti-forgery-field]]
            [yenu.helpers.images :as image-helper]
            [ring.middleware.anti-forgery :refer [*anti-forgery-token*]]
            [yenu.config :refer [env]]
            [yenu.db.core :as db]
            [digest :as digest]
            [java-time :refer [local-date-time]])
  (:use [markdown.core]))

(declare ^:dynamic *identity*)
(declare ^:dynamic *app-context*)
(parser/set-resource-path!  (clojure.java.io/resource "templates"))
(parser/add-tag! :csrf-field (fn [_ _] (anti-forgery-field)))
(filter/add-filter! :inc inc)
(filter/add-filter! :dec dec)
(filter/add-filter! :markdown-to-html md-to-html-string)
(filter/add-filter! :parse-date #(local-date-time "yyyy-MM-dd HH:mm:ss" %))

(defn footer []
  (if (= (:count (db/get-image-count)) 0)
    (clojure.string/join ", " (:authors env))
    (let [first-year (subs (:created_at (db/get-first-year)) 0 4)
          recent-year (subs (:created_at (db/get-recent-year)) 0 4)
          copy (if (= first-year recent-year) first-year (str first-year " - " recent-year))]
      (str "© " copy " " (:authors env)))))

(defn render-file [template & [params]]
  (content-type
   (ok
    (parser/render-file
     template
     (assoc params
            :page template
            :footer (footer)
            :csrf-token *anti-forgery-token*
            :servlet-context *app-context*
            :passwordhash (digest/md5 (:user-password env))
            :identity *identity*)))
   "text/html; charset=utf-8"))

(defn render [string contenttype]
  (content-type
   (-> (ok string)
       (assoc :servlet-context *app-context*
              :csrf-token *anti-forgery-token*
              :passwordhash (digest/md5 (:user-password env))
              :identity *identity*))
   (str contenttype "; charset=utf-8")))

(defn error-page
  "error-details should be a map containing the following keys:
   :status - error status
   :title - error title (optional)
   :message - detailed error message (optional)

   returns a response map with the error page as the body
   and the status specified by the status key"
  [error-details]
  {:status  (:status error-details)
   :headers {"Content-Type" "text/html; charset=utf-8"}
   :body    (parser/render-file "error.html" error-details)})
