class CustomBulletin
  include Mongoid::Document
  include Mongoid::Timestamps

  include OrbitModel::Status
  include OrbitModel::Impression
  # encoding: utf-8
  include OrbitTag::Taggable
  include OrbitCategory::Categorizable
  include Slug
  require 'custom_bulletin_model/cache'
  include ::CustomBulletinModel::Cache
  attr_accessor :org_tag_ids
  def tags=(ids)
    self.org_tag_ids = self.tag_ids
    super(ids)
  end
  def []=(index,value)
    if index.to_s=='tags'
      self.org_tag_ids = self.tag_ids
    end
    super(index,value)
  end
  SubPart.class_eval { include CustomBulletinModel::Cache }
  Page.class_eval { include CustomBulletinModel::Cache }
  before_destroy do
    CustomAnnsCache.all.destroy
  end
  field :custom_module
  field :bind_uid
  field :image_display_class, type: String, default: "full-size-img" #3 choices: full-size-img , pull-left , pull-right
  field :add_to_calendar,type: Boolean,default: false
  field :calendar_start_date, :type => DateTime
  field :calendar_end_date, :type => DateTime
  field :calendar_all_day,type: Boolean,default: false
  field :calendar_type_id
  field :event_id
  field :page_id
  field :title, type: String, localize: true
  field :subtitle, localize: true
  field :text, localize: true
  field :create_user_id
  field :update_user_id
  field :public, :type => Boolean, :default => true
  field :postdate , :type => DateTime, :default => Time.now
  field :deadline , :type => DateTime
  field :rss2_sn
  field :approved, :type => Boolean, :default => false
  field :is_preview, :type => Boolean, :default => false
  field :expirable_created_at, type: DateTime
  field :rejected, :type => Boolean, :default => false
  field :reapproval, :type => Boolean, :default => false
  field :rejection_reason
  field :is_external_link, :type => Boolean, :default => false
  field :external_link
  field :display_subtitle, :type => Boolean, :default => false
  field :display_img, :type => Boolean, :default => false

  field :email_id
  field :email_sent, :type => Boolean, :default => false
  field :email_sentdate , :type => DateTime
  field :email_member_ids
  field :other_mailaddress
  field :image_description, localize: true
  field :top_end_date, :type => DateTime
  field :open_comment, :type => Boolean, :default => false
  field :comment_end_time, :type => DateTime
  field :comment_role, :type => Array, :default => []
  
  mount_uploader :image, ImageUploader

  has_many :custom_bulletin_links, :autosave => true, :dependent => :destroy
  has_many :custom_bulletin_files, :autosave => true, :dependent => :destroy
  has_many :custom_bulletin_comments, :autosave => true, :dependent => :destroy
  has_many :custom_bulletin_carousel_images, :autosave => true, :dependent => :destroy
  accepts_nested_attributes_for :custom_bulletin_files, :allow_destroy => true
  accepts_nested_attributes_for :custom_bulletin_links, :allow_destroy => true
  accepts_nested_attributes_for :custom_bulletin_carousel_images, :allow_destroy => true

  before_destroy :destroy_email

  scope :can_display_and_sorted, ->{where(:is_hidden=>false,:is_preview => false).any_of({:postdate.lte=>Time.now, :deadline.gte=>Time.now},{:postdate.lte=>Time.now, :deadline=>nil},{:postdate=>nil}).order(is_top: :desc,postdate: :desc,id: :desc)}
  scope :is_approved, ->{where(:approved => true)}

  before_create :set_expire
  before_save :check_limit

  after_create do
    custom_record_callback(1)
  end
  after_destroy do
    custom_record_callback(-1)
  end
  def custom_record_callback(num)
    if self.custom_module && self.bind_uid.present?
      custom_bulletin_config = CustomBulletinConfig.where(:module=>self.custom_module).first
      if custom_bulletin_config && custom_bulletin_config.custom_record_callback.present? && custom_bulletin_config.bind_model.present?
        target_model = custom_bulletin_config.bind_model.constantize rescue nil
        if target_model
          target_record = target_model.where(custom_bulletin_config.uid_field=>self.bind_uid).first
          target_record.send(custom_bulletin_config.custom_record_callback,num) if target_record
        end
      end
    end
  end
  def to_calendar_param
    self.to_param
  end
  def calendar_type
    CalendarType.where(:category_id.in => self.calendar_type_id)
  end
  def event
    if !self.event_id.nil?
      Event.where(:id => self.event_id).first
    else
      nil
    end
  end
  def check_limit
    check_status_limit(update_user)
  end
  def check_status_limit(user,check_only=false)
    role_ids = user.member_profile.roles.map(&:id) rescue []
    status_settings = (role_ids.collect do |role_id|
      CustomAnnouncementSetting.first.custom_anns_status_settings.select{|v| v.role_id.to_s == role_id.to_s}
    end.flatten rescue [])
    reach_limit = []
    if status_settings.count != 0
      reach_limit = status_settings.collect do |status_setting|
        status = status_setting.status
        if status_setting.top_limit.to_i <= CustomBulletin.where(:update_user_id.in => Role.find(status_setting.role_id).member_profiles.collect(&:user).flatten.uniq.map{|v| v.id},status => true).count
          if !check_only
            if self[status] && !CustomBulletin.where(id:self.id).first[status]
              self[status] = false
              nil
            end
          else
            status
          end
        else
          nil
        end
      end.compact
      reach_limit = reach_limit.group_by{|v| v}.collect do |k,v|
                      if v.count >= user.member_profile.roles.count
                        k
                      else
                        nil
                      end
                    end.compact
    end
    reach_limit
  end
  def slug_title
    doc = Nokogiri::HTML(self.title)
    title = doc.text.gsub('/','-')
  end
  def set_expire
    self.expirable_created_at = Time.now if self.is_preview
    return true
  end

  def update_user
    User.find(update_user_id) rescue nil
  end

  def update_user=(user)
    self.update_user_id = user.id
  end

  def email_members
    MemberProfile.find(self.email_member_ids) rescue []
  end

  def email_addresses
    addresses = self.email_members.collect{|member| member.email} rescue []
    addresses = addresses +[self.other_mailaddress] if !self.other_mailaddress.blank?
    addresses.flatten
  end

  def email
    mail = Email.find(self.email_id) rescue nil
  end

  def expired?
    (self.deadline < Time.now) rescue false
  end

  def destroy_email
    mail = Email.find(self.email_id) rescue nil
    mail.destroy if !mail.nil?
  end

  def self.remove_expired_status
    self.where(:is_top => true, :top_end_date.ne => nil, :top_end_date.lt => Time.now).each do |b|
      b.is_top = false
      b.top_end_date = nil
      b.save
    end
  end

  def display_subtitle?
    self.display_subtitle rescue false
  end

  def display_img?
    self.display_img rescue false
  end
  def comments
    self.custom_bulletin_comments.select{|v| !v.is_hidden}
  end
  def open_comment_for_user(user)
    role_ids = user.member_profile.roles.collect{|v| v.id.to_s} rescue ['visitor']
    self.open_comment && (self.comment_end_time.blank? || self.comment_end_time > Time.now) && (self.comment_role.any?{|v| role_ids.include?(v)} || self.comment_role.include?('visitor') || (self.comment_role.include?('all_member') && role_ids[0] != 'visitor'))
  end
  def statuses
        statuses = []
        statuses << top_text if is_top?
        statuses << hot_text if is_hot?
        statuses << hidden_text if is_hidden?
        statuses
      end
  def statuses_with_classname
    statuses = []
    statuses << {"name" => top_text, "classname" => "top"} if is_top?
    statuses << {"name" => hot_text, "classname" => "hot"} if is_hot?
    statuses << {"name" => hidden_text, "classname" => "hidden"} if is_hidden?
    statuses
  end
  def status_for_table
    status = ""
    status << "<span class='label label-success'>#{top_text}</span> " if self.is_top
    status << "<span class='label label-important'>#{hot_text}</span> " if self.is_hot
    status << "<span class='label'>#{hidden_text}</span>"if self.is_hidden
    status.html_safe
  end
  def top_text
    I18n.t("custom_announcement.status.top")
  end
  def hot_text
    I18n.t("custom_announcement.status.hot")
  end
  def hidden_text
    I18n.t("custom_announcement.status.hidden")
  end
end
