(ns yenu.routes.core
  (:require [yenu.layout :as layout]
            [compojure.core :refer [defroutes GET POST]]
            [ring.util.http-response :as response]
            [ring.util.response :refer [redirect file-response]]
            [yenu.helpers.images :as images]
            [hiccup.core :as h]
            [hiccup.page :as p]
            [clj-time.format :as time-format]
            [clj-time.core :as time]
            [yenu.config :refer [env]]
            [yenu.db.core :as db]))

(defn number-of-pages [images-on-page]
  (int (Math/ceil
        (/ (:count (db/get-image-count)) images-on-page))))

(defn page [number is-current? additional-class content]
  (h/html
   [:li {:class (cond-> "page-item" is-current? (str " " additional-class))}
    [:a.page-link {:href (str "/page/" number)} content]]))

(defn dots []
  (h/html [:li.page-item.disabled [:p.page-link "..."]]))

(defn pagelist [from to current]
  (for [p (range from (inc to))] (page p (= p current) "active" p)))

(defn pagination [num current]
  (if (< num 2)
    ""
    (h/html
     [:nav.pull-right.clearfix {:aria-label "Page navigation"}
      [:ul.pagination.d-none.d-sm-none.d-xs-none.d-md-flex
       (page (dec current) (= current 1) "disabled" (h/html [:span.fa.fa-arrow-left] " Prev"))
       (cond
         (< num 13) (pagelist 1 num current)
         (<= current 7) (h/html (pagelist 1 10 current) (dots) (pagelist (- num 1) num current))
         (>= current (- num 6)) (h/html (pagelist 1 2 current) (dots) (pagelist (- num 9) num current))
         :else (h/html (pagelist 1 2 current) (dots) (pagelist (- current 3) (+ current 3) current) (dots) (pagelist (- num 1) num current)))
       (page (inc current) (= current num) "disabled" (h/html "Next " [:span.fa.fa-arrow-right]))]]
     [:div.clearfix])))

(defn pagination-mobile [num current]
  (if (< num 2)
    ""
    (h/html
     [:ul.pagination.justify-content-end.d-md-none
      (page (dec current) (= current 1) "disabled" (h/html [:span.fa.fa-arrow-left] " Prev"))
      [:form.form-inline
       [:select#page-switcher.form-control
        (for [p (range 1 (inc num))]
          [:option (cond-> {:value p} (= p current) (assoc :selected "selected")) p])]]
      (page (inc current) (= current num) "disabled" (h/html "Next " [:span.fa.fa-arrow-right]))])))

(defn index-page [current request]
  (let [image-count (:images-per-page env)
        offset (* (dec current) image-count)
        pages (number-of-pages image-count)
        images (db/get-all-images {:offset offset :count image-count})]
    (layout/render-file "index.html"
                        {:images images
                         :flash (:flash request)
                         :pagination (pagination pages current)
                         :pagination-mobile (pagination-mobile pages current)})))

(defn detail-page [image-id request]
  (let [image (db/get-image {:id image-id})
        next-img (db/get-next-image {:image-date (:created_at image)})
        prev-img (db/get-prev-image {:image-date (:created_at image)})
        saved-author (get-in request [:cookies "author" :value])]
    (if (not (nil? image))
      (layout/render-file "detail.html"
                          {:image image
                           :flash (:flash request)
                           :next-image next-img 
                           :prev-image prev-img
                           :tags (db/get-tags-for-image {:id (:id image)})
                           :saved-author saved-author
                           :comments (db/get-comments-for-image {:image_id (:id image)})})
      (layout/error-page {:status 404
                          :title "page not found"}))))

(defn add-comment! [image-id request]
  (let [author (:author (:params request))
        comment (:comment (:params request))]
    (if  (not= comment "")
      (db/create-comment! {:image_id image-id
                           :author author
                           :comment comment}))
    (-> (redirect (str "/show/" image-id))
        (assoc :flash (if (not= comment "")
                        {:message "Thank you for your comment." :type "success"}
                        {:message "The comment was empty." :type "danger"}))
        (assoc-in [:cookies "author"]
                  {:value author
                   :path "/"
                   :max-age (* 60 60 24 30 12)}))))

(defn image-file [type hash ext]
  (let [filename (str hash "." ext)]
    (file-response (images/data-path "gallery" type filename))))

(defroutes core-routes
  (GET "/" []
       (redirect "/page/1"))
  (GET "/page/:page-number" [page-number :as request]
       (index-page (Integer. page-number) request))
  (GET "/show/:image-id" [image-id :as request]
       (detail-page image-id request))

  (POST "/add-comment/:image-id" [image-id :as request]
        (add-comment! image-id request))
  
  (GET ["/images/:type/:hash.:ext"
        ;;:type #"(normal|raw|thumbnails)"
        ;;:hash #"[0-9]+-[^.]+"
        ;;:ext #"(png|jpg)"
        ]
       [type hash ext]
       (image-file type hash ext)))
