(ns __table__
  (:require [coast]
            [components :refer [container tc link-to table thead tbody td th tr button-to text-muted mr2 dl dd dt submit input label]]))


(defn index [request]
  (let [rows (coast/q '[:select *
                        :from __table__
                        :order id
                        :limit 10])]
    (container {:mw 8}
     (when (not (empty? rows))
      (link-to (coast/url-for ::build) "New __table__"))

     (when (empty? rows)
      (tc
        (link-to (coast/url-for ::build) "New __table__")))

     (when (not (empty? rows))
       (table
        (thead
          (tr
            __table-headers__))
        (tbody
          (for [row rows]
            (tr
              __table-data__
              (td
                (link-to (coast/url-for ::view row) "View"))
              (td
                (link-to (coast/url-for ::edit row) "Edit"))
              (td
                (button-to (coast/action-for ::delete row) {:data-confirm "Are you sure?"} "Delete"))))))))))


(defn view [request]
  (let [id (-> request :params :__table__-id)
        __table__ (coast/fetch :__table__ id)]
    (container {:mw 8}
      (dl
        __data-elements__)
      (mr2
        (link-to (coast/url-for ::index) "List"))
      (mr2
        (link-to (coast/url-for ::edit {::id id}) "Edit"))
      (mr2
        (button-to (coast/action-for ::delete {::id id}) {:data-confirm "Are you sure?"} "Delete")))))


(defn errors [m]
  [:div {:class "bg-red white pa2 mb4 br1"}
   [:h2 {:class "f4 f-subheadline"} "Errors Detected"]
   [:dl
    (for [[k v] m]
      [:div {:class "mb3"}
       (dt (str k))
       (dd v)])]])


(defn build [request]
  (container {:mw 6}
    (when (some? (:errors request))
     (errors (:errors request)))

    (coast/form-for ::create
      __form-elements__

      (link-to (coast/url-for ::index) "Cancel")
      (submit "New __table__"))))


(defn create [request]
  (let [[_ errors] (-> (coast/validate (:params request) [[:required [__qualified-keywords__]]])
                       (select-keys [__qualified-keywords__])
                       (coast/insert)
                       (coast/rescue))]
    (if (nil? errors)
      (coast/redirect-to ::index)
      (build (merge request errors)))))


(defn edit [request]
  (let [__table__ (coast/fetch :__table__ (-> request :params :__table__-id))]
    (container {:mw 6}
      (when (some? (:errors request))
        (errors (:errors request)))

      (coast/form-for ::change __table__
        __edit-elements__

        (link-to (coast/url-for ::index) "Cancel")
        (submit "Update __table__")))))


(defn change [request]
  (let [__table__ (coast/fetch :__table__ (-> request :params :__table__-id))
        [_ errors] (-> (select-keys __table__ [:__table__/id])
                       (merge (:params request))
                       (coast/validate [[:required [__change-keywords__]]])
                       (select-keys [__change-keywords__])
                       (coast/update)
                       (coast/rescue))]
    (if (nil? errors)
      (coast/redirect-to ::index)
      (edit (merge request errors)))))


(defn delete [request]
  (let [[_ errors] (-> (coast/fetch :__table__ (-> request :params :__table__-id))
                       (coast/delete)
                       (coast/rescue))]
    (if (nil? errors)
      (coast/redirect-to ::index)
      (-> (coast/redirect-to ::index)
          (coast/flash "Something went wrong!")))))
