;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) KALEIDOS INC

(ns app.main.ui.viewer.header
  (:require-macros [app.main.style :as stl])
  (:require
   [app.common.data.macros :as dm]
   [app.main.data.modal :as modal]
   [app.main.data.shortcuts :as scd]
   [app.main.data.viewer :as dv]
   [app.main.data.viewer.shortcuts :as sc]
   [app.main.store :as st]
   [app.main.ui.components.dropdown :refer [dropdown]]
   [app.main.ui.export :refer [export-progress-widget]]
   [app.main.ui.formats :as fmt]
   [app.main.ui.icons :as i]
   [app.main.ui.viewer.comments :refer [comments-menu]]
   [app.main.ui.viewer.interactions :refer [flows-menu interactions-menu]]
   [app.util.dom :as dom]
   [app.util.i18n :refer [tr]]
   [okulary.core :as l]
   [rumext.v2 :as mf]))

(def fullscreen-ref
  (l/derived (fn [state]
               (dm/get-in state [:viewer-local :fullscreen?]))
             st/state))

(defn open-login-dialog
  []
  (modal/show! :login-register {}))

(mf/defc zoom-widget
  {::mf/memo true
   ::mf/props :obj}
  [{:keys [zoom
           on-increase
           on-decrease
           on-zoom-reset
           on-fullscreen
           on-zoom-fit
           on-zoom-fill]
    :as props}]

  (let [open*           (mf/use-state false)
        open?           (deref open*)
        open-dropdown
        (mf/use-fn
         (fn [event]
           (dom/stop-propagation event)
           (reset! open* true)))

        close-dropdown
        (mf/use-fn
         (fn [event]
           (dom/stop-propagation event)
           (reset! open* false)))

        on-increase
        (mf/use-fn
         (mf/deps on-increase)
         (fn [event]
           (dom/stop-propagation event)
           (on-increase)))

        on-decrease
        (mf/use-fn
         (mf/deps on-decrease)
         (fn [event]
           (dom/stop-propagation event)
           (on-decrease)))]

    [:div {:class (stl/css-case :zoom-widget true
                                :selected open?)
           :on-click open-dropdown
           :title (tr "workspace.header.zoom")}
     [:span {:class (stl/css :label)} (fmt/format-percent zoom)]
     [:& dropdown {:show open?
                   :on-close close-dropdown}
      [:ul {:class (stl/css :dropdown)}
       [:li  {:class (stl/css :basic-zoom-bar)}
        [:span {:class (stl/css :zoom-btns)}
         [:button {:class (stl/css :zoom-btn)
                   :on-click on-decrease}
          [:span {:class (stl/css :zoom-icon)}
           i/remove-icon]]
         [:p  {:class (stl/css :zoom-text)}
          (fmt/format-percent zoom)]
         [:button {:class (stl/css :zoom-btn)
                   :on-click on-increase}
          [:span {:class (stl/css :zoom-icon)}
           i/add]]]
        [:button {:class (stl/css :reset-btn)
                  :on-click on-zoom-reset}
         (tr "workspace.header.reset-zoom")]]

       [:li {:class (stl/css :zoom-option)
             :on-click on-zoom-fit}
        (tr "workspace.header.zoom-fit")
        [:span  {:class (stl/css :shortcuts)}
         (for [sc (scd/split-sc (sc/get-tooltip :toggle-zoom-style))]
           [:span {:class (stl/css :shortcut-key)
                   :key (dm/str "zoom-fit-" sc)} sc])]]
       [:li {:class (stl/css :zoom-option)
             :on-click on-zoom-fill}
        (tr "workspace.header.zoom-fill")
        [:span  {:class (stl/css :shortcuts)}
         (for [sc (scd/split-sc (sc/get-tooltip :toggle-zoom-style))]
           [:span {:class (stl/css :shortcut-key)
                   :key (dm/str "zoom-fill-" sc)} sc])]]
       [:li {:class (stl/css :zoom-option)
             :on-click on-fullscreen}
        (tr "workspace.header.zoom-full-screen")
        [:span  {:class (stl/css :shortcuts)}
         (for [sc (scd/split-sc (sc/get-tooltip :toggle-fullscreen))]
           [:span {:class (stl/css :shortcut-key)
                   :key (dm/str "zoom-fullscreen-" sc)} sc])]]]]]))

(mf/defc header-options
  [{:keys [section zoom page file index permissions interactions-mode]}]
  (let [fullscreen?    (mf/deref fullscreen-ref)

        toggle-fullscreen
        (mf/use-fn
         (fn [] (st/emit! dv/toggle-fullscreen)))

        go-to-workspace
        (mf/use-fn
         (mf/deps page)
         (fn []
           (st/emit! (dv/go-to-workspace (:id page)))))

        open-share-dialog
        (mf/use-fn
         (mf/deps page)
         (fn []
           (modal/show! :share-link {:page page :file file})
           (modal/allow-click-outside!)))

        handle-increase
        (mf/use-fn
         #(st/emit! dv/increase-zoom))

        handle-decrease
        (mf/use-fn
         #(st/emit! dv/decrease-zoom))

        handle-zoom-reset
        (mf/use-fn
         #(st/emit! dv/reset-zoom))

        handle-zoom-fill
        (mf/use-fn
         #(st/emit! dv/zoom-to-fill))

        handle-zoom-fit
        (mf/use-fn
         #(st/emit! dv/zoom-to-fit))]

    [:div {:class (stl/css :options-zone)}
     [:& export-progress-widget]

     (case section
       :interactions [:*
                      (when index
                        [:& flows-menu {:page page :index index}])
                      [:& interactions-menu {:interactions-mode interactions-mode}]]
       :comments [:& comments-menu]
       [:div {:class (stl/css :view-options)}])

     [:& zoom-widget
      {:zoom zoom
       :on-increase handle-increase
       :on-decrease handle-decrease
       :on-zoom-reset handle-zoom-reset
       :on-zoom-fill handle-zoom-fill
       :on-zoom-fit  handle-zoom-fit
       :on-fullscreen toggle-fullscreen}]

     (when (:in-team permissions)
       [:span {:on-click go-to-workspace
               :class (stl/css :edit-btn)}
        i/curve])

     [:span {:title (tr "viewer.header.fullscreen")
             :class (stl/css-case :fullscreen-btn true
                                  :selected fullscreen?)
             :on-click toggle-fullscreen}
      i/expand]

     (when (and
            (:in-team permissions)
            (:is-admin permissions))
       [:button {:on-click open-share-dialog
                 :class (stl/css :share-btn)}
        (tr "labels.share")])

     (when-not (:is-logged permissions)
       [:span {:on-click open-login-dialog
               :class (stl/css :go-log-btn)} (tr "labels.log-or-sign")])]))

(mf/defc header-sitemap
  [{:keys [project file page frame toggle-thumbnails] :as props}]
  (let [project-name   (:name project)
        file-name      (:name file)
        page-name      (:name page)
        page-id        (:id page)
        frame-name     (:name frame)
        show-dropdown? (mf/use-state false)

        open-dropdown
        (mf/use-fn
         (fn []
           (reset! show-dropdown? true)))

        close-dropdown
        (mf/use-fn
         (fn []
           (reset! show-dropdown? false)))

        navigate-to
        (mf/use-fn
         (fn [page-id]
           (st/emit! (dv/go-to-page page-id))
           (reset! show-dropdown? false)))]

    [:div {:class (stl/css :sitemap-zone)
           :title (tr "viewer.header.sitemap")}
     [:span {:class (stl/css :project-name)} project-name]
     [:div {:class (stl/css :sitemap-text)}
      [:div {:class (stl/css :breadcrumb)
             :on-click open-dropdown}
       [:span  {:class (stl/css :breadcrumb-text)}
        (dm/str file-name " / " page-name)]
       [:span {:class (stl/css :icon)} i/arrow]
       [:span "/"]
       [:& dropdown {:show @show-dropdown?
                     :on-close close-dropdown}
        [:ul {:class (stl/css :dropdown-sitemap)}
         (for [id (get-in file [:data :pages])]
           [:li {:class (stl/css-case :dropdown-element true
                                      :selected (= page-id id))
                 :id (dm/str id)
                 :key (dm/str id)
                 :on-click (partial navigate-to id)}
            [:span {:class (stl/css :label)}
             (get-in file [:data :pages-index id :name])]
            (when (= page-id id)
              [:span {:class (stl/css :icon-check)} i/tick])])]]]
      [:div {:class (stl/css :current-frame)
             :id "current-frame"
             :on-click toggle-thumbnails}
       [:span {:class (stl/css :frame-name)} frame-name]
       [:span {:class (stl/css :icon)} i/arrow]]]]))

(mf/defc header
  [{:keys [project file page frame zoom section permissions index interactions-mode shown-thumbnails]}]
  (let [go-to-dashboard
        (mf/use-fn
         #(st/emit! (dv/go-to-dashboard)))

        go-to-inspect
        (mf/use-fn
         (mf/deps permissions)
         (fn []
           (if (:is-logged permissions)
             (st/emit! dv/close-thumbnails-panel
                       (dv/go-to-section :inspect))
             (open-login-dialog))))

        navigate
        (mf/use-fn
         (mf/deps permissions)
         (fn [event]
           (let [section (-> (dom/get-current-target event)
                             (dom/get-data "value")
                             (keyword))]
             (if (or (= section :interactions) (:is-logged permissions))
               (st/emit! (dv/go-to-section section))
               (open-login-dialog)))))

        toggle-thumbnails
        (mf/use-fn
         (fn []
           (st/emit! dv/toggle-thumbnails-panel)))


        close-thumbnails
        (mf/use-fn
         (mf/deps shown-thumbnails)
         (fn [_]
           (when shown-thumbnails
             (st/emit! dv/close-thumbnails-panel))))]


    [:header {:class (stl/css-case :viewer-header true
                                   :fullscreen (mf/deref fullscreen-ref))
              :on-click close-thumbnails}
     [:div {:class (stl/css :nav-zone)}
      ;; If the user doesn't have permission we disable the link
      [:a {:class (stl/css :home-link)
           :on-click go-to-dashboard
           :style {:cursor (when-not (:in-team permissions) "auto")
                   :pointer-events (when-not (:in-team permissions) "none")}}
       [:span {:class (stl/css :logo-icon)}
        i/logo-icon]]

      [:& header-sitemap {:project project
                          :file file
                          :page page
                          :frame frame
                          :toggle-thumbnails toggle-thumbnails
                          :index index}]]

     [:div {:class (stl/css :mode-zone)}
      [:button {:on-click navigate
                :data-value "interactions"
                :class (stl/css-case :mode-zone-btn true
                                     :selected (= section :interactions))
                :title (tr "viewer.header.interactions-section" (sc/get-tooltip :open-interactions))}
       i/play]

      (when (or (:in-team permissions)
                (= (:who-comment permissions) "all"))
        [:button {:on-click navigate
                  :data-value "comments"
                  :class (stl/css-case :mode-zone-btn true
                                       :selected (= section :comments))
                  :title (tr "viewer.header.comments-section" (sc/get-tooltip :open-comments))}
         i/comments])

      (when (or (:in-team permissions)
                (and (= (:type permissions) :share-link)
                     (= (:who-inspect permissions) "all")))
        [:button {:on-click go-to-inspect
                  :class (stl/css-case :mode-zone-btn true
                                       :selected (= section :inspect))
                  :title (tr "viewer.header.inspect-section" (sc/get-tooltip :open-inspect))}
         i/code])]

     [:& header-options {:section section
                         :permissions permissions
                         :page page
                         :file file
                         :index index
                         :zoom zoom
                         :interactions-mode interactions-mode}]]))
