# pass the layout=false for not rendering the layouts and also can specify the methods to in the backend controller.
# data-layout-content="arrayname" in layouts can be used to render data in the array  
require 'zhconv'
require "uri"
class PagesController < ApplicationController
  before_action :get_key
  layout :get_layout
  include PagesHelper
  before_filter :check_frontend_open, :only => [:home,:show]
  before_filter :check_authorization, :except => [:home,:show]
  before_filter :set_edit_mode
  
  def index
  	@pages = Page.all
    # render json: @pages
  end

  def edit_view
    @manifest = @key
    @dataApi = "edit"
    view = get_view
    if File.exists?(view)
      render view
    end
  end

  def home
    @manifest = @key
    page = Page.first
    impressionist(page)
    OrbitHelper.set_params params,current_user
    OrbitHelper.set_site_locale locale
    render :html => render_final_page("home",page,true).html_safe
  end

  def show
    display_type = ""
    path = request.path.split('/')
    if path.size <= 2
      redirect_to root_path
    else
      if path.last.include? '-'
        params[:page_id] = path[-2]
        s = CGI.unescape(path[-1])
        s.encode!('UTF-8')
        params[:slug] = s
        uid = path[-1].split("-").last
        uid = uid.split("?").first
        params[:uid] = uid
        params[:target_action] = params[:method] || "show"
        display_type = "show"
      else
        params[:page_id] = path[-1]
        params[:slug] = nil
        params[:uid] = nil
        params[:target_action] = params[:method] || "index"
        display_type = "index"
        OrbitHelper.set_page_number params[:page_no].to_i || 1
      end
      page = Page.find_by_param(params[:page_id])
      if !page.nil?
        if !page.enabled_for_mobile && !$mobile.blank?
          render :file => "#{Rails.root}/public/404.html", :layout => false, :status => :not_found
          return
        end
        if page.enabled_for.include? I18n.locale.to_s
          if page.page_type == "link"
            redirect_to page.external_url
            return
          end
          module_app = page.module.downcase.pluralize
          params[:target_controller] = "#{module_app}"
          if display_type == "index"
             params[:layout_type] = params[:method] || page.layout || "index"
          end
          params[:url] = page.url

          @manifest = @key
          OrbitHelper.set_params params,current_user
          OrbitHelper.set_site_locale locale
          OrbitHelper.set_this_module_app module_app.singularize
          OrbitHelper.set_page_categories page.categories || []
          OrbitHelper.set_page_tags page.tags || []
          OrbitHelper.set_page_role_status page.role_status || []
          OrbitHelper.set_member_sort_position page.member_sort_position
          OrbitHelper.set_page_data_count page.data_count
          if params[:layout].kind_of?(String)
            layout = to_bool(params[:layout]) 
          else
            layout = true
          end

          impressionist(page)
          render :html => render_final_page("#{module_app}/#{params[:target_action]}",page,layout).html_safe
        else
          render :file => "#{Rails.root}/public/404.html", :layout => false, :status => :not_found
        end
      else
          render :file => "#{Rails.root}/public/404.html", :layout => false, :status => :not_found
      end
    end
  end

  def update_item_position
    @page = Page.find(params[:id])
    new_parent_page = Page.find(params[:parent_id])
    old_parent_page_id = @page.parent_page_id
    @page.parent_page_id = new_parent_page.id
    if new_parent_page.id != old_parent_page_id
      url = (new_parent_page.url == "/" ? "" : new_parent_page.url)
      @page.url = url + "/#{@page.page_id}"
    end
    @page.save
    params["children_ids"].each_with_index do |child,i|
      page = Page.find(child)
      page.number = i
      page.save
    end

    if new_parent_page.id != old_parent_page_id
      old_parent_page = Page.find(old_parent_page_id)

      # old_parent_page.child_page.each_with_index do |page,i|
      #   page.number = i
      #   page.save
      # end
      params["parent_children_ids"] = params["parent_children_ids"] || []
      params["parent_children_ids"].each_with_index do |child, i|
        page = Page.find(child)
        page.number = i
        page.save
      end
    end
    render :json => {"success"=>true}.to_json
  end

  def preview
    render render_final_page
  end

  def destroy
    page = Page.find(params[:id])
    @parent_pages = page.parent_pages_without_root
    page.destroy
    respond_to do |format|
      format.js
    end
  end

  def get_categories
    module_app = ModuleApp.find_by_key(params[:module]);
    if module_app.key.eql?("member")
        roles = Role.order_by(:_id=>'ASC').all.collect do |role|
        {
          "title" => role.title,
          "id" => role.id.to_s,
          "status" => RoleStatus.where(:role=>role).collect do |status|
            {
              "title" => status.title,
              "id" => status.id.to_s
            }
          end
        }
      end
    else
      categories = module_app.categories.collect do |cat|
        {
          "title" => cat.title,
          "id" => cat.id.to_s
        }
      end
    end

    roles = roles.nil? ? [] : roles
    categories = categories.nil? ? [] : categories
    
    if module_app.data_count.nil?
      render :json => {"categories" => categories, "tags" => module_app.tags,"roles" => roles,"layouts" => (get_layouts module_app.key),"data_count" => {"present"=>false}}.to_json
    else
      render :json => {"categories" => categories, "tags" => module_app.tags,"roles" => roles,"layouts" => (get_layouts module_app.key),"data_count" => {"present"=>true,"start"=>module_app.data_count.begin, "end" => module_app.data_count.end}}.to_json
    end
  end

  def new
  	@page = Page.new(
      :enabled_for_mobile=>true, 
      :menu_enabled_for=>["en", "zh_tw"], 
      :enabled_for=>["en", "zh_tw"],
      :enabled_for_sitemap=>["en", "zh_tw"]
      )
  	@pages = Page.where(:page_id.ne => "" , :page_id.exists => true)
  	@modules = ModuleApp.all.frontend_enabled.order_by(:key=>'asc')
  
  end

  def edit
    @page = Page.find(params[:id])
    if params[:type] == "page"
      @pages = Page.where(:page_id.ne => "" , :page_id.exists => true)
      @modules = ModuleApp.all.frontend_enabled
      @module_app = ModuleApp.find_by_key(@page.module) rescue nil
      @categories =  @module_app.categories rescue []
      @tags =  @module_app.tags rescue []
      if @module_app.key.eql?("member")
        @roles = Role.order_by(:_id=>'ASC').all.collect do |role|
                    {
                      "title" => role.title,
                      "id" => role.id.to_s,
                      "status" => RoleStatus.where(:role=>role)
                    }
                  end
      else
        @roles = []
      end
      @layout_types = get_layouts @module_app.key
    end
  end

  def update
    @page = Page.find(params[:id])
    @page.update_attributes(page_update_params)
    @page.save
    @parent_pages = @page.parent_pages_without_root
    respond_to do |format|
      format.js
    end

  end

  def create
    params['page']['page_id'] = params['page']['page_id'].gsub('-','_')
    @page = Page.new(page_params)
    @page.save!
    @parent_pages = @page.parent_pages_without_root
    respond_to do |format|
      format.js
    end
  end

	private

  def get_layouts(module_app)
    layout_types = []
    f = File.join("#{Rails.root}/app/templates/#{@key}/modules/#{module_app}/info.json")
    if File.exists?f
      info = File.read(f)
      hash = JSON.parse(info) rescue {}
      frontends = hash["frontend"] || []
      frontends.each do |frontend|
        frontend["thumbnail"] = "/assets/#{module_app}/thumbs/#{frontend["thumbnail"]}"
        layout_types <<  frontend
      end
    end
    if layout_types.empty?
      Dir.glob("#{Rails.root}/app/templates/#{@key}/modules/#{module_app}/*").each do |w|
        next if File.ftype(w).eql?("directory")
        w = File.basename(w, ".*") 
        w = File.basename(w, ".*") 
        if w[0,1] != "_" && w[0,1] != "s" && w != "info"
          layout_types << w
        end
      end
    end
    layout_types
  end

  def render_final_page(original_view=get_view,page,layout)
    final_html_for_render = ""
    if layout
      parts = $mobile.blank? ? (page.page_parts rescue []) : (page.mobile_page_parts rescue [])

      @part_partials = {}

      parts.each do |part|
        subparts = part.sub_parts.asc(:created_at)
        partials = []
        subparts.each do |subpart|
          if subpart.kind == "module_widget"
            OrbitHelper.set_widget_data_count subpart.data_count
            OrbitHelper.set_widget_categories subpart.categories
            OrbitHelper.set_widget_module_app subpart.module
            OrbitHelper.set_widget_item_url subpart
            OrbitHelper.set_widget_title subpart.title
            OrbitHelper.set_widget_categories subpart.categories || []
            OrbitHelper.set_widget_tags subpart.tags || []
            custom_value = subpart.custom_string_field || subpart.custom_array_field rescue nil
            if !custom_value.nil?
               OrbitHelper.set_widget_custom_value custom_value
            end
            if @editmode
               partials << "<div class='editmode-ps' title='#{subpart.module}'> " + render_widget_for_frontend(subpart.module,subpart.widget_method,subpart.widget_type) + "<a href='/page_parts/edit_sub_part?page_id=#{page.id.to_s}&part_id=#{part.id.to_s}&sub_part_id=#{subpart.id.to_s}#{(!$mobile.blank? ? '&mobile_view=1' : '')}'> </a></div>"
            else
                partials << render_widget_for_frontend(subpart.module,subpart.widget_method,subpart.widget_type)
            end
          elsif subpart.kind == "text"
              if @editmode
                partials << "<div class='editmode-ps' title='text'> " + subpart.content + "<a href='/page_parts/edit_sub_part?page_id=#{part.page_id.to_s}&part_id=#{part.id.to_s}&sub_part_id=#{subpart.id.to_s}#{(!$mobile.blank? ? '&mobile_view=1' : '')}'> </a></div>"
              else
                partials << subpart.content
              end
          end
        end
        @part_partials["data-pp='#{part.part_id}'"] = partials
      end

      @file = nil
      @layout_html = nil
      if original_view == "home"
        @file = File.join('../templates', "#{@key}", "/home/index.html.erb")
      else
        @file = File.join('../templates', "#{@key}", "/home/page.html.erb")
      end
      @layout_html = render_to_string(@file)
      doc = Nokogiri::HTML(@layout_html, nil, "UTF-8")

      @part_partials.each do |key, partial|
        html_string = ""
        partial.each do |p|
          html_string = html_string + p
        end
        pp = doc.css("*[#{key}]")
        if !pp.blank?
          pp = pp[0]
          pp.inner_html = html_string
        end
      end

      if @editmode
        pps = doc.css("*[data-pp]")
        pps.each do |pp|
          number = pp.attributes["data-pp"].value
          if pp.inner_html.strip == ""
              pp.inner_html = "<a href='/page_parts/new?part=#{number}&page_id=#{page.id.to_s}#{(!$mobile.blank? ? '&mobile_view=1' : '')}'> </a>"
          else
            inner_html = pp.inner_html
            pp.inner_html = inner_html + "<a href='/page_parts/#{number}/edit?page_id=#{page.id.to_s}#{(!$mobile.blank? ? '&mobile_view=1' : '')}'> </a>"
          end
        end
      end

      if original_view != "home"
        viewarea = doc.css("*[data-content='true']")[0]
        viewarea.inner_html = render_to_string(original_view) rescue "<div></div>"
      end
      link = doc.css("link")[0]
      link.attributes["href"].value = current_site.favicon.url.nil? ? "/assets/favicon.ico" : current_site.favicon.url
      final_html_for_render = doc.to_html

    else
        final_html_for_render = render_to_string(original_view) rescue "<div></div>"
    end
    final_html_for_render = change_to_language(final_html_for_render)
    if @editmode
      session[:mobile] = $temp_mobile
    end
    format_date(final_html_for_render) rescue final_html_for_render
  end

  def format_date(html)
    doc = Nokogiri::HTML(html, nil, "UTF-8")
    dates = doc.css("*[date-format]")
    if dates.blank?
      return html
    else
      dates.each do |d|
        format = d.attributes["date-format"].value
        date = DateTime.parse(d.inner_text)
        d.inner_html = d.inner_html.gsub(d.inner_text.strip, " " + date.strftime(format))
      end
      return doc.to_html
    end
  end

  def get_widget_path(widget)
    file = File.join('../templates', "#{@key}", "modules/#{widget}")
  end

  def get_view
    page = Page.find(params[:id]) rescue Page.root
    if page == Page.root
      @view = File.join(Rails.root, 'app', 'templates', "#{@key}", "home/index.html.erb")
    else
      module_name = page.module.downcase.singularize
      @view = File.join(Rails.root, 'app', 'templates', "#{@key}", "modules/#{module_name}/index.html.erb")
    end
  end

  def page_params
    page = Page.find(params[:page][:parent_page])
    page.url = page.url == "/" ? "" : page.url
    @url = page.url + "/#{params[:page][:page_id]}"
    p = params.require(:page).permit(:number, :page_type, :page_id, :module, :layout, :parent_page, :data_count, :enabled_for_mobile, :member_sort_position, enabled_for_sitemap: [], enabled_for: [], menu_enabled_for: [], categories: [], tags: [], role_status: [], name_translations: [:en, :zh_tw],external_url_translations: [:en, :zh_tw])
    p["url"] = @url
    if p["external_url_translations"]
      p["external_url_translations"]["en"] = p["external_url_translations"]["en"].sub("http://" + request.host_with_port,"")
      p["external_url_translations"]["zh_tw"] = p["external_url_translations"]["zh_tw"].sub("http://" + request.host_with_port,"")
    end
    p
  end

  def page_update_params
    p = params.require(:page).permit(:number, :page_type, :page_id, :module, :layout, :parent_page, :data_count, :enabled_for_mobile, :member_sort_position, enabled_for_sitemap: [], enabled_for: [],menu_enabled_for: [], categories: [], tags: [], role_status: [], name_translations: [:en, :zh_tw], external_url_translations: [:en, :zh_tw])
    p["role_status"] = p["role_status"] || []
    p["categories"] = p["categories"] || []
    p["enabled_for"] = p["enabled_for"] || []
    p["menu_enabled_for"] = p["menu_enabled_for"] || []
    p["enabled_for_sitemap"] = p["enabled_for_sitemap"] || []
    p["enabled_for_mobile"] = p["enabled_for_mobile"] || 0
    if p["external_url_translations"]
      p["external_url_translations"]["en"] = p["external_url_translations"]["en"].sub("http://" + request.host_with_port,"")
      p["external_url_translations"]["zh_tw"] = p["external_url_translations"]["zh_tw"].sub("http://" + request.host_with_port,"")
    end
    p
  end

  def get_layout
    if request[:action] == "edit_view"
     page = Page.find(params[:id])
      if page.page_id == "" || page.page_id == nil
        false
      else
        File.join("../../templates", "#{@key}", "/home/page.html.erb")
      end
    # elsif request[:action] == "show" || request[:action] == "moduleShow"
    #    File.join("../../templates", "themes", "#{@key}", '/home/page.html.erb')
    else
      false
    end
  end
  def to_bool(str)
    return true if str == "true" 
    return false if str == "false"
  end

  def check_frontend_open
    if !current_site.frontend_open && current_user.blank?
      redirect_to '/admin/dashboards'  
    end
  end

  def check_authorization
    if current_user.blank? or !current_user.is_admin?
      redirect_to '/admin/dashboards'  
    end
  end

  def set_edit_mode
    @dataApi = nil
    @editmode = false
    if !current_user.nil? and current_user.is_admin?
      if params[:editmode] == "on"
        @editmode = true
        @dataApi = "edit"
      end
    end
  end
 
  def change_to_language(final_html)
     if session[:zh_cn]
        final_html =  ZhConv.convert("zh-cn", final_html)
        final_html.gsub!('/zh_tw/','/zh_cn/')
        final_html.sub!('<a href="'+request.path+'">繁体中文</a>','<a href="'+(request.path.sub('/zh_cn/','/zh_tw/'))+'">繁体中文</a>')
      end
      final_html
  end

end