(ns wanijo.instance.forms
  (:require [wanijo.specs :as specs]))

(def form
  {:fields {:name {:label "Name"
                   :required true
                   :spec ::specs/req-name
                   :attrs {:autofocus true}}}})

(defn link-form [instances]
  {:fields {:name {:label "Name"}
            :instances {:label "Instances"
                        :widget :mselect
                        :size (min 40 (count instances))
                        :from-req #(if (vector? %) % [%])
                        :options (map #(vector (:name %)
                                               (:uuid %))
                                      instances)}}})

(defn bulk-link-form [link-forms]
  (map (fn [{:keys [schema form]}]
         (let [name-field (keyword (str "name[" (:uuid schema) "]"))
               instances-field (keyword (str "instances[" (:uuid schema) "]"))]
           {:schema schema
            :form (-> form
                      (assoc-in [:fields name-field]
                                (-> form :fields :name))
                      (update :fields dissoc :name)
                      (assoc-in [:fields instances-field]
                                (-> form :fields :instances))
                      (update :fields dissoc :instances))}))
       link-forms))

(defn attr-type->widget [attr-type]
  (case attr-type
    ("markdown" "text") :textarea
    :input))

(defn attr->field-id [attr]
  (keyword (str "attr-" (:uuid attr))))

(defn attr->field [attr]
  {:label (:name attr)
   :required (= 1 (:required attr))
   :widget (attr-type->widget (:type attr))})

(defn attr->uuid-field-id [attr]
  (keyword (str "attr-" (:uuid attr) "-prop-uuid")))

(defn with-attributes [attrs]
  (update form
          :fields
          (fn [fields]
            (reduce (fn [fields attr]
                      (assoc fields
                             (attr->field-id attr)
                             (attr->field attr)
                             (attr->uuid-field-id attr)
                             {:widget :hidden}))
                    fields
                    attrs))))

(defn form-data->instance [form-data attrs]
  {:name (:name form-data)
   :properties (map (fn [attr]
                      {:attribute attr
                       :value ((attr->field-id attr) form-data)
                       :uuid ((attr->uuid-field-id attr) form-data)})
                    attrs)})

(defn instance->form-data [instance]
  (merge {:name (:name instance)}
         (reduce #(assoc %1
                         (attr->field-id (:attribute %2))
                         (:value %2)
                         (attr->uuid-field-id (:attribute %2))
                         (:uuid %2))
                 {}
                 (:properties instance))))
