(ns auto-ap.views.pages.ledger.report-table
  (:require
   [clojure.string :as str]
   [auto-ap.views.utils :refer [->$ ->% dispatch-event]]))

(defn cell [{:keys [width click-event other-style]} c]
  (let [cell-contents (cond

                        (= :dollar (:format c))
                        (->$ (:value c))

                        (= :percent (:format c))
                        (->% (:value c))

                        :else
                        (str (:value c)))
        cell-contents (if (:filters c)
                        [:a {:on-click (dispatch-event [click-event (:filters c)])}
                         cell-contents]
                        cell-contents)]
    [:td
     (cond->  {:style (cond-> {:width (str width "em")}
                        other-style (merge other-style))}

       (:border c)              (update :style
                                        (fn [s]
                                          (->> (:border c)
                                               (map
                                                 (fn [b]
                                                   [(keyword (str "border-" (name b))) "1px solid black"])
                                                 )
                                               (into s)))) 
       (:colspan c)             (assoc :colspan (:colspan c))
       (:align c)               (assoc :align (:align c))
       (= :dollar (:format c))  (assoc :align :right)
       (= :percent (:format c)) (assoc :align :right)
       (:bold c)                (assoc-in [:style :font-weight] "bold")
       (:color c)               (assoc-in [:style :color] (str "rgb("
                                                               (str/join ","
                                                                         (:color c))
                                                               ")"))
        true               (assoc-in [:style :background-color] (str "rgb("
                                                               (str/join ","
                                                                         (or (:bg-color c) [255 255 255]))
                                                               ")")))

     cell-contents]))

(defn cell-count [table]
  (let [counts (map count (:rows table))]
    (if (seq counts)
      (apply max counts)
      0)))

(defn table [{:keys [table widths click-event]}]
  (let [cell-count (cell-count table)]
    [:div {:style {:height     "70vh"
                   :overflow-y "auto"}}
     (-> [:table.table.compact.balance-sheet 
          (map
            (fn [header-row header]
              (into ^{:key header-row}
                    [:tr]
                    (map
                      (fn [w header i]
                        ^{:key i} [cell {:width       w :click-event click-event
                                         :other-style {:position "sticky"
                                                       :top      (* header-row (+ 22 18))}} header])
                      widths
                      header
                      (range))))
            (range)
            (:header table))]

         (conj 
           (-> [:tbody {:style {}}]
               (into
                 (for [[i row] (map vector (range) (:rows table))]
                   ^{:key i}
                   [:tr
                    (for [[i c] (map vector (range) (take cell-count
                                                          (reduce 
                                                            (fn [[acc cnt] cur]
                                                              (if (>= (+ cnt (:colspan cur 1)) cell-count)
                                                                (reduced (conj acc cur))
                                                                [(conj acc cur) (+ cnt (:colspan cur 1))]))
                                                            [[] 0]
                                                            (concat row (repeat nil)))))]
                      ^{:key i}
                      [cell {:click-event click-event} c])]))
               (conj ^{:key "last"}
                     [:tr (for [i (range cell-count)]
                            ^{:key i}
                            [cell {:click-event click-event} {:value " "}])])))
         )]))

(defn concat-tables [tables]
  (let [[first & rest] tables]
    {:header (:header first)
     :rows   (concat (:rows first)
                     [[]]
                     (mapcat
                       (fn [table]
                         (-> (:header table)
                             (into (:rows table))
                             (conj [])))
                       rest))}))
