(ns wanijo.public.view
  (:require [hiccup.page :refer [html5 include-js include-css]]
            [hiccup.core :refer [h]]
            [markdown.core :as md]
            [clojure.string :as string]
            [wanijo.infrastructure.routing :refer [path]]
            [wanijo.infrastructure.time :refer [prettify-dt]]))

(defn breadcrumb [& links]
  [:nav
   [:ol.breadcrumb
    (into
     [:li.breadcrumb-item
      [:a {:href (path :public-index)}
       [:img {:src "/img/klammer.svg"}]
       "Start"]]
     links)]])

(defn layout [title content]
  (html5
   [:head
    [:meta {:charset "utf-8"}]
    [:meta {:name "viewport"
            :content "width=device-width,initial-scale=1,shrink-to-fit=no"}]
    [:title title " - Moxie!"]
    (include-css "/css/bootstrap.min.css"
                 "/css/public.css")
    (include-js "/js/jquery-3.4.1.min.js"
                "/js/bootstrap.min.js"
                "/js/scripts.js")]
   [:body
    [:nav.navbar.navbar-expand-lg.sticky-top.navbar-light
     [:a.navbar-brand {:href (path :public-index)}
      [:img.navbar__logo {:src "/img/trio-logo.svg"
                          :alt "logo"}]]
     [:button.navbar-toggler {:type "button"
                              :data-toggle "collapse"
                              :data-target "#navbar-content"}
      [:span.navbar-toggler-icon]]
     [:div#navbar-content.collapse.navbar-collapse.justify-content-end
      [:form.form-inline.mr-3.global-search
       {:action (path :public-search)}
       [:input.form-control {:type "search"
                             :placeholder "\uD83D\uDD0D ..."
                             :name "term"}]
       [:button.global-search__submit {:type "submit"}]]
      [:a {:href (path :auth-login)}
       "Login"]]]
    [:div.container-fluid.super-container
     [:menu.global-nav
      [:ol.global-nav__card-nav
       [:li.global-nav__card-nav-item
        [:a.global-nav__link {:href (path :public-coc {:coc "dev"})}
         "Development"]]
       [:li.global-nav__card-nav-item
        [:a.global-nav__link {:href (path :public-coc {:coc "prk"})}
         "Projekte"]]
       [:li.global-nav__card-nav-item
        [:a.global-nav__link {:href (path :public-coc {:coc "req"})}
         "Req. Eng."]]]]
     (into [:div.content] content)]]))

(defn index []
  (layout
   "Index"
   [[:main.main
     [:h1 "Schön, dass du da bist!"]
     [:h2 "Willkommen auf der TRIO-Wissensplattform"]
     [:p "Hier findest du das gesammelte Wissen unserer Kollegen."]
     [:p "Schau dich um. Vermisst du etwas? Dann sprich mit deinem CoC!"]
     [:p "Du möchtest dich weiterentwickeln?"
      "Dann gestalte selbst deinen Weg bei der TRIO und sprich"
      "deinen Vorgesetzten an"]]]))

(defn show-coc [coc roles-with-levels]
  (layout
   (h (:name coc))
   [[:main.main
     [:h1 "CoC " (h (:name coc))]
     [:div.table-responsive
      [:table.table.no-sort
       [:thead
        [:tr
         [:th "Rolle"]
         [:th "Erfahrungsstufe"]]]
       [:tbody
        (for [row roles-with-levels
              :let [{:keys [role levels]} row
                    level (first levels)]]
          (list
           [:tr
            [:td {:rowspan (max 1 (count levels))}
             [:a {:href (path :public-role
                              {:coc (:key coc)
                               :role (:uuid role)})}
              (h (:name role))]]
            [:td
             [:a {:href (path :public-level
                              {:coc (:key coc)
                               :level (:uuid level)})}
              (h (:name level))]]]
           (for [level (rest levels)]
             [:tr
              [:td [:a {:href (path :public-level
                                    {:coc (:key coc)
                                     :level (:uuid level)})}
                    (h (:name level))]]])))]]]]
    (breadcrumb
     [:li.breadcrumb-item.active (h (:name coc))])]))

(defn show-level [coc level modules-with-comps]
  (layout
   (h (:name level))
   [[:main.main
     [:h1 "Erfahrungsstufe " (h (:name level))]
     [:div.table-responsive
      [:table.table.no-sort
       [:thead
        [:tr
         [:th "Modul"]
         [:th "Komponente"]]]
       [:tbody
        (for [row modules-with-comps
              :let [{:keys [module comps]} row
                    compo (first comps)]]
          (list
           [:tr
            [:td {:rowspan (max 1 (count comps))}
             [:a {:href (path :public-module
                              {:coc (:key coc)
                               :module (:uuid module)})}
              (h (:name module))]]
            [:td (h (:name compo))]]
           (for [compo (rest comps)]
             [:tr
              [:td (h (:name compo))]])))]]]]
    (breadcrumb
      [:li.breadcrumb-item
       [:a {:href (path :public-coc
                        {:coc (:key coc)})}
        (h (:name coc))]]
      [:li.breadcrumb-item.active (h (:name level))])]))

(defn show-role [coc role modules-and-levels]
  (layout
   (h (:name role))
   [[:main.main
     [:h1 "Rolle " (h (:name role))]
     [:div.markdown-content
      (md/md-to-html-string (:desc role))]
     [:div.table-responsive
      [:table.table
       [:thead
        [:tr
         [:th "Modul"]
         [:th "Qualifikationsstufe"]]]
       [:tbody
        (for [{:keys [module level]} modules-and-levels]
          [:tr
           [:td
            [:a {:href (path :public-module
                             {:coc (:key coc)
                              :module (:uuid module)})}
             (h (:name module))]]
           [:td
            [:a {:href (path :public-level
                             {:coc (:key coc)
                              :level (:uuid level)})}
             (h (:name level))]]])]]]]
    (breadcrumb
     [:li.breadcrumb-item
      [:a {:href (path :public-coc {:coc (:key coc)})}
       (h (:name coc))]]
     [:li.breadcrumb-item.active (h (:name role))])]))

(defn show-module [coc module]
  (layout
    (h (:name module))
    [[:main.main
      [:h1 "Modul " (h (:name module))]
      [:div.markdown-content
       (md/md-to-html-string (:desc module))]
      [:h2 "Komponenten"]
      [:table.table
       [:thead
        [:tr
         [:th "Name"]]]
       [:tbody
        (for [comp (:components module)]
          [:tr
           [:td
            [:a {:href (path :public-comp
                             {:coc (:key coc)
                              :module (:uuid module)
                              :comp (:uuid comp)})}
             (h (:name comp))]]])]]]
     (breadcrumb
       [:li.breadcrumb-item
        [:a {:href (path :public-coc {:coc (:key coc)})}
         (h (:name coc))]]
       ;; link to role not possible
       ;; multiple roles could use this module
       [:li.breadcrumb-item.active (h (:name module))])]))

(defn show-comp [coc module comp]
  (layout
    (h (:name comp))
    [[:main.main
      [:h1 "Komponente " (h (:name comp))]
      [:div.markdown-content
       (md/md-to-html-string (:desc comp))]]
     (breadcrumb
       [:li.breadcrumb-item
        [:a {:href (path :public-coc {:coc (:key coc)})}
         (h (:name coc))]]
       [:li.breadcrumb-item
        [:a {:href (path :public-module
                         {:coc (:key coc)
                          :module (:uuid module)})}
         (h (:name module))]]
       [:li.breadcrumb-item.active (h (:name comp))])]))

(defn highlight-match [s term]
  (let [matches (re-find (re-pattern (str "(?im)^(.*)(" term ")(.*)$"))
                         (h s))]
    (str (nth matches 1)
         "<mark>"
         (nth matches 2)
         "</mark>"
         (last matches))))

(defn search-result-link [schema path-to-coc]
  (let [coc-key (name (:key (last path-to-coc)))
        find-uuid (fn [which]
                    (->> path-to-coc
                        (filter #(= which (-> % :schema :which)))
                        first
                        :uuid))]
    (case (:which schema)
      :coc (path :public-coc
                 {:coc coc-key})
      :role (path :public-role
                  {:coc coc-key
                   :role (find-uuid :role)})
      :level (path :public-level
                   {:coc coc-key
                    :level (find-uuid :level)})
      :module (path :public-module
                    {:coc coc-key
                     :module (find-uuid :module)})
      :component (path :public-comp
                       {:coc coc-key
                        :module (find-uuid :module)
                        :comp (find-uuid :component)}))))

(defn show-search-result [term results]
  (layout
    (str "Suche nach \"" (h term) "\"")
    [[:main.main
      [:h1 "Suchergebnisse für " [:q (h term)]]
      (when (empty? results)
        [:p.mt-5 "Es konnten keine Ergebnisse gefunden werden"])
      (when (seq results)
        [:div.list-group.mt-5
         (for [{:keys [name updated_at match
                       schema path-to-coc]} results]
           [:div.list-group-item.list-group-item-action
            [:div.d-flex.w-100.justify-content-between
             [:h5.mb-1
              [:a {:href (search-result-link schema path-to-coc)}
               (if (= match name)
                 (highlight-match name term)
                 (h name))]]
             [:small (prettify-dt updated_at)]]
            (when (not= match name)
              (list [:p.markdown-content
                     (md/md-to-html-string
                       (highlight-match match term))]))])])]]))
