(ns frontend.modules.outliner.op
  "Build outliner ops"
  (:require [datascript.impl.entity :as de]))

(def ^:private ^:dynamic *outliner-ops*
  "Stores outliner ops that are generated by the following calls"
  nil)

(defn- op-transact!
  [result]
  (when (nil? *outliner-ops*)
    (throw (js/Error. (str (name (first result)) " not used in (transact! ...)"))))
  (conj! *outliner-ops* result)
  result)

(defn save-block!
  [block & {:as opts}]
  (op-transact!
   (when-let [block' (if (de/entity? block)
                       (assoc (.-kv ^js block) :db/id (:db/id block))
                       block)]
     [:save-block [block' opts]])))

(defn insert-blocks!
  [blocks target-block opts]
  (op-transact!
   (let [id (:db/id target-block)]
    [:insert-blocks [blocks id opts]])))

(defn delete-blocks!
  [blocks opts]
  (op-transact!
   (let [ids (map :db/id blocks)]
     (when (seq ids)
       [:delete-blocks [ids opts]]))))

(defn move-blocks!
  [blocks target-block sibling?]
  (op-transact!
   (let [ids (map :db/id blocks)
        target-id (:db/id target-block)]
    [:move-blocks [ids target-id sibling?]])))

(defn move-blocks-up-down!
  [blocks up?]
  (op-transact!
   (let [ids (map :db/id blocks)]
    [:move-blocks-up-down [ids up?]])))

(defn indent-outdent-blocks!
  [blocks indent? & {:as opts}]
  (op-transact!
   (let [ids (map :db/id blocks)]
    [:indent-outdent-blocks [ids indent? opts]])))

(defn upsert-property!
  [property-id schema property-opts]
  (op-transact!
   [:upsert-property [property-id schema property-opts]]))

(defn set-block-property!
  [block-eid property-id value]
  (op-transact!
   [:set-block-property [block-eid property-id value]]))

(defn remove-block-property!
  [block-eid property-id]
  (op-transact!
   [:remove-block-property [block-eid property-id]]))

(defn delete-property-value!
  [block-eid property-id property-value]
  (op-transact!
   [:delete-property-value [block-eid property-id property-value]]))

(defn create-property-text-block!
  [block-id property-id value opts]
  (op-transact!
   [:create-property-text-block [block-id property-id value opts]]))

(defn batch-set-property!
  [block-ids property-id value]
  (op-transact!
   [:batch-set-property [block-ids property-id value]]))

(defn batch-remove-property!
  [block-ids property-id]
  (op-transact!
   [:batch-remove-property [block-ids property-id]]))

(defn class-add-property!
  [class-id property-id]
  (op-transact!
   [:class-add-property [class-id property-id]]))

(defn class-remove-property!
  [class-id property-id]
  (op-transact!
   [:class-remove-property [class-id property-id]]))

(defn upsert-closed-value!
  [property-id closed-value-config]
  (op-transact!
   [:upsert-closed-value [property-id closed-value-config]]))

(defn delete-closed-value!
  [property-id value-block-id]
  (op-transact!
   [:delete-closed-value [property-id value-block-id]]))

(defn add-existing-values-to-closed-values!
  [property-id values]
  (op-transact!
   [:add-existing-values-to-closed-values [property-id values]]))

(defn transact!
  [tx-data tx-meta]
  (op-transact!
   [:transact [tx-data tx-meta]]))

(defn create-page!
  [title options]
  (op-transact!
   [:create-page [title options]]))

(defn rename-page!
  [page-uuid new-name]
  (op-transact!
   [:rename-page [page-uuid new-name]]))

(defn delete-page!
  [page-uuid]
  (op-transact!
   [:delete-page [page-uuid]]))
