(ns com.oly.static-sites.do-blog.core
  (:require [ajax.core :refer [GET text-response-format]]
            [com.oly.static-sites.do-blog.theme :refer [tachyon-theme]]
            [cl-eorg.html :refer [org->to-hiccup]]
            [cl-eorg.parser :as parser]
            [cljs.reader :as reader]
            [datascript.core :as d]
            [clojure.string :as str]
            [reagent.core :as r]
            [reagent.dom :as dom]
            [reitit.frontend :as rf]
            [reitit.frontend.easy :as rfe]
            [tachyons.cards :refer [profile-card]]
            [clojure.core.async :refer [<! >! chan go]]
            [tick.core :as t]
            [tick.timezone]
            [tick.locale-en-us]
            ;; [cljsjs.js-joda-timezone]
            ;; [henryw374.js-joda-locale_en-us]
            [com.oly.static-sites.do-blog.pages.components.core :refer [ui-tags title-text-image article-list-author-media-flipped]]
            [com.oly.static-sites.do-blog.pages.helpers.database
             :refer [state document conn schema latest-article search-articles]]
            ;; [com.oly.static-sites.ui-hiccup.interface :refer [board square]]
            ;; [com.oly.static-sites.do-blog.pages.chess.render :refer [draw-board]]
            ;; [com.oly.static-sites.do-blog.pages.chess.state :refer [start-state]]
            [com.oly.static-sites.do-blog.pages.home :refer [home-page]]
            [com.oly.static-sites.do-blog.pages.article :refer [article-page]]
            [com.oly.static-sites.do-blog.pages.archive :refer [archive-page]]
            [com.oly.static-sites.do-blog.pages.chess-board :refer [chess-page]]
            [com.oly.static-sites.do-blog.pages.about :refer [about-page]])
  (:require-macros [cl-eorg.macros :refer [org-doc->move-process inline-filelist-map]]))


;(set! js/JSJoda (.use js/JSJoda js/JSJodaLocale))

(inline-filelist-map "bases/do-blog/resources/documents/")

(org-doc->move-process
 "bases/do-blog/resources/documents/"
 "bases/do-blog/resources/public/documents/")

(d/listen!
 conn
 (fn [tx-report]
   ;; Only update if data was modified
   (when (:tx-data tx-report)
     (swap! state update :new-data inc))))

(defn convert-date [text]
  (when text
    (let [parts (-> text
                    clojure.string/trim
                    (clojure.string/split #" "))]
      (-> (t/date (first parts))))))


(defn href
  "Build up path to document"
  [doc]
  (str (rfe/href :posts {:path ""}) (:relative-path doc)))

(defn fetch-document-cb [doc callback]
  (GET (str "/documents/" doc)
    {:response-format (text-response-format)
     :handler callback}))

(defn org-dsl-render
  "Render and store parsed documents"
  [doc]
  (swap! state assoc-in [:document :body] (parser/parse doc))
  (swap! state assoc-in [:document :hiccup] (into [:div] (vec (rest (org->to-hiccup tachyon-theme (-> @state :document :body))))))
  (swap! state assoc-in [:document :details] (parser/filter-root-nodes [] (-> @state :document :body))))

(defn render-doc-from-path [path]
  (if path 
    (let [comm (r/atom (chan))]
      (fetch-document-cb path #(go (>! @comm %)))
      (go (reset! document (<! @comm))
          (swap! state assoc :search {:terms nil :results []})
          (org-dsl-render @document)))
    (prn (str "render from path nothing found ") path)))


(def router
  (rf/router
   [["/"
     {:name :homepage
      :init 'switch-to-latest
      :view #'home-page}]
    ["/archive/{*tag}"
     {:name :archive
      :view #'archive-page}]
    ["/tags/{*path}"
     {:name :tags
      :view 'post
      :parameters {:path string?}}]
    ["/chess"
     {:name :chess
      :view #'chess-page}]
    ["/about"
     {:name :about
      :view #'about-page}]
    #_["/book/{*path}"
     {:name :book
      :view 'book
      :parameters {:path string?}}]
    ["/posts/{*path}"
     {:name :posts
      :view #'article-page
      :state render-doc-from-path
      :parameters {:path string?}}]]))

(defn switch-to-latest
  [path-params]
   (-> (latest-article)
       (render-doc-from-path)))

(defn select-initial-page
  [path-params]
  (if path-params
    (render-doc-from-path path-params)
    (-> (latest-article)
        (render-doc-from-path))))

(defn ui-search [search]
  [:div
   [:input.w-100.center.input-reset.ba.b--black-20.pa2.mb2
    {:type "text"
     :placeholder "Search"
     :on-change (fn [evt]
                  (swap! state assoc :search {:active true})
                  (swap! state assoc :search {:terms  (-> evt .-target .-value)}))}]])

(defn ui-sidebar [{:keys [sidebar body]}]
  (let [search (r/atom "")]
    (fn [{:keys [sidebar body]}]
      [:div.h-100.flex.items-stretch
       [:div.dn.db-l.pa3.bg-blue {:style {:flex-basis "20rem" :flex-grow "1"}} sidebar]
       [:div.ma3.pa3 {:style {:flex-basis "0" :flex-grow "999"}}
        [ui-search search]
        body]])))

#_(defn ui-tags [meta]
    [:div (map-indexed
           (fn [idx tag]
             [:span.mr2 {:key idx}
              [pill-grow
               {:href (rfe/href :archive {:tag tag})
                :text tag}]])
           (-> meta :filetags extract-tags))])

#_(defn title-text-image [{:keys [title content] :as optional} tags]
    [:article.lh-copy.f4.mt-0
     [:h1.f2 title]
     (when tags
       [ui-tags tags])
     (when (:img-src optional)
       [:img.w-100.f5.measure {:src (:img-src optional) :alt (:img-alt optional)}])
     content])

(defn layout [content]
  (let [search (r/cursor state [:search :terms])
        active-search (r/cursor state [:search :active])
        org-index (r/cursor state [:index])]
    (fn [content]

      [:<>
       [:link {:rel "stylesheet" :href "https://unpkg.com/tachyons@4.12.0/css/tachyons.min.css"}]
       [:link {:rel "stylesheet" :href "https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.15.3/css/fontawesome.min.css"}]
       [:style
        ".font{font-family: \"Roboto Slab\",serif !important;}"
        ".r90{transition: all 3s; transform-style: preserve-3d; transform-origin: top left; transform: rotate3d(0,1,0,180deg);   backface-visibility: visible;}


        .r180-back{transition: all 3s; transform-style: preserve-3d; transform-origin: top left; transform: rotate3d(0,1,0,180deg);   backface-visibility: visible;}
        .r180-front{transition: all 3s; transform-style: preserve-3d; transform-origin: top left; transform: rotate3d(0,1,0,180deg);   backface-visibility: hidden;}
        .r0{transition: all 3s; transform-style: preserve-3d; transform-origin: top left; transform: rotate3d(0,1,0,0deg);   backface-visibility: visible;}"]
       [:div.font.h-100
        [ui-sidebar
         {:body [:div (when (true? @active-search)
                        [article-list-author-media-flipped
                         "Articles"
                         (search-articles {:search @search})])
                 content
                 ]
          :sidebar [:div
                    [profile-card {:name "Oly" :tagline "Earthling, Software Engineer" :img-src "/images/default/me.png"}]
                    [:ul.list.pl0.measure.center
                     [:li.lh-copy.pv3.b--black-30.ba.bt-0.bl-0.br-0
                      [:a.black.f3.link.hover-green
                       {:href (rfe/href :homepage)} "Home"]]
                     [:li.lh-copy.pv3.b--black-30.ba.bt-0.bl-0.br-0
                      [:a.black.f3.link.hover-green
                       {:href (rfe/href :archive {:tag ""})} "Past articles"]]
                     [:li.lh-copy.pv3.b--black-30.ba.bt-0.bl-0.br-0
                      [:a.black.f3.link.hover-green
                       {:href (rfe/href :chess)} "Chess"]]
                     [:li.lh-copy.pv3.b--black-30.ba.bt-0.bl-0.br-0
                      [:a.black.f3.link.hover-green
                       {:href (rfe/href :about)} "About"]]
                     #_[:li.lh-copy.pv3.b--black-30.ba.bt-0.bl-0.br-0
                        [:a.black.f3.link.hover-green
                         {:href (rfe/href :book {:path ""})} "Book test"]]]]}]]])))

(defn ^:dev/after-load reagent-render [hiccup]
  (swap! state update :refresh inc)
  (dom/render [hiccup] (js/document.getElementById "app")))


(defn render-page []
  (let [current-page (r/cursor state [:current-route])
        update (r/cursor state [:refresh])]
    ;; load in the latest document
    (fn []
      @update
      (swap! state assoc :search {:active false})
      (when (-> @current-page :data :init)
        ((-> @current-page :data :init) nil)
        ((-> @current-page :data :init) (-> @current-page :parameters :path :path)))
      (when (-> @current-page :data :state)
        ((-> @current-page :data :state) (-> @current-page :parameters :path :path)))
      [layout [(-> @current-page :data :view) (-> @current-page)]])))

(defn init []
  (rfe/start!
   router
   (fn [m]
     (prn m)
     (swap! state assoc
            :current-route m)
     (switch-to-latest (-> @state :current-route :parameters :path :path))
     )
   {:use-fragment false})

  (GET "/documents/org-meta-index.edn"
    {:handler (fn [response]
                (->> (reader/read-string response)
                     ;; filter out missing dates
                     (filter (fn [doc] (some? (:date doc))))
                     (mapv #(assoc % :tags (into [] (:filetags %))))
                     (mapv #(assoc % :date (convert-date (:date %))))
                     (swap! state assoc :index))
                (d/reset-conn! conn (d/empty-db schema))
                (d/transact! conn (:index @state))
                (select-initial-page (-> @state :current-route :parameters :path :path)))})
  (reagent-render render-page))

;;(comment )
;; (-> @state :document)
;; (latest-article)

; (switch-to-latest)
;; (org->to-hiccup tachyon-theme (-> @state :document :body))
