class Supplier
  include SimplyStored::Couch
  include ActiveModel::SerializerSupport
  include Supplier::Counters

  #devise :database_authenticatable, :recoverable, :rememberable, :trackable, :registerable, :confirmable

  property :name
  property :email
  property :open, type: :boolean, default: false
  property :time_zone, default: 'UTC'
  property :night_offset, type: Fixnum, default: 0 # Minutes
  property :address
  property :house_number
  property :house_number_addition
  property :postal_code
  property :city
  property :country, default: 'Netherlands'
  property :facebook_promotion_url
  property :week_starts_on_monday, type: :boolean, default: true
  property :employee_settings_storage
  property :user_message

  # PAYMENT
  property :accept_bitpay, type: :boolean, default: false
  property :bitpay_number

  #LOCATION
  property :lat, type: Float #, default: 52.08062426379751
  property :lng, type: Float #, default: 4.312562942504883

  #WIFI
  property :offer_wifi
  property :wifi_ssid
  property :wifi_type
  property :wifi_password

  #REVIEWS
  property :iens_profile

  #has_many :orders, through: :lists
  has_many :products, dependent: :destroy
  has_many :product_variants
  has_many :product_categories, dependent: :destroy
  has_many :tables, dependent: :destroy
  has_many :lists, dependent: :destroy
  #has_many :lists, through: :tables
  has_many :orders, dependent: :destroy
  has_many :sections, dependent: :destroy
  has_and_belongs_to_many :employees, storing_keys: true
  has_many :employee_shifts

  view :by_name, key: :name

  alias_method :non_enriced_employees, :employees
  def employees
    @cached_enriched_employees ||= non_enriced_employees.tap { |es| es.each{ |e| e.enrich_with_settings(settings_for(e) ) }}
  end

  after_create :add_section_on_create

  validates :name, presence: true
  validates :iens_profile, numericality: {allow_blank: true}
  #validates :password, confirmation: true, presence: {if: ->(r){ r.new_record? }}

  def location=(val)
    lat, lng = val.is_a?(Array) ? val : val.strip.split(/[ ,]+/).map(&:to_f)
    self.lat = lat
    self.lng = lng
  end

  def location
    [lat, lng].join(',')
  end

  def add_manager(employee)
    add_employee employee unless employee_ids.include? employee.id
    settings = settings_for(employee)
    settings.is_manager!
    save and employee
  end

  after_method :add_employee do |result, employee|
    @employee_settings = nil
    employee.settings = settings_for(employee)
    result
  end

  def employee_settings
    @employee_settings ||= SupplierEmployeesSettings.new(self)
  end

  def settings_for(employee)
    employee_settings.for_employee(employee)
  end

  #TODO: depricate
  def active_orders(options = {})
    return @active_orders if @active_orders && @active_orders_options == options
    @active_orders_options = options
    @active_orders = options[:section_id] ? Order.active_for_supplier_and_section(self, options[:section_id]) : Order.active_for_supplier(id)
    @active_orders.include_relation(list: {table: :section}, product_orders: :order)
    @active_orders
  end

  # Tody, simplify to List.active_for_supplier(self)
  #TODO: depricate
  def active_lists(options = {})
    return @active_lists if @active_lists
    @active_lists = options[:section_id].present? ? List.active_for_supplier_and_section(self, options[:section_id]) : List.active_for_supplier(self)
    @active_lists.include_relations(table: :section, orders: {product_orders: :product})
    @active_lists
  end

  before_method :reload do
    @employees = nil
    @cached_enriched_employees = nil
    @employee_settings = nil
    @active_lists = nil
    @active_orders = nil
  end


  # Return the currently active tables for the supplier
  def active_tables(options = {})
    options[:section_id].present? ? tables.select{|t| t.section_id == options[:section_id]} : tables
  end

  def non_placed_tables
    tables.reject{|t| t.section_id.present? }
  end

  def open?
    open
  end
  def closed?
    !open?
  end

  def get_employee(id)
    return nil unless employee_ids.include?(id)
    employee = Employee.find id
    employee.settings = settings_for(employee)
    employee
  end

  def mark_as_open!
    self.open = true
    save
  end

  def mark_as_closed!
    self.open = false
    save
  end

  def serializable_hash(*)
    {
      id: id,
      name: name
    }
  end

  def as_json(*)
    serializable_hash
  end


  # Find a user by its confirmation token and try to confirm it.
  # If no user is found, returns a new user with an error.
  # If the user is already confirmed, create an error for the user
  # Options must have the confirmation_token
  #
  # Overwrite devise method for mail sending
  #def self.confirm_by_token(confirmation_token)
    #confirmable = find_or_initialize_with_error_by(:confirmation_token, confirmation_token)
    #send_creation_mail = confirmable.errors.empty? && !confirmable.confirmed?
    #confirmable.confirm! if confirmable.persisted?
    #confirmable.send_creation_notifications if send_creation_mail
    #confirmable
  #end

  # Send confirmation instructions by email
  #def send_confirmation_instructions(*args)
    #self.confirmation_token = nil if reconfirmation_required?
    #@reconfirmation_required = false

    #@bypass_postpone = true and generate_confirmation_token! if self.confirmation_token.blank?
    #self.devise_mailer.confirmation_instructions(self, confirmation_token).deliver_now
  #end

  def find_order(id)
    order = Order.find(id)
    raise SimplyStored::RecordNotFound unless order.supplier_id == self.id
    order
  end

  def send_creation_notifications
    SupplierMailer.creation(self).deliver_later
  end

  private

  def add_section_on_create
    @section = Section.create supplier: self, title: I18n.t('supplier.section.first_section_title')
  end


end
