(ns auto-ap.events.admin.vendors
  (:require [re-frame.core :as re-frame]
            [clojure.spec.alpha :as s]
            [auto-ap.db :as db]
            [auto-ap.routes :as routes]
            [auto-ap.effects :as effects]
            [auto-ap.entities.vendors :as entity]

            [bidi.bidi :as bidi]))

(re-frame/reg-event-db
 ::edit
 (fn  [db [_ vendor-id]]
   (assoc-in db [:admin :vendor]
             (get  (:vendors db) vendor-id))))

(re-frame/reg-event-db
 ::new
 (fn  [db _]
   (assoc-in db [:admin :vendor]
             {})))

(re-frame/reg-event-fx
 ::save
 (fn  [{:keys [db]} _]
   (let [edited-vendor (get-in db [:admin :vendor])
         fx {:db (assoc-in db [:admin :vendor :saving?] true)}]
     (when (s/valid? ::entity/vendor edited-vendor)
       (if (:id edited-vendor)
         (assoc fx :http {:method :put
                          :token (:user db)
                          :body (pr-str edited-vendor)
                          :headers {"Content-Type" "application/edn"}
                          :uri (str "/api/vendors/" (:id edited-vendor))
                          :on-success [::save-complete]
                          :on-error [::save-error]})
         (assoc fx :http {:method :post
                          :token (:user db)
                          :body (pr-str edited-vendor)
                          :headers {"Content-Type" "application/edn"}
                          :uri (str "/api/vendors")
                          :on-success [::save-complete]
                          :on-error [::save-error]}))))))

(re-frame/reg-event-fx
 ::remind
 (fn  [{:keys [db] :as fx} [_ id]]
   { :http {:method :post
            :token (:user db)
            :headers {"Content-Type" "application/edn"}
            :uri (str "/api/vendors/" id "/remind")
            :on-success [::reminder-sent]
            :on-error [::failed "Failed to send reminder"]}
    :db (assoc-in db [:admin :banner] nil)}))

(re-frame/reg-event-db
 ::reminder-sent
 (fn  [db [_ error]]
   (-> db
       (assoc-in [:admin :banner] "Reminder sent!"))))

(re-frame/reg-event-db
 ::failed
 (fn  [db [_ error]]
   (-> db
       (assoc-in [:admin :banner] error))))

(re-frame/reg-event-db
 ::save-complete
 (fn  [db [_ vendor]]
   (-> db
       
       (assoc-in [:admin :vendor] nil)
       (assoc-in [:vendors (:id vendor)] vendor))))

(re-frame/reg-event-db
 ::save-error
 (fn  [db [_ vendor]]
   (-> db
       (assoc-in [:admin :vendor :error] true)
       (assoc-in [:admin :vendor :saving?] false))))

(re-frame/reg-event-db
 ::change
 (fn  [db [_ path value]]
   (assoc-in db (concat [:admin :vendor] path)
             value)))

(re-frame/reg-event-db
 ::add-relationship
 (fn  [db [_ ]]
   (-> db
       (update-in [:admin :vendor :relationships] #(conj (or % [])
                                                         {:account-number (get-in db [:admin :vendor :new-relationship-account-number])
                                                          :company-id (get-in db [:admin :vendor :new-relationship-company])}))
       (update-in [:admin :vendor] dissoc :new-relationship-account-number :new-relationship-company))))

(re-frame/reg-event-db
 ::remove-relationship
 (fn  [db [_ i]]
   (-> db
       (update-in [:admin :vendor :relationships] #(vec (concat (subvec % 0 i) (subvec % (min (count %) (inc i)))))))))

(re-frame/reg-event-fx
 ::mounted
 (fn  [{:keys [db]} _]
   {:http {:method :get
           :token (:user db)
           :uri "/api/vendors"
           :on-success [::received-vendors]}}))

(re-frame/reg-event-db
 ::received-vendors
 (fn  [db [_ vendors]]
   
   (assoc db :vendors (reduce (fn [vendors vendor]
                                (assoc vendors (:id vendor) vendor))
                              {}
                              vendors))))
