(ns auto-ap.entities.clients
  (:require [clojure.spec.alpha :as s]
            [auto-ap.entities.shared :as shared]
            [clojure.string :as str]
            [auto-ap.entities.address :as address]))

(def email-regex #"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,63}$")
(s/def ::id int)

(s/def ::name ::shared/required-identifier)
(s/def ::code (s/and ::shared/required-identifier
                     #(re-matches #"[A-Z0-9\-]+" %)))
(s/def ::address (s/nilable ::address/address))

(s/def ::bank-name ::shared/required-identifier)
(s/def ::bank-code (s/nilable string?))
(s/def ::routing (s/nilable string?))
(s/def ::number ::shared/required-identifier)
(s/def ::type keyword?)
(s/def ::number string?)
(s/def ::yodlee-account-id string?)

(s/def ::checking-bank-account (s/and (s/keys :req-un [::code ::name ::bank-name  ::number ::type]
                                              :opt-un [::bank-code ::routing])
                                      #(= (:type %) :check)))

(s/def ::credit-account (s/and (s/keys :req-un [::code ::name ::bank-name  ::number ::type]
                                              :opt-un [])
                                      #(= (:type %) :credit)))

(s/def ::cash-account (s/and (s/keys :req-un [::type ::code ::name])
                             #(= (:type %) :cash)))
(s/def ::bank-account (s/or :cash ::cash-account
                            :checking ::checking-bank-account
                            :credit ::credit-account))
(s/def ::bank-accounts (s/coll-of ::bank-account))
;; disabled because graphql defaults to string representation
#_(s/def ::weekly-debits (s/nilable double?))
#_(s/def ::weekly-credits (s/nilable double?))

(s/def ::location string?)
(s/def ::locations (s/coll-of ::location :min-count 1))

(s/def ::email (s/nilable (s/and string? (s/or :is-email #(re-matches email-regex %)
                                               :is-empty #(= % "")))))


(s/def ::client (s/keys :req-un [::name ::code ::locations]
                         :opt-un [::email
                                  ::address
                                  #_::weekly-debits
                                  #_::weekely-credits
                                  ::bank-accounts
                                  ::id]))


(def client-spec (apply hash-map  (drop 1 (s/form ::client))))
(def all-keys (map #(keyword (name %)) (concat (:req-un client-spec) (:opt-un client-spec))))
