class ArchivesController < ApplicationController
	def self.custom_widget_data
		ac = ActionController::Base.new
		ac.render_to_string("archives/custom_widget_data",:locals=>{:@custom_data_field=>@custom_data_field,:@field_name=>@field_name})
	end
	#avoid the categories to be not in the ArchiveCategory
	def serve_cmap
		file_name = File.basename(params[:file_name].to_s)
		extension = File.basename(params[:extension].to_s)
		serve_path = File.expand_path("../../assets/javascripts/archive/pdf/bcmaps/#{file_name}.#{extension}",__FILE__)
		if Dir.glob(serve_path).length != 0
			send_file(serve_path, type: "application/octet-stream")
		else
			render :file => "#{Rails.root}/app/views/errors/404.html", :layout => false, :status => :not_found, :content_type => 'text/html' and return
		end
	end
	def show
		params = OrbitHelper.params
	    archive_file = ArchiveFile.find_by(:uid=>params[:uid].to_s)
	    locale = I18n.locale.to_s
	    data, serial_number, idx = archive_file.get_frontend_data(locale, 0, 0, true, OrbitHelper.url_to_show(""))
	    {
	    	"data" => data
	    }
	end
	def index
		ArchiveFile.check_sort_number
		page = OrbitHelper.page rescue nil
		unless page
		  page = Page.where(url:params['url']).first
		end
		params = OrbitHelper.params
		@@total_pages = 1
		in_class = ""
		custom_data_field = page.custom_data_field rescue nil
		if custom_data_field && custom_data_field["expanded"] == "yes"
		  in_class = "in"
		end
		locale = I18n.locale.to_s
		cats_last = []
		if !params['title'].nil?
			files_by_category = ArchiveFile.can_display.sorted.group_by(&:category)
			categories = files_by_category.keys
			categories_sort = get_sorted_cat_with_filter(categories,'orm')
			categories_sort.each_with_index do |category, cat_idx|
				url_to_edit = ""
				flag = false
				archives = []
				serial_number = 0
				files_by_category[category].each_with_index do |archive,idx|
					if archive.title == params['title']
						flag = true
						data, serial_number, idx = archive.get_frontend_data(locale, serial_number, idx)
						archives << data
					end
				end
				if flag
					cats_last << {
						"category-id" => category.id,
						"category-title" => category.title,
						"archives" => archives,
						"url_to_edit" => url_to_edit
					}
				end
			end
		else
			if OrbitHelper.page_data_count > 0
				OrbitHelper.set_page_data_count 0
				page = Page.where(:page_id => params["page_id"]).first rescue nil
				if !page.nil?
					page.data_count = 0
					page.save
				end
			end
			categories = params["categories"].blank? ? OrbitHelper.page_categories : params["categories"]
			tags = params["tags"].blank? ? OrbitHelper.page_tags : params["tags"]
			module_app = ModuleApp.where(:key=>'archive').first
			if categories == ["all"]
				categories = module_app.categories.pluck(:id).map(&:to_s)
			end
			if tags == ["all"]
				tags = module_app.tags.sort_by{|tag| ((module_app.asc rescue true) ? tag.sort_number.to_i : -tag.sort_number.to_i)}.map{|tag| tag.id.to_s}
				tags << nil
			end
			if params[:data_count].to_i <=0
				page_data_count = 0
			else
				page_data_count = params[:data_count].to_i
			end
			if params[:page_no].nil?
				page_no = 1
			else
				page_no = params[:page_no].to_i
			end
			if (tags.count > 1 && categories.count <= 1 rescue false)
				archive_files = ArchiveFile.can_display.filter_by_categories(categories).sorted
				group_archive_files = {}
				cats = []
				each_data_count = []
				archive_files_ids = archive_files.pluck(:id)
				archive_files_ids_count = archive_files_ids.count
				tags.each_with_index do |tag_id, tag_idx|
					tag_name = ""
					if tag_id
						tag = Tag.find(tag_id) rescue nil
						next if tag.nil?
						url_to_edit = OrbitHelper.current_user ? "/admin/archive_files?filters[tags][]=#{tag_id}" : ""
						taggings = Tagging.where(:tag_id=>tag_id).pluck(:taggable_id)
						archives = archive_files.where(:id.in=>taggings).to_a
						archive_files_ids = archive_files_ids - archives.map{|a| a.id}
						tag_name = Tag.find(tag_id).name
					else
						if categories.count == 1
							url_to_edit = OrbitHelper.current_user ? "/admin/archive_files?filters[category][]=#{categories[0]}" : ""
						else
							url_to_edit = OrbitHelper.current_user ? "/admin/archive_files" : ""
						end
						archives = []
						if tags.count > 1 && archive_files_ids_count != archive_files_ids.count
							tag_name = I18n.t("archive.other")
							archives = archive_files.where(:id.in=>archive_files_ids).to_a
						else
							archives = archive_files.to_a
						end
					end
					serial_number = 0
					if archives.count != 0
						archives = archives.map.with_index do |archive,idx|
							data, serial_number, idx = archive.get_frontend_data(locale, serial_number, idx)
							data
						end
						each_data_count.push(archives.length)
						sorted = archives
						cats << {
							"category-id" => tag_id,
							"category-title" => tag_name,
							"archives" => sorted,
							"url_to_edit" => url_to_edit
						}
					end
				end
				cats_last = cats  			
			else
			files_by_category = ArchiveFile.can_display.filter_by_categories(categories).filter_by_tags(tags).sorted.group_by(&:category)
			each_data_count = []
			categories = files_by_category.keys
			categories_sort = get_sorted_cat_with_filter(categories,'orm')
			cats = categories_sort.collect.with_index do |category, cat_idx|
				url_to_edit = OrbitHelper.user_has_cateogry?(category) ? "/admin/archive_files?filters[category][]=#{category.id.to_s}" : ""
				serial_number = 0
				archives = files_by_category[category].collect.with_index do |archive,idx|
					data, serial_number, idx = archive.get_frontend_data(locale, serial_number, idx)
					data
				end
				each_data_count.push(archives.length)
				sorted = archives
				{
					"category-id" => category.id,
					"category-title" => (categories.count > 1 ? category.title : ""),
					"archives" => sorted,
					"url_to_edit" => url_to_edit
				}
			end
			if page_data_count != 0
				all_data_count = 0
				data_start = -1
				data_end = -1
				for i in 0...each_data_count.length
					all_data_count_before = all_data_count
					all_data_count += each_data_count[i]
					if ( data_start == -1 && (all_data_count > (page_no - 1) * page_data_count) )
						data_start = i
						data_start_first =  (page_no - 1) * page_data_count - all_data_count_before
					end
					if ( data_end == -1 && (all_data_count > (page_no * page_data_count - 1)) )
						data_end = i
						data_end_last = (page_no * page_data_count - 1) - all_data_count_before
					end
				end
				if ( data_end == -1 && data_start != -1)
					data_end = i
					data_end_last = -1
				end 
				if data_start!=-1 && page_no>=1
					cats_last = []
					for i in data_start..data_end
						if data_start != data_end
							if i==data_start
								cats_last << Hash[cats[i].map{|k,v| [k , (k=='archives' ? v[data_start_first..-1] : v)]}]
							elsif i==data_end
								cats_last << Hash[cats[i].map{|k,v| [k , (k=='archives' ? v[0..data_end_last] : v)]}]
							else
								cats_last << cats[i]
							end
						else
							cats_last << Hash[cats[i].map{|k,v| [k,(k=='archives' ? v[data_start_first..data_end_last] : v)]}]
						end
					end
				else
					cats_last = [Hash[cats[0].map{|k,v| [k,'']}]]
				end
				@@total_pages = (all_data_count.to_f / page_data_count).ceil
			else
				if page_no!=1
					cats_last = [Hash[cats[0].map{|k,v| [k,'']}]]
					@@total_pages = 0
				else
					cats_last = cats
					@@total_pages = 1
				end
			end
			end
		end
		if cats_last.count != 0
			cats_last.each_with_index do |h, i|
				h["active_class"] = (i == 0 ? 'active' : '')
			end
		end
		{
			"categories" => cats_last,
			"extras" =>{
				"serial_number-head" => I18n.t("archive.serial_number"),
				"date-head" => I18n.t("archive.updated_at"),
				"title-head" => I18n.t(:name),
				"description-head"=>I18n.t("archive.description"),
				"file-head" =>I18n.t("archive.download_file"),
				"in_class" => in_class
			}
		}
	end

	def download_file
		file_id = params[:file]
		file = ArchiveFileMultiple.find(file_id) rescue nil
		if !file.nil?
			file.download_count = file.download_count + 1
			file.save
			@url = file.file.url
			begin
				@path = file.file.file.file rescue ""
				@filename = File.basename(@path)
				@ext = @filename.split(".").last
				if @ext == "png" || @ext == "jpg" || @ext == "bmp" || @ext == "pdf"
					render "download_file",:layout=>false
				else
					if (current_site.accessibility_mode rescue false)
						render "redirect_to_file",:layout=>false
					else
						send_file(@path)
					end
				end
			rescue
				redirect_to @url
			end
		else
			render :file => "#{Rails.root}/app/views/errors/404.html", :layout => false, :status => :not_found
		end
	end

	def group_by_category
		cat_id = OrbitHelper.widget_categories.map {|cat_id| cat_id.to_s}
		if OrbitHelper.widget_tags.first == "all"
			files_by_category = ArchiveFile.where(:category_id.in => OrbitHelper.widget_categories).with_tags(OrbitHelper.widget_module_app.tags.collect{|tag| tag.id.to_s}).asc(:sort_number).group_by(&:category)
		else
			files_by_category = ArchiveFile.where(:category_id.in => OrbitHelper.widget_categories).with_tags(OrbitHelper.widget_tags).asc(:sort_number).group_by(&:category)
		end
		cats = files_by_category.keys.collect do |cat|
			files_by_category_tag = files_by_category[cat].group_by(&:tags)
				
			ts = []
			archive_counts = 0
			files_by_category_tag.keys.each do |t|
				archives = []
				archive_counts = archive_counts + 1 
				files_by_category_tag[t].each do |archive|
					a = {
							"archive-title" => archive.title,
							"description" => archive.description,
							"archive-url" => archive.url,
							"archive_url" => archive.get_archive_url(locale, OrbitHelper.widget_more_url)
						}
					
					if t.count > 1
						t.each do |inner_tag|
							idx = ts.index{|tot| tot["tag-name"] == inner_tag.name}
							if !idx.nil?
								break if ts[idx]["archives"].count >= OrbitHelper.widget_data_count
								ts[idx]["archives"] << a
							else
								break if archives.count >= OrbitHelper.widget_data_count
								archives << a
							end
						end
					else
						break if archives.count >= OrbitHelper.widget_data_count
						archives << a
					end
					
				end
				ts << {
					"tag-name" => (t[0].name rescue ""),
					"archives" => archives
				} if !archives.blank? && archive_counts < OrbitHelper.widget_data_count
			end
			{
				"category-id" => cat.id,
				"category-title" => cat.title,
				"tags" => ts
			}
		end
		{
			"categories" => cats,
			"extras" => {"more_url" => OrbitHelper.widget_more_url}
		}
	end
	def get_archives_count(cats_with_archives)
		cats_with_archives.map{|h| (h["archives"].count rescue 0)}.sum
	end
	def get_archives_for_pack_data(categories,tags)
		page_data_count = OrbitHelper.widget_data_count
		sort_order = (ArchiveSortOrder.first['sort_order'] rescue false) ? 1 : -1 #Order with ascending
		subpart = OrbitHelper.get_current_widget
		filter_cache_parent_id = subpart.id.to_s + categories.to_s + tags.to_s + page_data_count.to_s
		locale = I18n.locale.to_s
		archive_cache = ArchiveCache.where(parent_id: filter_cache_parent_id,locale: locale)
		count = archive_cache.count
		if count > 1
		  archive_cache.limit(count-1).destroy
		end
		if archive_cache.count == 0
			@categories = []
			categorie_ids = []
			if categories.first == "all"
				categories = OrbitHelper.widget_module_app.categories
				categories_sort = get_sorted_cat_with_filter(categories,'orm')
				@categories = categories_sort.collect do |cat|
					cat_id = cat.id.to_s
					categorie_ids << cat_id
					{
						"title" => cat.title,
						"id" =>  cat_id
					}
				end
			else
				categories_sort = get_sorted_cat_with_filter(categories,'id')
				@categories = categories_sort.collect do |cat|
					cat_id = cat.id.to_s
					categorie_ids << cat_id
					{
						"title" => cat.title,
						"id" => cat_id
					}
				end
			end
			cats_with_archives = @categories.collect do |cat|
				archives_sorted = ArchiveFile.can_display.where(:category_id => cat["id"]).filter_by_tags(tags).sorted
				serial_number = 0
				archives = archives_sorted.to_a.map.with_index do |archive,idx|
					data, serial_number, idx = archive.get_widget_data(locale, serial_number, idx)
					data
				end
				{
					"category-title" => cat["title"],
					"category-id" => cat["id"],
					"archives" => archives 
				}
			end
			cats_with_archives = cats_with_archives.select{|h| h["archives"].count != 0}
			ArchiveCache.create(parent_id: filter_cache_parent_id,locale: locale,filter_result: cats_with_archives)
		else
		  c = archive_cache.first
		  cats_with_archives = c.filter_result
		end
		cats_with_archives
	end
	def widget
		ArchiveFile.check_sort_number
		page_data_count = OrbitHelper.widget_data_count
		categories = OrbitHelper.widget_categories  #data are categories' ids or 'all' 
		tags = OrbitHelper.widget_tags
		cats_with_archives = get_archives_for_pack_data(categories, tags)
		{
			"categories" => cats_with_archives,
			"extras" => {"more_url" => (OrbitHelper.widget_more_url + '?data_count=' + page_data_count.to_s)}
		}
	end
	private
		def get_sorted_cat_with_filter(categories,cat_type)
			all_categories_with_nil = ArchiveCategory.all.in(sort_number: nil).uniq{|c| c.category_id }.to_a rescue []
			sort_method = ArchiveSortOrder.first.sort_order ? 'asc' : 'desc'
			all_categories_no_nil = ArchiveCategory.all.not_in(sort_number: nil).order_by(sort_number: sort_method).uniq{|c| c.category_id }.to_a rescue []
			all_categories_id = all_categories_no_nil.concat(all_categories_with_nil).collect do |cat|
				cat.category_id.to_s
			end
			if cat_type=='id'
				categories_temp = ModuleApp.where(:key => "archive").first.categories
				categories = categories_temp.select{|cat| categories.include? cat.id.to_s}
			end
			categories_sort = []
			all_categories_id.each do |cat_id|
				category_selected = categories.select{|category| cat_id == category.id.to_s}
				if category_selected.length!=0
					categories_sort  << category_selected[0]
				end
			end
			categories_sort
		end
		def self.get_total_pages
			@@total_pages
		end
end
