class ArchivesController < ApplicationController
	#avoid the categories to be not in the ArchiveCategory
    def serve_cmap
        serve_path=File.expand_path("../../assets/javascripts/archive/pdf/bcmaps/#{params[:file_name]}.#{params[: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 index
	    params = OrbitHelper.params
		@@total_pages = 1
		cats_last = []
		sort_order = (ArchiveSortOrder.first['sort_order'] rescue false) ? 1 : -1 #Order with ascending
	    if !params['title'].nil?
	        files_by_category = ArchiveFile.where(is_hidden: false).order_by(:created_at => "desc").group_by(&:category)
	        categories = files_by_category.keys
	        categories_sort = get_sorted_cat_with_filter(categories,'orm')
	        categories_sort.each do |category|
    			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
        				statuses = archive.statuses_with_classname.collect do |status|
        			        {
        			          "status" => status["name"] || "",
        			          "status-class" => "status-#{status['classname']}"
        			        }
        			    end
        			    files = []
        				archive.archive_file_multiples.order_by(:sort_number=>'desc').each do |file|
        					if file.choose_lang.include?(I18n.locale.to_s)
        						title = (file.file_title.blank? ?  File.basename(file.file.path) : file.file_title) rescue ""
        						extension = file.file.file.extension.downcase rescue ""
        						serial_number += 1
        						files <<  {
        							"file-name" => title,
        							"file-type" =>  extension,
        							"file-url" => "/xhr/archive/download?file=#{file.id}",
        							"serial_number" => serial_number
        						}
        					end
        				end
                        if archive.urls.present?
	                        archive.urls.each_with_index do |url,i|
	                        	serial_number += 1
		                        files <<  {
		                            "file-name" => archive.title,
		                            "file-type" => archive.get_url_text(i),
		                            "file-url" => url,
        							"serial_number" => serial_number
		                        }
		                    end
		                end
        				archives << {
        					"archive-title" => archive.title,
                            "description" => archive.description,
        					"created_at" => archive.created_at.strftime('%Y%m%d').to_i,
        					"archive-url" => archive.url,
        					"url" => archive.url,
        					"statuses" => statuses,
        					"sort_number" => archive.sort_number,
        					"is_top" => (archive.is_top ? 1 : 0),
        					"files" => files,
    						"idx" => (idx + 1)
        				}
        			end
    			end
    			if flag
        			cats_last << {
        				"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 = OrbitHelper.page_categories
     		tags = OrbitHelper.page_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.where(is_hidden: false,:title.nin=>["",nil]).filter_by_categories.order_by(:created_at => "desc")
     			group_archive_files = {}
     			cats = []
     			each_data_count = []
     			archive_files_ids = archive_files.pluck(:id)
     			archive_files_ids_count = archive_files_ids.count
     			tags.each do |tag_id|
     				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.sort_by{|k| [(k["is_top"] ? 0 : 1) ,(k["sort_number"].nil? ? Float::INFINITY : sort_order * k["sort_number"].to_i),-k["created_at"].to_i]}.map.with_index do |archive,idx|
	     					statuses = archive.statuses_with_classname.collect do |status|
		    			        {
		    			          "status" => status["name"] || "",
		    			          "status-class" => "status-#{status['classname']}"
		    			        }
		    			    end
		    			    files = []
		    				archive.archive_file_multiples.order_by(:sort_number=>'desc').each do |file|
		    					if file.choose_lang.include?(I18n.locale.to_s)
		    						title = (file.file_title.blank? ?  File.basename(file.file.path) : file.file_title) rescue ""
		    						extension = file.file.file.extension.downcase rescue ""
		    						serial_number += 1
		    						files <<  {
		    							"file-name" => title,
		    							"file-type" =>  extension,
		    							"file-url" => "/xhr/archive/download?file=#{file.id}",
        								"serial_number" => serial_number
		    						}
		    					end
		    				end
			                if archive.urls.present?
			                    archive.urls.each_with_index do |url,i|
			                    	serial_number += 1
			                        files <<  {
			                            "file-name" => archive.title,
			                            "file-type" => archive.get_url_text(i),
			                            "file-url" => url,
        								"serial_number" => serial_number
			                        }
			                    end
			                end
		    				{
		    					"archive-title" => archive.title,
		                        "description" => archive.description,
		    					"created_at" => archive.created_at.strftime('%Y%m%d').to_i,
		    					"archive-url" => archive.url,
		    					"url" => archive.url,
		    					"statuses" => statuses,
		    					"sort_number" => archive.sort_number,
		    					"is_top" => (archive.is_top ? 1 : 0),
		    					"files" => files,
		    					"idx" => (idx + 1)
		    				}
			    		end
			    		each_data_count.push(archives.length)
		    			sorted = archives
		    			cats << {
		    				"category-title" => tag_name,
		    				"archives" => sorted,
		    				"url_to_edit" => url_to_edit
		    			}
     				end
     			end
     			cats_last = cats  			
     		else
    		files_by_category = ArchiveFile.where(is_hidden: false,:title.nin=>["",nil]).filter_by_categories.filter_by_tags.order_by(:created_at => "desc").group_by(&:category)
    		each_data_count = []
    		categories = files_by_category.keys
	        categories_sort = get_sorted_cat_with_filter(categories,'orm')
    		cats = categories_sort.collect do |category|
    			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].sort_by{|k| [(k["is_top"] ? 0 : 1) ,(k["sort_number"].nil? ? Float::INFINITY : sort_order * k["sort_number"].to_i),-k["created_at"].to_i]}.collect.with_index do |archive,idx|
    				statuses = archive.statuses_with_classname.collect do |status|
    			        {
    			          "status" => status["name"] || "",
    			          "status-class" => "status-#{status['classname']}"
    			        }
    			    end
    			    files = []
    				archive.archive_file_multiples.order_by(:sort_number=>'desc').each do |file|
    					if file.choose_lang.include?(I18n.locale.to_s)
    						serial_number += 1
    						title = (file.file_title.blank? ?  File.basename(file.file.path) : file.file_title) rescue ""
    						extension = file.file.file.extension.downcase rescue ""
    						files <<  {
    							"file-name" => title,
    							"file-type" =>  extension,
    							"file-url" => "/xhr/archive/download?file=#{file.id}",
    							"serial_number" => serial_number
    						}
    					end
    				end
                    if archive.urls.present?
                        archive.urls.each_with_index do |url,i|
                        	serial_number += 1
	                        files <<  {
	                            "file-name" => archive.title,
	                            "file-type" => archive.get_url_text(i),
	                            "file-url" => url,
    							"serial_number" => serial_number
	                        }
	                    end
                    end
    				{
    					"archive-title" => archive.title,
                        "description" => archive.description,
    					"created_at" => archive.created_at.strftime('%Y%m%d').to_i,
    					"archive-url" => archive.url,
    					"url" => archive.url,
    					"statuses" => statuses,
    					"sort_number" => archive.sort_number,
    					"is_top" => (archive.is_top ? 1 : 0),
    					"files" => files,
    					"idx" => (idx + 1)
    				}
    			end
    			each_data_count.push(archives.length)
    			sorted = archives
    			{
    				"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
		{
			"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")
            }
		}
	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 = @path.split("/").last
                @ext = @path.split("/").last.to_s.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_with_index do |archive,index|
				a = {
						"archive-title" => archive.title,
                        "description" => archive.description,
						"archive-url" => archive.url,
						"archive_url" => OrbitHelper.widget_more_url
					}
				
				if t.count > 1
					t.each do |inner_tag|
						index = ts.index{|tot| tot["tag-name"] == inner_tag.name}
						if !index.nil?
							break if ts[index]["archives"].count >= OrbitHelper.widget_data_count
							ts[index]["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-title" => cat.title,
				"tags" => ts
			}
		end
		{
			"categories" => cats,
			"extras" => {"widget-title" => "Archives","more_url" => OrbitHelper.widget_more_url}
		}
	end

	def widget
        page_data_count = OrbitHelper.widget_data_count
		categories = OrbitHelper.widget_categories  #data are categories' ids or 'all' 
		@categories = []
		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|
				{
					"title" => cat.title,
					"id" => cat.id.to_s
				}
			end
		else
		    categories_sort = get_sorted_cat_with_filter(categories,'id')
			@categories = categories_sort.collect do |cat|
				{
					"title" => cat.title,
					"id" => cat.id.to_s
				}
			end
		end
		cats = @categories.collect do |cat|
			if ArchiveSortOrder.first.sort_order #Order with ascending
			    archives_all = ArchiveFile.can_display.where(:category_id => cat["id"]).filter_by_tags(OrbitHelper.widget_tags)
			    temp_with_nil = archives_all.in(sort_number: nil).order_by(created_at: 'desc')
    			temp_no_nil = archives_all.not_in(sort_number: nil).order_by(sort_number: 'asc',created_at: 'desc')
    			archives_temp = temp_no_nil.concat(temp_with_nil)
    			archives = archives_temp.collect do |archive|
    			    if archive.archive_file_multiples.count==0
    			        url = (archive[:url][OrbitHelper.get_site_locale].to_s.empty? ? 'javascript:void' : archive[:url][OrbitHelper.get_site_locale])
    			    else
    				    url = archive.archive_file_multiples.count > 1 ? (OrbitHelper.widget_more_url + '?title=' + archive.title.to_s) : "/xhr/archive/download?file=#{archive.archive_file_multiples.first.id}"
    				end
    				{
    					"archive-title" => archive.title,
                        "description" => archive.description,
    					"archive-url" => archive.url,
    					"archive_url" => url
    				}
    			end
			else
			    archives_temp = ArchiveFile.can_display.where(:category_id => cat["id"]).filter_by_tags(OrbitHelper.widget_tags).order_by(sort_number: 'desc',created_at: 'desc')
			    archives = archives_temp.collect do |archive|
    				if archive.archive_file_multiples.count==0
    			        url = (archive[:url][OrbitHelper.get_site_locale].to_s.empty? ? 'javascript:void' : archive[:url][OrbitHelper.get_site_locale])
    			    else
    				    url = archive.archive_file_multiples.count > 1 ? (OrbitHelper.widget_more_url + '?title=' + archive.title.to_s) : "/xhr/archive/download?file=#{archive.archive_file_multiples.first.id}"
    				end
    				{
    					"archive-title" => archive.title,
                        "description" => archive.description,
    					"archive-url" => archive.url,
    					"archive_url" => url
    				}
    			end
			end
			{
				"category-title" => cat["title"],
				"category-id" => cat["id"],
				"archives" => archives 
			}
		end
		{
			"categories" => cats,
			"extras" => {"widget-title" => "Archives","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
