(ns auto-ap.views.pages.home
  (:require [auto-ap.views.components.layouts :refer [side-bar-layout]]
            [re-frame.core :as re-frame]
            [auto-ap.subs :as subs]
            [reagent.core :as r]))


(def pie-chart (r/adapt-react-class js/Recharts.PieChart))
(def pie (r/adapt-react-class js/Recharts.Pie))
(def bar-chart (r/adapt-react-class js/Recharts.BarChart))
(def x-axis (r/adapt-react-class js/Recharts.XAxis))
(def y-axis (r/adapt-react-class js/Recharts.YAxis))
(def bar (r/adapt-react-class js/Recharts.Bar))
(def legend (r/adapt-react-class js/Recharts.Legend))
(def cell (r/adapt-react-class js/Recharts.Cell))
(def tool-tip (r/adapt-react-class js/Recharts.Tooltip))

(def colors ["hsl(171, 100%, 41%)" "hsl(217, 71%, 53%)" "hsl(141, 71%, 48%)" "hsl(48, 100%, 67%)" "hsl(348, 100%, 61%)" "hsl(217, 71%, 53%)"])
(def light-colors ["hsl(171, 60%, 80%)" "hsl(217, 71%, 53%)" "hsl(141, 71%, 48%)" "hsl(48, 100%, 67%)" "hsl(348, 100%, 61%)" "hsl(217, 71%, 53%)"])

(defn make-pie-chart
  [{:keys [width height data]}]
  [pie-chart {:width width
             :height height}
   [pie {:fill "#82ca9d"
         :data data
         :dataKey "value"
         :inner-radius 20}
    (map (fn [x y]
           ^{:key y}
           [cell {:key y :fill (colors y)}]) data (range))
    ]
   [tool-tip]
   [legend]])

(defn make-bar-chart [{:keys [width height data]}]
  [bar-chart {:width width :height height :data data :fill "#FFFFFF"}
   [tool-tip]
   [bar {:dataKey "paid" :fill (get colors 0) :stackId "a" :name "Paid"}]
   [bar {:dataKey "unpaid" :fill (get light-colors 0) :stackId "a" :name "Unpaid"}]
   
   [x-axis {:dataKey "name"}]
   [y-axis]
   [legend]]
  )

(re-frame/reg-event-db
 ::received
 (fn [db [_ {:keys [expense-account-stats invoice-stats]}]]
   (let [expense-account-stats (->> expense-account-stats
                                    (map #(update % :total (fn [t] (js/parseFloat t))))
                                    (sort-by :total)
                                    (reverse)
                                    (take 5))
         top-5 (vec (take 5 expense-account-stats))
         rest (drop 5 expense-account-stats)
         other {:expense-account-id 0 :expense-account-name "Other" :total (reduce + 0 (map :total rest))}]
     (cond-> db
       (seq top-5)
       (assoc ::top-expense-categories (conj top-5 other))

       (seq invoice-stats)
       (assoc ::invoice-stats invoice-stats)


       )
     )))

(re-frame/reg-sub
 ::invoice-stats
 (fn [db]
   (println (::invoice-stats db))
   (::invoice-stats db)))

(re-frame/reg-sub
 ::top-expense-categories
 (fn [db]
   (::top-expense-categories db)))

(re-frame/reg-event-fx
 ::mounted
 (fn [{:keys [db]} _]
   {:db (assoc db ::top-expense-categories nil)
    :graphql {:token (-> db :user)
              :query-obj {:venia/queries [[:expense_account_stats
                                           {:client-id (:id @(re-frame/subscribe [::subs/client]))} 
                                           [:expense-account-id :total :expense-account-name]]
                                          [:invoice_stats
                                           {:client-id (:id @(re-frame/subscribe [::subs/client]))} 
                                           [:name :paid :unpaid]]]}
              :on-success [::received]}}))

(defn home-content []
  (let [client-id (-> @(re-frame/subscribe [::subs/client]) :id)]
    ^{:key client-id}
    [side-bar-layout {:side-bar [:div]
                      :main [:div [:h1.title "Home"]
                             [:h1.title.is-4 "Top expense categories"]
                             (let [expense-categories @(re-frame/subscribe [::top-expense-categories])]
                               (make-pie-chart {:width 800 :height 500 :data (clj->js
                                                                              (map (fn [x] {:name (:expense-account-name x) :value (:total x)}) expense-categories))}))
                             [:h1.title.is-4 "Upcoming Bills"]
                             (make-bar-chart {:width 800 :height 500 :data (clj->js
                                                                            @(re-frame/subscribe [::invoice-stats]))})]}]))


(defn home-page []
  (let [client-id (-> @(re-frame/subscribe [::subs/client]) :id)]
    (re-frame/dispatch [::mounted])
    ^{:key client-id} [home-content]))
