require 'mongoid'

class DigitalAsset
  include Mongoid::Document
  include Mongoid::Timestamps

  store_in :digital_assets_ssc2

  field :title, type: String
  field :changed_at, type: DateTime 
  field :audiences, type: Array, default: []
  field :sami_code, type: String
  field :published_at, type: DateTime 
  field :unpublished_at, type: DateTime 
  field :expires_at, type: DateTime 
  field :guid, type: String
  field :business_owner, type: String
  field :summary, type: String
  field :omniture_codes, type: Array, default: []
  field :orderable, :type => Boolean, default: false
  field :product_ids, type: Array, default: []
  field :program_ids, type: Array, default: []
  # refactor version:
  field :path, type: String
  field :legacy_path, type: String
  field :doc_changed_at, type: DateTime 
  field :content_type, type: String
  alias :doctype :content_type
  alias :doctype_id :content_type
  field :pages, type: Integer, default: 1
  field :size, type: String
  field :mime_type, type: String
  field :subject, type: String
  field :keywords, type: Array, default: []
  field :author, type: String
  field :finra_path, type: String
  field :fund_codes, type: Array, default: []
  field :digital_asset_id, type: String
  key :digital_asset_id

  #Exclude XBRL documents from all queries
  default_scope excludes(:content_type => "LDJDCMAIK") #Had to use static value instead of a Constant

  scope :title_is, ->(title) { where(:title => title)}
  scope :business_owner_is, ->(business_owner) { where(:business_owner => business_owner)}
  scope :guid_is, ->(guid) { where(:guid => guid)}
  scope :digital_asset_id_is, ->(id) { where(:digital_asset_id => id)}
  scope :fund_in, ->(fund_codes) {where(:fund_codes.in => fund_codes)}
  scope :audience_in, ->(audience_id) {where(:audiences.in => audience_id)}
  scope :audience_investor_approved, -> {where(:audiences.in => [Audience::INVESTOR_APPROVED])}

  scope :published_since, ->(since) {where(:published_at.gte => since)}
  scope :content_organization_in, ->(content_organization_id) {where(:content_organization_ids.in => content_organization_id)}
  scope :program_id_in, ->(program_id) {where(:program_ids.in => program_id)}
  scope :sami_is, ->(sami_code) {where(:sami_code => sami_code)}
  scope :sami_in, ->(sami_codes) {where(:sami_code.in => sami_codes)}
  scope :path_is, ->(path) {where(:'path' => path)}
  scope :legacy_path_is, ->(path) {where(:'legacy_path' => path)}
  scope :doctype_in, ->(types) {where(:'content_type'.in => types)}
  scope :content_type_in, ->(types) {where(:'content_type'.in => types)}
  scope :product_in, ->(types) {where(:product_ids.in => types)}
  scope :stale, -> {where(:updated_at.lte => 2.minutes.ago)}
  scope :orderable_is, ->(orderable) {where(:orderable => orderable)}
  scope :orderable, -> {where(orderable: true)}
  scope :audience_in, ->(audience) {where(:audiences.in => audience)}
  scope :alphabetical, order_by(:title => :asc)
  scope :not_xbrl, -> {excludes(:'content_type' => ContentType::XBRL_DOCUMENT)}
  scope :fund_docs, -> {where(:'content_type'.in => ContentType::FUND_DOC_TYPES)}

  # validations
  validates_presence_of :digital_asset_id, :title, :changed_at, :published_at,
      :expires_at, :audiences, :path
  validates_uniqueness_of :path, :digital_asset_id     
  validate :validate_future_expiration

  def guid
    super || digital_asset_id
  end

  def self.purge!
    DigitalAsset.stale.destroy_all if bulk_processed?
  end

  def latest_doc_changed_at
    doc_changed_at
  end

  def validate_future_expiration
    errors.add(:expires_at, "Expiration date must be at least 1 minute from now") unless expires_at and expires_at > 1.minute.from_now
  end

  def self.bulk_processed?
    (stale.count.to_f / self.count) <= 0.05
  end

  def has_finra?
    finra_path.present?
  end

  def expired?
    expires_at < Time.now
  end

  def is_investor_approved?
    audiences.index(DigitalAsset::Audience::INVESTOR_APPROVED)
  end
  alias :investor_approved? :is_investor_approved?

  def is_institutional_use?
    audiences.index(DigitalAsset::Audience::INSTITUTIONAL_USE)
  end
  alias :institutional_use? :is_institutional_use?

  def product
    TaxonomyTerm.label_for_term(product_ids[0])
  end
  def program
    TaxonomyTerm.label_for_term(program_ids[0])
  end
  def content_org
    TaxonomyTerm.label_for_term(content_organization_ids[0])
  end

  def content_type_label
    TaxonomyTerm.label_for_term(content_type)
  end

  def audience
    TaxonomyTerm.label_for_term(audiences[0])
  end

  def primary_path
    path
  end

  def primary_extension
    self.try(:path).try(:split,'.').try(:last).try(:upcase)
  end
end

# class DigitalAsset::Document
#   include Mongoid::Document

  

#   embedded_in :digital_asset

#   key :path

#   validates_uniqueness_of :path

#   validates_presence_of :path #, :doc_changed_at, :content_type
#   validates_format_of :path, without: /\/manifest|archives\// # dont accept manifest files

# end

class DigitalAsset::ContentType
  FINRA = '549'
  PROSPECTUS = '542'
  FACTSHEET = '533'
  COMMENTARY = '532'
  FUND_YIELD = '538'
  FLYER = '511'
  L_SHARE_YIELD_SHEET = 'MCOBX14FY'
  P_SHARE_YIELD_SHEET = 'MCOBYY7SX'
  ANNUAL_REPORT = '529'
  SEMIANNUAL_REPORT = '541'
  SAI = '540'
  SUMMARY_PROSPECTUS = '5380'
  DAILY_HOLDINGS = 'MA53THCZQ'
  MONTHLY_HOLDINGS = 'MA53Y14FY'
  BUSINESS_CALENDAR = 'MA540I7SX'
  WEEKLY_HOLDINGS = 'MA542HDIJ'
  FUND_DOCUMENTS = '528'
  FORMS_AND_APPLICATIONS = '496'
  XBRL_DOCUMENT = 'LDJDCMAIK'

  FUND_DOC_TYPES = [DAILY_HOLDINGS, WEEKLY_HOLDINGS, MONTHLY_HOLDINGS, COMMENTARY,FACTSHEET,
    PROSPECTUS,SUMMARY_PROSPECTUS,ANNUAL_REPORT,SEMIANNUAL_REPORT,SAI,BUSINESS_CALENDAR,FUND_YIELD,
    L_SHARE_YIELD_SHEET, P_SHARE_YIELD_SHEET
  ]
end

class DigitalAsset::Audience
  INVESTOR_APPROVED = '490'
  INSTITUTIONAL_USE = '491'
end


FUND_DOC_ORDER = {
    :daily_holdings => [DigitalAsset::ContentType::DAILY_HOLDINGS],
    :weekly_holdings => [DigitalAsset::ContentType::WEEKLY_HOLDINGS],
    :current_monthly_holdings => [
      DigitalAsset::ContentType::MONTHLY_HOLDINGS,
      lambda {|docs| docs[0] ? [docs[0]] : [] }
      ],
    :commentary => [DigitalAsset::ContentType::COMMENTARY],
    :factsheet => [DigitalAsset::ContentType::FACTSHEET],
    :prospectus => [DigitalAsset::ContentType::PROSPECTUS],
    :summary_prospectus => [DigitalAsset::ContentType::SUMMARY_PROSPECTUS],
    :annual_report => [DigitalAsset::ContentType::ANNUAL_REPORT],
    :semiannual_report => [DigitalAsset::ContentType::SEMIANNUAL_REPORT],
    :sai => [DigitalAsset::ContentType::SAI],
    :business_calendar => [DigitalAsset::ContentType::BUSINESS_CALENDAR],
    :prior_monthly_holdings => [
      DigitalAsset::ContentType::MONTHLY_HOLDINGS,
      lambda {|docs| docs }
      ],
    :fund_yield => [DigitalAsset::ContentType::FUND_YIELD]
  }