(ns cheatsheet
  (:require [reagent.core :as r]))

(defonce tooltip-state (r/atom nil))

(defn matches-search? [item search]
  (let [search-lower (.toLowerCase search)
        name-match (when-let [n (:name item)]
                     (.includes (.toLowerCase n) search-lower))
        symbol-match (when-let [s (:symbol item)]
                       (.includes (.toLowerCase s) search-lower))]
    (or name-match symbol-match)))

(defn show-tooltip! [item e]
  (let [rect (.getBoundingClientRect (.-target e))
        x (.-left rect)
        y (+ (.-bottom rect) 5)]
    (reset! tooltip-state {:item item :x x :y y})))

(defn hide-tooltip! []
  (reset! tooltip-state nil))

(defn tooltip []
  (when-let [{:keys [item x y]} @tooltip-state]
    [:div.tooltip {:style {:left (str x "px") :top (str y "px")}}
     (when-let [sig (:signature item)]
       [:div.tooltip-sig sig])
     [:div.tooltip-desc (:description item)]
     (when-let [args (:args item)]
       [:div.tooltip-args
        (for [[idx arg] (map-indexed vector args)]
          ^{:key idx}
          [:span.tooltip-arg
           [:strong (:name arg)] ": " (:type arg)
           (when (:range arg) (str " (" (:range arg) ")"))])])
     (when-let [example (:example item)]
       [:pre.tooltip-example example])]))

(defn item-span [item]
  [:span.item-name
   {:on-mouse-enter #(show-tooltip! item %)
    :on-mouse-leave hide-tooltip!}
   (or (:name item) (:symbol item))])

;; Group items by a label (for mini-notation, we'll group differently)
(defn group-items-by-label [items]
  ;; For now, just return all items as one group
  ;; Later we can add :label to items for finer grouping
  [["" items]])

(defn category-table [category search]
  (let [all-items (:items category)
        filtered-items (if (empty? search)
                         all-items
                         (filter #(matches-search? % search) all-items))]
    (when (seq filtered-items)
      [:div.category-items
       [:div.item-row
        [:div.item-label (:name category)]
        [:div.item-content
         (for [[idx item] (map-indexed vector filtered-items)]
           ^{:key idx}
           [:<>
            [item-span item]
            (when (< idx (dec (count filtered-items))) " ")])]]])))

(defn sidebar [categories selected-category on-select]
  [:nav.sidebar
   [:ul.category-list
    [:li {:class (when (nil? selected-category) "selected")}
     [:a {:href "#"
          :on-click (fn [e] (.preventDefault e) (on-select nil))}
      "All"]]
    (for [cat categories]
      ^{:key (:id cat)}
      [:li {:class (when (= selected-category (:id cat)) "selected")}
       [:a {:href "#"
            :on-click (fn [e] (.preventDefault e) (on-select (:id cat)))}
        (:name cat)]])]])

(defn cheatsheet-view [state]
  (let [categories @(r/cursor state [:categories])
        search @(r/cursor state [:search])
        selected-category @(r/cursor state [:selected-category])
        visible-categories (if selected-category
                             (filter #(= (:id %) selected-category) categories)
                             categories)]
    [:div.cheatsheet
     [sidebar categories selected-category
      #(swap! state assoc :selected-category %)]
     [:main.content
      [:div.search-box
       [:input {:type "text"
                :placeholder "Search..."
                :value search
                :auto-focus true
                :on-change #(swap! state assoc :search (-> % .-target .-value))}]]
      [:div.categories
       (for [cat visible-categories]
         ^{:key (:id cat)}
         [category-table cat search])]]
     [tooltip]]))
