(ns auto-ap.ssr.hiccup-helper
  (:require [clojure.string :as str]
            [hiccup2.core :as hiccup]
            [hiccup.util :as hu]
            [clojure.set :as set]))


(defprotocol ClassHelper
  (add-class [this add])
  (remove-class [this remove])
  (replace-class [this remove add])
  (remove-wildcard [this wildcard])
  (replace-wildcard [this wildcard add])
  (replace-tw [this add]))

(defn string->class-list [n]
  (let [class-set (atom (set (str/split (or n "") #" ")))]
    (reify
      ClassHelper
      (add-class [this add]
        (if (sequential? add)
          (swap! class-set into add)
          (swap! class-set into (str/split (str (or add "")) #" ")))
        this)
      (remove-class [this remove]
        (if (sequential? remove)
          (swap! class-set set/difference (set remove))
          (swap! class-set disj remove))
        this)
      (replace-class [this remove add]
        (remove-class this remove)
        (add-class this add)
        this)
      (remove-wildcard [this wildcard]
        (if (sequential? wildcard)
          (reduce
           remove-wildcard
           this
           wildcard)
          (reduce
           remove-class
           this
           (filter (fn [c]
                     (str/starts-with? c wildcard)) @class-set)))
        this)
      (replace-wildcard [this wildcard add]
        (remove-wildcard this wildcard)
        (add-class this add)
        this)
      (replace-tw [this add]
        ;; TODO
        )
      Object
      (toString [this]
        (str/join " " @class-set)))))

(extend-protocol ClassHelper
  String
  (add-class [this add]
    (add-class (string->class-list this) add))
  (remove-class [this remove]
    (remove-class (string->class-list this) remove))
  (replace-class [this remove add]
    (replace-class (string->class-list this) remove add))
  (remove-wildcard [this wildcard]
    (remove-wildcard (string->class-list this) wildcard))
  (replace-wildcard [this wildcard add]
    (replace-wildcard (string->class-list this) wildcard add))
  (add-tw [this tw]
    (replace-tw (string->class-list this)
                tw)))


(str (hiccup/html [:div {:class (-> "hello bryce hello-1 hello-2"
                                    (replace-wildcard ["hello-" "b"] ["hi" "there"]))}]))
(str (hiccup/html [:div {:class (-> "p-1.5 "
                                    (add-class "bg-blue-500")
                                    #_(replace-wildcard ["hello-" "b"] ["hi" "there"]))}]))
