class LibrariesController < ApplicationController
  layout 'base_library'

  before_filter :require_login, :except => [:index, :show]
  after_filter :increment_visit_count, only: [:show, :create, :edit, :update]

  def index
    libraries = Library.where(nil)

    libraries =
      if User.current.logged? && params[:type] == 'mine'
        libraries.where(user_id: current_user.id).order('created_at desc')
      else
        libraries.where(status: :published).order('visited_count desc')
      end

    search = params[:search].to_s.strip
    if search.present?
      libraries = libraries.where('title LIKE :search OR author_name LIKE :search OR author_school_name LIKE :search',
                                  search: "%#{search}%")
    end

    per_page = params[:per_page].to_i <= 0 ? 20 : params[:per_page].to_i
    @libraries = paginateHelper libraries.includes(:library_tags, :praise_tread_cache, user: :user_extensions), per_page

    @download_count_map = Attachment.where(container_type: 'Library', container_id: @libraries.map(&:id)).group(:container_id).sum(:downloads)
  end

  def show
    @library = current_library
    return render_403 unless admin_or_self? || @library.published?

    @library_applies = @library.library_applies.where(status: :refused).order('created_at desc')
  end

  def new
    @library = current_user.libraries.new
  end

  def create
    @library = current_user.libraries.new
    Libraries::SaveService.new(@library, current_user, form_params).call
    if with_publish?
      Libraries::SubmitService.new(@library).call
      redirect_to publish_success_libraries_path(id: @library.id)
    else
      redirect_to library_path(id: @library.id)
    end
  rescue ActiveRecord::RecordInvalid => e
    flash[:message] = e.record.errors.full_messages.join(',')
    render 'new'
  rescue Libraries::SubmitService::Error, Libraries::SaveService::Error => ex
    flash[:message] = ex.message
    render 'new'
  end

  def edit
    return render_403 unless admin_or_self?
    @library = current_library
  end

  def update
    return render_403 unless admin_or_self?

    @library = current_library
    Libraries::SaveService.new(@library, current_user, form_params).call
    if with_publish?
      Libraries::SubmitService.new(@library).call
      redirect_to publish_success_libraries_path(id: @library.id)
    else
      redirect_to library_path(id: @library.id)
    end
  rescue ActiveRecord::RecordInvalid => e
    flash[:message] = e.record.errors.full_messages.join(',')
    render 'edit'
  rescue Libraries::SubmitService::Error, Libraries::SaveService::Error => ex
    flash[:message] = ex.message
    render 'edit'
  end

  def destroy
    if admin_or_business?
      current_library.destroy
    elsif current_library.user_id == current_user.id
      unless current_library.pending?
        render json: { status: -1, message: '只有草稿才能删除' }
        return
      end

      current_library.destroy
    else
      render_403
      return
    end

    render json: { status: 0, message: 'success' }
  end

  def publish
    Libraries::SubmitService.new(current_library).call
    render json: { status: 0 }
  rescue Libraries::SubmitService::Error => ex
    render json: { status: 0, message: ex.message }
  end

  def publish_success
  end

  private

  def current_library
    @_current_library ||= Library.find(params[:id])
  end

  def form_params
    @_form_params ||= begin
      hash = params[:library].presence || {}
      hash[:tag_ids] = params[:tag_ids].to_s.split(',')
      hash[:attachment_ids] = (params[:attachments].presence || []).values.map{|h| h[:attachment_id]}
      hash[:cover_id] = save_cover.try(:id) || hash[:cover_id]
      hash
    end
  end

  def with_publish?
    params[:apply_publish].to_s == 'true'
  end

  def admin_or_self?
    current_library.try(:user_id) == current_user.try(:id) || admin_or_business?
  end

  def increment_visit_count
    @library.increment_visited_count! if @library && @library.id
  end

  def save_cover
    return if params[:cover_file].blank?

    attachment = Attachment.new(file: params[:cover_file])
    attachment.author = User.current
    attachment.filename = Redmine::Utils.random_hex(16)
    attachment.save
    attachment
  end
end