# == Schema Information
#
# Table name: attachments
#
#  id                        :integer          not null, primary key
#  container_id              :integer
#  container_type            :string(30)
#  filename                  :string(255)      default(""), not null
#  disk_filename             :string(255)      default(""), not null
#  filesize                  :integer          default("0"), not null
#  content_type              :string(255)      default("")
#  digest                    :string(60)       default(""), not null
#  downloads                 :integer          default("0"), not null
#  author_id                 :integer          default("0"), not null
#  created_on                :datetime
#  description               :text(65535)
#  disk_directory            :string(255)
#  attachtype                :integer          default("1")
#  is_public                 :integer          default("1")
#  copy_from                 :integer
#  quotes                    :integer          default("0")
#  is_publish                :integer          default("1")
#  publish_time              :datetime
#  resource_bank_id          :integer
#  unified_setting           :boolean          default("1")
#  cloud_url                 :string(255)      default("")
#  course_second_category_id :integer          default("0")
#  delay_publish             :boolean          default("0")
#  uuid                      :string(255)
#
# Indexes
#
#  index_attachments_on_author_id                        (author_id)
#  index_attachments_on_container_id_and_container_type  (container_id,container_type)
#  index_attachments_on_course_second_category_id        (course_second_category_id)
#  index_attachments_on_created_on                       (created_on)
#  index_attachments_on_is_public                        (is_public)
#  index_attachments_on_quotes                           (quotes)
#  index_attachments_on_uuid                             (uuid)
#





class Attachment < ApplicationRecord
  include BaseModel
  include Publicable
  include Publishable
  include Lockable
  include DunCheckImageAble
  belongs_to :container, polymorphic: true, optional: true
  belongs_to :author, class_name: "User", foreign_key: :author_id
  # belongs_to :course, foreign_key: :container_id, optional: true
  # has_many :attachment_group_settings, :dependent => :destroy
  # has_many :attachment_histories, -> { order(version: :desc) }, :dependent => :destroy
  # 二级目录
  # belongs_to :course_second_category, optional: true

  scope :by_filename_or_user_name,      -> (keywords) { joins(:author).where("filename like :search or LOWER(CONCAT(users.lastname, users.firstname)) LIKE :search OR users.nickname LIKE :search",
                                                        :search => "%#{keywords.split(" ").join('|')}%") unless keywords.blank? }
  scope :by_keywords,                   -> (keywords) { where("filename LIKE ?", "%#{keywords.split(" ").join('|')}%") unless keywords.blank? }
  scope :ordered,                       -> (opts = {}) { order("#{opts[:sort_type]} #{opts[:sort] == 1 ? 'asc': 'desc'}") }
  scope :by_course_second_category_id,  -> (course_second_category_id = 0) { where(course_second_category_id: course_second_category_id) }
  scope :contains_only_course,          -> { where(container_type: 'Course') }
  scope :contains_only_project,         -> { where(container_type: 'Project') }
  scope :contains_course_and_project,   -> { contains_only_course.or(contains_only_project) }
  scope :mine,                          -> (author_id) { where(author_id: author_id) }
  scope :simple_columns,                -> { select(:id, :filename, :filesize, :created_on, :cloud_url, :author_id, :content_type, :container_type, :container_id) }
  scope :search_by_container,           -> (ids) {where(container_id: ids)}
  scope :unified_setting, -> {where("unified_setting = ? ", 1)}
  scope :where_id_or_uuid, -> (id) { (Float(id) rescue nil).present? ? where(id: id) : id.present? ? where(uuid: id) : [] }

  validates_length_of :description, maximum: 255, message: "不能超过255个字符"

  DCODES = %W(2 3 4 5 6 7 8 9 a b c f e f g h i j k l m n o p q r s t u v w x y z)

  def self.build_from_remote_url(user, name, url, container=nil)
    ext = name.split('.')[-1]
    tmp_path = "#{Rails.root}/#{name}"
    uri = URI(url)
    size = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
      response = http.get(uri.path)
      File.open(tmp_path, 'wb') do |file| 
        file.write(response.body)
      end
    end
    digest = "#{Digest::MD5.file(tmp_path).hexdigest}_#{(Time.now.to_f * 1000).to_i}.#{ext}"
    month_folder = "#{Time.now.year}/#{Time.now.month.to_s.rjust(2, '0')}"
    save_path = "#{Rails.root}#{EduSetting.get("attachment_folder")}#{month_folder}"
    unless Dir.exists?(save_path)
      FileUtils.mkdir_p(save_path) ##不成功这里会抛异常
    end
    path = File.join(save_path, digest)
    FileUtils.mv(tmp_path, path)
    attachment = Attachment.new 
    attachment.filename = name 
    attachment.disk_filename = path[save_path.size+1, path.size]
    attachment.filesize = size 
    attachment.content_type = 'application/octet-stream'
    attachment.digest = digest.split('.')[0]
    attachment.author_id = user.id 
    attachment.disk_directory = month_folder
    attachment.cloud_url = url 
    attachment.uuid = SecureRandom.uuid 
    attachment.container = container
    attachment.save! 

    return attachment
  rescue 
    return nil
  end

  def diskfile
    File.join(File.join(Rails.root, "files"), disk_directory.to_s, disk_filename.to_s)
  end

  def relative_path_filename
    File.join(disk_directory.to_s, disk_filename.to_s)
  end

  def title
    filename
    # title = filename
    # if container && container.is_a?(StudentWork) && author_id != User.current.id
    #   course = container&.homework_common&.course
    #   unless User.current.teacher_of_course?(course)
    #     title = "#{Time.now.strftime('%Y%m%d%H%M%S')}_#{DCODES.sample(8).join}" + File.extname(filename)
    #   end
    # end
    # title
  end

  def downloads_count
    downloads
  end

  def generate_uuid
    self.uuid = uuid || SecureRandom.uuid
    save!
  end

  def quotes_count
    quotes.nil? ? 0 : quotes
  end

  def self.associate_container(ids, container_id, container_type, attachtype=1)
    return false  if ids.blank? || !ids.is_a?(Array)
    ids.each do |id|
      attachment = Attachment.find id
      attachment.update_attributes(container_id: container_id, container_type: container_type, attachtype: attachtype)
    end
  end

  # Returns an unsaved copy of the attachment
  def copy(attributes=nil)
    copy = self.class.new
    copy.attributes = self.attributes.dup.except("id", "downloads", "quotes")
    copy.attributes = attributes if attributes
    copy
  end

  def set_publish_time(publish_time)
    self.unified_setting = 1
    if publish_time.blank?
      self.publish_time = Time.now
      self.is_publish = 1
    else
      self.is_publish = publish_time.to_s > (format_time Time.now).to_s ? 0 : 1
      self.publish_time = publish_time.to_s > (format_time Time.now).to_s ? publish_time : Time.now
    end
  end

  def set_course_group_publish_time(course, course_group_publish_times)
    self.unified_setting = 0
    min_publish_time = ""
    course_group_publish_times.each do |obj|
      if obj && obj[:course_group_id]
        publish_time = obj[:publish_time]
        if !publish_time.blank? && publish_time < min_publish_time
          min_publish_time = publish_time
        elsif publish_time.blank?
          publish_time = Time.now
        end
        attachment_group_setting = self.attachment_group_settings.where(course_group_id: obj[:course_group_id], course_id: course.id).first
        if attachment_group_setting.present?
          attachment_group_setting.update_columns(publish_time: publish_time)
        else
          self.attachment_group_settings.create(
              :course_group_id => obj[:course_group_id],
              :course_id => course.id,
              :publish_time => publish_time
          )
        end
      end
    end
    self.is_publish = min_publish_time > (format_time Time.now).to_s ? 0 : 1
    self.publish_time = min_publish_time > (format_time Time.now).to_s ? min_publish_time : self.created_on
  end

  def become_history
    history = self.attachment_histories.first
    new_attachment_history = AttachmentHistory.new(self.attributes.except("id", "resource_bank_id", "unified_setting", "course_second_category_id", "delay_publish").merge(
        attachment_id: self.id,
        version: history.nil? ? 1 :  history.version + 1,
    ))
    new_attachment_history
  end

  def copy_attributes_from_new_attachment(new_attachment)
    self.attributes = new_attachment.attributes.dup.except("id","container_id","container_type","is_public","downloads", "quotes",'is_publish','publish_time', "delay_publish")
  end

  def set_public(is_public)
    if is_public == true
      is_public = 1
    elsif is_public == false
      is_public = 0
    end
  end

  #判断是否为pdf文件
  def is_pdf?
    is_pdf = false
    file_content_type = content_type
    file_ext_type = File.extname(filename).strip.downcase[1..-1]
    if (file_content_type.present? && file_content_type.downcase.include?("pdf")) || (file_ext_type.present? && file_ext_type.include?("pdf"))
      is_pdf = true
    end
    is_pdf
  end

  def to_builder
    Jbuilder.new do |attachment|
      attachment.id self.id
      attachment.title self.title
      attachment.filesize self.filesize
      attachment.is_pdf self.is_pdf?
      attachment.created_on self.created_on.strftime("%Y-%m-%d %H:%M")
      attachment.content_type self.content_type
    end
  end
end