require 'uri'

module Blacksand
  class Page < ActiveRecord::Base
    belongs_to :parent, class_name: Page, foreign_key: 'parent_id'
    has_many :children, class_name: Page, foreign_key: 'parent_id', :dependent => :destroy
    has_one :navigation, :dependent => :destroy

    belongs_to :template
    belongs_to :prototype

    has_many :properties, :dependent => :destroy
    has_many_kindeditor_assets :attachments, :dependent => :destroy

    accepts_nested_attributes_for :properties

    has_many :positioned_children, -> { order(:position) }, class_name: 'Page', foreign_key: 'parent_id'

    # validates :title, :template, presence: true

    # 在新建页面的时候,上传的图片没有 owner_id 和 owner_type
    # TODO: 还有一种情况是在新建页面的时候,图片上传上来后又被删除了。这时候图片就变成没有人认领的孤儿了。
    after_commit :set_owner_for_kindeditor_assets, on: :create

    # 在编辑的过程中可能从内容中删除了部分图片, 但是 Kinkeditor::Assets 还没有被删除
    after_commit :clean_unsued_kindeditor_assets, on: :update

    # page.props.name
    # page.props[:name]
    def props
      if @attrs.blank?
        properties = self.properties.includes(:field).map { |p| [p.field.name, p.content] }
        @attrs = OpenStruct.new(Hash[properties])
      end

      @attrs
    end

    # 推荐使用 props 方法 @gaohui 2015.11.26
    def values
      if @values.blank?
        @values = ActiveSupport::HashWithIndifferentAccess.new
        self.properties.each do |p|
          @values[p.field.name] = p.content
        end
      end

      @values
    end

    def ancestors
      if self.parent.present?
        self.parent.ancestors + [self.parent]
      else
        []
      end
    end

    def descendents
      self.positioned_children.reduce([]) do |all, child|
        all << child
        all.concat(child.descendents)
        all
      end
    end
    
    def child(title)
      self.children.where(title: title).first
    end

    def child_with(conditions)
      self.children.find_by(conditions)
    end

    def content_first_image
      image_assets = image_assets_of_content

      return if image_assets.empty?

      asset_name = image_assets.first
      Kindeditor::Asset.where(asset: asset_name).first
    end

    def all_image_srcs_of_content
      html_doc = Nokogiri::HTML(self.content)
      images = html_doc.xpath("//img")
      images.map{|img| img['src'] }
    end

    def preferred_child_template_name
      preferred_option('preferred_child_template_name')
    end

    def preferred_child_prototype_name
      preferred_option('preferred_child_prototype_name')
    end

    def tree_node
      href = Blacksand::Engine.routes.url_helpers.children_partial_pages_path(parent_id: self.id)

      return {text: self.title, href: href, page_id: self.id} if self.children.count == 0

      # children 多余 15 个且都是叶子节点, 那么子节点不显示
      if self.children.count >= 15 && self.children.limit(15).all? { |p| p.children.empty? }
        {
        text: self.title,
        href: href,
        page_id: self.id
        }
      else
        {
        text: self.title,
        href: href,
        page_id: self.id,
        nodes: self.children.order(:position).map { |p| p.tree_node },
        }
      end

    end

    def build_properties
      self.prototype.fields.each do |field|
        Property.build_property(self, field)
      end
    end

    def self.tree_nodes(page_ids = nil)
      if page_ids
        Page.where(id: page_ids).order(:position).map { |p| p.tree_node }
      else
        Page.where('parent_id is null').order(:position).map { |p| p.tree_node }
      end
    end

    def self.selectNode(nodes, page_id)
      nodes.each do |node|
        if node[:page_id] == page_id
          node.merge!(state: {selected: true})
          return
        end

        selectNode(node[:nodes], page_id) if node[:nodes].present?
      end
    end


    def self.query_value(name, value)
      joins(properties: :field).where(fields: {name: name}, properties: {value: value})
    end

    protected

    def set_owner_for_kindeditor_assets
      image_assets = image_assets_of_content

      image_assets.each do |asset_name|
        asset = Kindeditor::Asset.where(asset: asset_name, owner_id: 0).first
        asset.update(owner_id: self.id, owner_type: self.class.name) if asset.present?
      end
    end

    def clean_unsued_kindeditor_assets
      image_assets = image_assets_of_content
      exists_image_assets = self.attachments.to_a.select { |asset| asset.asset_type == 'image' }.map { |a| File.basename(a.asset.path) }

      redundant_image_assets = exists_image_assets - image_assets
      Kindeditor::Asset.where('asset in (?)', redundant_image_assets).destroy_all
    end

    # 返回内容中所有上传的图片
    def image_assets_of_content
      srcs = all_image_srcs_of_content.select do |src|
        # 本地上传的文件
        if src.start_with? "/#{RailsKindeditor.upload_store_dir}"
          true
        # 有可能是与存储
        elsif src.start_with?("http") && URI(src).path.start_with?("/#{RailsKindeditor.upload_store_dir}")
          true
        else
          false
        end
      end
      srcs.map { |src| File.basename(src) }
    end

    def preferred_option(key)
      if self.template && self.template.options.present? && self.template.options[key]
        self.template.options[key]
      elsif self.prototype && self.prototype.options.present? && self.prototype.options[key]
        self.prototype.options[key]
      end
    end
  end
end