(ns auto-ap.views.pages.import-invoices
  (:require [re-frame.core :as re-frame]
            [reagent.core :as reagent]
            [auto-ap.events :as events]
            [auto-ap.subs :as subs]
            [auto-ap.entities.clients :as client]
            [auto-ap.views.components.layouts :refer [side-bar-layout]]
            [auto-ap.views.components.invoices.side-bar :refer [invoices-side-bar]]
            [auto-ap.views.utils :refer [dispatch-event]]
            [auto-ap.entities.vendors :as vendor]
            [auto-ap.views.components.invoice-table :refer [invoice-table] :as invoice-table]
            [cljsjs.dropzone :as dropzone]
            [cljs.reader :as edn]))
(def dropzone
  (let [client (re-frame/subscribe [::subs/client])
        token (re-frame/subscribe [::subs/token])]
    (with-meta
      (fn []
        [:form.dz {:action "/api/invoices/upload"}
         [:div.tile.notification
          [:div.has-text-centered {:style {:padding "80px 0px" :width "100%"}}
           [:span
            [:span {:class "icon"}
             [:i {:class "fa fa-cloud-download"}]]
            "Drop any invoices you want to process here"]]]])
      {:component-did-mount (fn [this]
                              (js/Dropzone. (reagent/dom-node this)
                                            (clj->js {:init (fn []
                                                              (.on (js-this) "success" (fn [_ files]
                                                                                         (re-frame/dispatch [::invalidated]))))
                                                      :paramName "file"
                                                      :headers {"Authorization" (str "Token " @token)}
                                                      :url (str "/api/invoices/upload"
                                                                (when-let [client-name (-> @client :id)]
                                                                  (str "?client=" client-name)))
                                                      :previewsContainer "#dz-hidden"
                                                      :previewTemplate "<div class='dz-hidden-preview'></div>"})))})))

(re-frame/reg-sub
 ::invoice-page
 (fn [db]
   (-> db ::invoice-page)))

(re-frame/reg-sub
 ::params
 (fn [db]
   (-> db (::params {}))))

(re-frame/reg-event-fx
 ::invalidated
 (fn [cofx [_ params]]
   {:dispatch [::params-change @(re-frame/subscribe [::params])]}))

(re-frame/reg-event-fx
 ::params-change
 (fn [cofx [_ params]]
   
   {:db (-> (:db cofx)
            (assoc-in  [:status :loading] true)
            (assoc-in [::params] params))
    :graphql {:token (-> cofx :db :user)
              :query-obj (invoice-table/query (assoc params :import-status "pending")) 
              :on-success [::received]}}))

(re-frame/reg-event-db
 ::received
 (fn [db [_ data]]
   (-> db
       (assoc ::invoice-page (first (:invoice-page data)))
       (assoc-in [:status :loading] false))))

(re-frame/reg-event-fx
 ::reject-invoices-clicked
 (fn  [{:keys [db]} [_ invoices on-success]]
   {:graphql
    {:token (-> db :user)
     :query-obj {:venia/operation {:operation/type :mutation
                                   :operation/name "RejectInvoices"}
                 
                 :venia/queries [[:reject-invoices
                                  {:invoices (keys invoices)}
                                  []]]}  
     :on-success [::invalidated]}
    }))

(re-frame/reg-event-fx
 ::approve-invoices-clicked
 (fn  [{:keys [db]} [_ invoices on-success]]
   {:graphql
    {:token (-> db :user)
     :query-obj {:venia/operation {:operation/type :mutation
                                   :operation/name "ApproveInvoices"}
                 
                 :venia/queries [[:approve-invoices
                                  {:invoices (keys invoices)}
                                  []]]}  
     :on-success [::invalidated]}
    }))

(re-frame/reg-event-fx
 ::approve-invoices
 (fn  [cofx [_ on-success]]
   {:http {:method :post
           :token (-> cofx :db :user)
           :uri (str "/api/invoices/approve"
                     (when-let [client-id (:id @(re-frame/subscribe [::subs/client]))]
                       (str "?client=" client-id)))
           :on-success on-success
           }}))

(re-frame/reg-event-db
 ::toggle-check
 (fn [db [_ id invoice]]
   (-> db
       (update-in [::invoice-page :checked] (fn [x]
                                              (let [x (or x {})]
                                                (if (x id)
                                                  (dissoc x id)
                                                  (assoc x id invoice))))))))

(defn approve-reject-button [checked]
  [:div.is-pulled-right
  
   [:button.button.is-success {:on-click (dispatch-event [::approve-invoices-clicked checked])
                               :disabled (if (seq checked)
                                           ""
                                           "disabled")}
    "Approve "
    (when (> (count checked ))
      (str 
       (count checked)
       " invoices"))
    
    
    [:span " "]]
   [:button.button.is-danger {:on-click (dispatch-event [::reject-invoices-clicked checked])
                               :disabled (if (seq checked)
                                           ""
                                           "disabled")}
    "Reject "
    (when (> (count checked ))
      (str 
       (count checked)
       " invoices"))
    
    
    [:span " "]
    ]])

(def import-invoices-content
  (with-meta
    (fn []
      (let [invoice-page (re-frame/subscribe [::invoice-page])
            status (re-frame/subscribe [::subs/status])]
        [:div
         [:h1.title "Upload invoices"]
         [dropzone]
         
         [:div {:class "section"}]
         [:div {:class "card found-invoices",}
          [:div {:class "card-header"}
           [:span {:class "card-header-title"} "Found Invoices"]]
          [:div {:class "card-content"}
           [approve-reject-button (:checked @invoice-page)]
           (if (:loading @status)
             [:h1.title
              [:i.fa.fa-spin.fa-spinner]]
             (if (seq (:invoices @invoice-page))
               [invoice-table {:id :approved
                               :invoice-page  invoice-page
                               :check-boxes true
                               :checked (:checked @invoice-page)
                               :on-check-changed (fn [which invoice]
                                                   (re-frame/dispatch [::toggle-check which invoice]))
                               :status (re-frame/subscribe [::subs/status])
                               :params (re-frame/subscribe [::params])
                               :on-params-change (fn [params]
                                                   (re-frame/dispatch [::params-change params])) }]
               [:span "No pending invoices"]))]]]))
    {:component-will-mount (fn []
                             (re-frame/dispatch-sync [::invalidated]))}))

(defn import-invoices-page []
  [side-bar-layout {:side-bar [invoices-side-bar {}]
                    :main [import-invoices-content ]}])


