;; 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 Sucursal en España SL

(ns app.main.ui.ds.controls.utilities.input-field
  (:require-macros
   [app.main.style :as stl])
  (:require
   [app.common.data :as d]
   [app.main.constants :refer [max-input-length]]
   [app.main.ui.ds.foundations.assets.icon :refer [icon* icon-list]]
   [app.main.ui.ds.tooltip :refer [tooltip*]]
   [app.util.dom :as dom]
   [rumext.v2 :as mf]))

(def ^:private schema:input-field
  [:map
   [:class {:optional true} [:maybe :string]]
   [:aria-label {:optional true} [:maybe :string]]
   [:id :string]
   [:icon {:optional true}
    [:maybe [:and :string [:fn #(contains? icon-list %)]]]]
   [:text-icon {:optional true} [:maybe :string]]
   [:has-hint {:optional true} :boolean]
   [:hint-type {:optional true} [:maybe [:enum "hint" "error" "warning"]]]
   [:type {:optional true} :string]
   [:max-length {:optional true} :int]
   [:variant {:optional true} [:enum "seamless" "dense" "comfortable"]]
   [:slot-start {:optional true} [:maybe some?]]
   [:slot-end {:optional true} [:maybe some?]]])

(mf/defc input-field*
  {::mf/forward-ref true
   ::mf/schema schema:input-field}
  [{:keys [id icon text-icon class type
           has-hint hint-type
           max-length variant
           slot-start slot-end
           data-option-focused
           input-wrapper-ref
           aria-label] :rest props} ref]
  (let [input-ref (mf/use-ref)
        type  (d/nilv type "text")
        variant (d/nilv variant "dense")
        tooltip-id (mf/use-id)
        props (mf/spread-props props
                               {:class [class
                                        (stl/css-case
                                         :input true
                                         :input-with-icon (some? icon))]
                                :ref (or ref input-ref)
                                :aria-invalid (when (and has-hint
                                                         (= hint-type "error"))
                                                "true")
                                :aria-describedby (when has-hint
                                                    (str id "-hint"))
                                :aria-labelledby tooltip-id
                                :type (d/nilv type "text")
                                :id id
                                :max-length (d/nilv max-length max-input-length)})

        inside-class (stl/css-case :input-wrapper true
                                   :has-hint has-hint
                                   :hint-type-hint (= hint-type "hint")
                                   :hint-type-warning (= hint-type "warning")
                                   :hint-type-error (= hint-type "error")
                                   :variant-seamless (= variant "seamless")
                                   :variant-dense (= variant "dense")
                                   :variant-comfortable (= variant "comfortable"))
        on-icon-click
        (mf/use-fn
         (mf/deps ref)
         (fn [_event]
           (let [input-node (mf/ref-val ref)]
             (dom/select-node input-node)
             (dom/focus! input-node))))]

    [:div {:class [inside-class class]
           :ref input-wrapper-ref
           :data-option-focused data-option-focused}
     (when (some? slot-start)
       slot-start)
     (when (some? icon)
       [:> icon* {:icon-id icon
                  :class (stl/css :icon)
                  :size "s"
                  :on-click on-icon-click}])
     (when (some? text-icon)
       [:span {:class (stl/css :text-icon)}
        text-icon])
     (if aria-label
       [:> tooltip* {:content aria-label
                     :trigger-ref (or ref input-ref)
                     :class (stl/css :tooltip-wrapper)
                     :id tooltip-id}
        [:> "input" props]]
       [:> "input" props])
     (when (some? slot-end)
       slot-end)]))
