(ns wanijo.schema.routes
  (:require [compojure.core :refer [defroutes GET POST DELETE] :as comp]
            [ring.util.response :as resp]
            [formulare.core :as form]
            [wanijo.infrastructure.routing :refer [register! path]]
            [wanijo.user.db :as domain-user]
            [wanijo.schema
             [view :as schema-view]
             [forms :as schema-forms]
             [db :as domain]
             [middleware :as middleware]]
            [wanijo.attribute.db :as db-attr]))

(defn new! [req]
  (if (form/valid? schema-forms/schema req)
    (do
      (domain/create-new!
       (get-in req [:params :name])
       (get-in req [:session :uuid]))
      (resp/redirect (path :schema-overview)))
    (schema-view/overview! req)))

(defn delete-schema! [uuid]
  (domain/delete! uuid)
  (resp/redirect (path :schema-overview)))

(defn view! [uuid req]
  (schema-view/show-schema!
   (domain/find-with-assigned-entities! uuid)
   (db-attr/find-by-schema! uuid)
   (assoc-in schema-forms/assign-form
             [:fields :assigned :options]
             (map #(vector (:ident %) (:uuid %))
                  (domain-user/all!)))
   (assoc-in schema-forms/schema-connections-form
             [:fields :connections :options]
             (map #(vector (:name %) (:uuid %))
                  (domain/all!)))
   req))

(defn edit! [req]
  (let [uuid (get-in req [:params :uuid])]
    (if (form/valid? schema-forms/schema req)
      (do
        (domain/edit! (:params req))
        (resp/redirect (path :schema-show (:params req))))
      (view! uuid req))))

(defn assign-users! [req]
  (let [{:keys [uuid assigned]} (form/form-data schema-forms/assign-form req)
        permission (get-in req [:params :permission])]
    (if (form/valid? schema-forms/assign-form req)
      (do
        (domain/assign-users! uuid assigned permission)
        (resp/redirect (path :schema-show (:params req))))
      (view! uuid req))))

(defn assign-schemas! [req]
  (let [form schema-forms/schema-connections-form
        {:keys [uuid connections]} (form/form-data form req)]
    (if (form/valid? form req)
      (do
        (domain/assign-schemas! uuid connections)
        (resp/redirect (path :schema-show (:params req))))
      (view! uuid req))))

(defroutes write-routes
  (POST (register! :schema-edit "/schema/edit") []
        edit!)
  (POST (register! :schema-assign-users "/schema/assign/users") []
        assign-users!)
  (POST (register! :schema-assign-schemas "/schema/assign/schemas") []
        assign-schemas!)
  (DELETE (register! :schema-delete "/schema/:uuid")
          [uuid]
          (delete-schema! uuid)))

(defroutes read-routes
  (GET (register! :schema-show "/schema/:uuid")
       [uuid :as req]
       (view! uuid req)))

(defroutes routes
  (GET (register! :schema-overview "/schema") []
       schema-view/overview!)
  (POST (register! :schema-new "/schema/new") []
        new!)
  (comp/wrap-routes read-routes
                    (middleware/wrap-allowed-to-read!
                     #(get-in % [:route-params :uuid])))
  (comp/wrap-routes write-routes
                    (middleware/wrap-allowed-to-write!)))
