(ns auto-ap.ssr.components.paginator
  (:require [auto-ap.ssr.svg :as svg]
            [auto-ap.ssr.components.inputs :as inputs]))

(defn bound [x y z]
  (cond
    (< z x)
    x
    (< y x)
    x
    (> y z)
    z
    :else 
    y))

(def elipsis-button
  [:p {:href "#", :class "flex items-center justify-center px-3 py-2 text-sm leading-tight text-gray-500 bg-white border border-gray-300 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400"} "..."])

(defn paginator-internal- [{:keys [start per-page end total a-params per-page-params]}]
  (let [per-page          (or per-page 25)
        max-buttons       5
        buttons-before    (Math/floor (/ max-buttons 2))
        total-pages       (long (Math/max (long 1) (long (Math/ceil (/ total per-page)))))
        current-page      (long (Math/floor (/ start per-page)))
        first-page-button (bound 0 (- current-page buttons-before) (- total-pages max-buttons))
        all-buttons       (into [] (for [x (range total-pages)]
                                     [:li  
                                      [:a (-> (a-params x)
                                              (update 
                                                :class #(cond-> %
                                                          true (str  " flex items-center justify-center px-3 py-2 text-sm leading-tight  border ")

                                                          (= current-page x)
                                                          (str " text-primary-600 bg-primary-50 border-primary-300 hover:bg-primary-100 hover:text-primary-700 dark:border-gray-700 dark:bg-gray-700 dark:text-white")

                                                          (not= current-page x)
                                                          (str " text-gray-500 bg-white border-gray-300 hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white")))
                                              (assoc :href "#"))
                                       [:div.htmx-indicator.flex.items-center
                                        (svg/spinner {:class "inline w-4 h-4 text-black"})]
                                       [:div.htmx-indicator-hidden 
                                        (inc x)]]]))


        last-page-button (Math/min (long total-pages) (long (+ max-buttons first-page-button)))

        extended-last-page-button (when (not= last-page-button total-pages)
                                    (list
                                      elipsis-button
                                      (last all-buttons)))

        extended-first-page-button (when (not= first-page-button 0)
                                     (list
                                        (first all-buttons)
                                        elipsis-button))]
    [:nav.flex.items-center.space-x-3
     [:span.text-sm.text-gray-500 "Per page"]
     (inputs/select- (merge per-page-params
                            {:options [[25 "25"]
                                                       [50 "50"]
                                                       [100 "100"]
                                                       [200 "200"]]
                             :value   per-page
                             :name "per-page"}))
     [:ul {:class "inline-flex items-stretch -space-x-px"}
      extended-first-page-button
      (apply list (subvec all-buttons first-page-button last-page-button))
      extended-last-page-button]]))

(defn paginator- [{:keys [start per-page end total a-params] :as params}]
  [:nav {:class "flex flex-col items-start justify-between p-4 space-y-3 md:flex-row md:items-center md:space-y-0", :aria-label "Table navigation"}
   [:span {:class "text-sm font-normal text-gray-500 dark:text-gray-400"}
    [:span {:class "font-semibold text-gray-900 dark:text-white"} (str (inc start)) "-" (str end) " of " (str total)]]
   (paginator-internal- params)])
