class SlackSmartBot

  def public_holidays(country_name, location, year, month, day, add_stats: true, publish_results: true)
    save_stats(__method__) if add_stats
    if config[:public_holidays][:api_key].to_s == ""
      respond "Sorry, I don't have the API key for the public holidays #{config[:public_holidays][:host]}. Set it up on your SmartBot config file."
    else
      begin
        found_location = true
        http = NiceHttp.new("#{config[:public_holidays][:host]}/api/v2")
        if !defined?(@countries_candelarific)
          get_countries_candelarific()
        end
        country = @countries_candelarific.find { |c| c.country_name.match?(/^\s*#{country_name}\s*$/i) }
        if country.nil?
          respond "Country #{country_name} not found"
        else
          country_original_name = country_name.downcase
          country_region_id = country_name.downcase
          country_region_id += "/#{location.downcase}" unless location.empty?
          country_name = country["country_name"]
          country_iso = country["iso-3166"]
          states = []
          if @public_holidays.key?(country_region_id) and @public_holidays[country_region_id].key?(year.to_s)
            holidays = @public_holidays[country_region_id][year.to_s]
          elsif File.exist?(File.join(config.path, "vacations", "#{year}_#{country_region_id.gsub("/", "_").gsub(" ", "_")}.json"))
            holidays = (File.read(File.join(config.path, "vacations", "#{year}_#{country_region_id.gsub("/", "_").gsub(" ", "_")}.json"))).json()
          elsif !location.empty? and File.exist?(File.join(config.path, "vacations", "#{year}_#{country_original_name.gsub("/", "_").gsub(" ", "_")}.json"))
            holidays = (File.read(File.join(config.path, "vacations", "#{year}_#{country_original_name.gsub("/", "_").gsub(" ", "_")}.json"))).json()
            holidays.each do |holiday|
              if holiday.states.is_a?(Array)
                states << holiday.states.name
              else
                states << holiday.states
              end
            end
            holidays = holidays.select { |h| h.states.is_a?(String) and h.states == "All" or (h.states.is_a?(Array) and h.states.name.grep(/^\s*#{location}\s*$/i).length > 0) }
            holidays_specific = holidays.select { |h| h.states.is_a?(Array) and h.states.name.grep(/^\s*#{location}\s*$/i).length > 0 }
            found_location = false if holidays_specific.length == 0
          else
            response = http.get "/holidays?country=#{country_iso}&year=#{year}&day=#{day}&month=#{month}&api_key=#{config[:public_holidays][:api_key]}"
            holidays = response.data.json(:holidays)
            if location != ""
              holidays.each do |holiday|
                if holiday.states.is_a?(Array)
                  states << holiday.states.name
                else
                  states << holiday.states
                end
              end
              holidays = holidays.select { |h| h.states.is_a?(String) and h.states == "All" or (h.states.is_a?(Array) and h.states.name.grep(/^\s*#{location}\s*$/i).length > 0) }
              holidays_specific = holidays.select { |h| h.states.is_a?(Array) and h.states.name.grep(/^\s*#{location}\s*$/i).length > 0 }
              found_location = false if holidays_specific.length == 0
            end
            if day == "" and month == "" and holidays.is_a?(Array) and holidays.length > 0 and found_location
              File.write(File.join(config.path, "vacations", "#{year}_#{country_region_id.gsub("/", "_").gsub(" ", "_")}.json"), holidays.to_json) if holidays.is_a?(Array)
            end
          end
          if day == "" and month == ""
            date = year
          elsif day == ""
            date = "#{year}-#{"%02d" % month.to_i}"
          else
            date = "#{year}-#{"%02d" % month.to_i}-#{"%02d" % day.to_i}"
          end
          if holidays.is_a?(Array) and holidays.length > 0 and found_location
            date_holiday = ""
            messages = ["*Holidays in #{country_name}#{" #{location.downcase.capitalize}" unless location.empty?} in #{date}*"]
            num_holidays_to_show = 0
            all_holidays = []
            states = []
            holidays_to_add = []
            holidays.each do |holiday|
              if holiday.type.join.match?(/holiday/i)
                if location == "" or (location != "" and (holiday.states.is_a?(String) and holiday.states == "All") or (holiday.states.is_a?(Array) and holiday.states.name.grep(/#{location}/i).length > 0))
                  holiday_id = "#{holiday[:date][:datetime][:year]}-#{"%02d" % holiday[:date][:datetime][:month]}-#{"%02d" % holiday[:date][:datetime][:day]} #{holiday[:name]}"
                  unless all_holidays.include?(holiday_id) or
                        (day != "" and holiday[:date][:datetime][:day] != day.to_i) or
                        (month != "" and holiday[:date][:datetime][:month] != month.to_i)
                    all_holidays << holiday_id
                    if day == ""
                      m = holiday[:date][:datetime][:month]
                      d = holiday[:date][:datetime][:day]
                      date_holiday = " #{holiday[:date][:datetime][:year]}-#{"%02d" % m}-#{"%02d" % d} "
                    end
                    num_holidays_to_show += 1
                    unless num_holidays_to_show > 30 and publish_results
                        week_day = Date.new(holiday[:date][:datetime][:year], holiday[:date][:datetime][:month], holiday[:date][:datetime][:day]).strftime("%A")
                        messages << "\t:spiral_calendar_pad:#{date_holiday}*#{holiday[:name]}* _(#{holiday[:type].join(", ")}) (#{week_day})_"
                        messages << "\t#{holiday[:description]}"
                        if location == ""
                        if holiday.states.is_a?(Array)
                          messages << "\tLocations: #{holiday.states.name.sort.join(", ")}"
                        else
                          messages << "\tLocations: #{holiday.states}"
                        end
                      end
                      messages << "\n"
                      holidays_to_add << holiday
                    end
                    if holiday.states.is_a?(Array)
                      states << holiday.states.name
                    else
                      states << holiday.states
                    end
                  end
                end
              end
            end
            @public_holidays[country_region_id] = {} if !@public_holidays.key?(country_region_id)
            @public_holidays[country_region_id][year.to_s] = holidays_to_add if !@public_holidays[country_region_id].key?(year.to_s) and date == year

            if num_holidays_to_show > 30
              messages = ["*Holidays in #{country_name}#{" #{location.downcase.capitalize}" unless location.empty?} in #{date}*"]
              messages << "Too many holidays to show, please refine your search"
            end
          else
            messages = ["*No holidays found in #{country_name}#{" #{location.downcase.capitalize}" unless location.empty?} in #{date}. Be sure the Country and State are written correctly. Try using just the Country, not all countries are supporting States.*"]
          end
          states.flatten!
          states.uniq!
          states.delete("All")
          if states.length > 1 and (location == "" or !found_location)
            messages << "*All States found in #{date} #{country_name}*: #{states.sort.join(", ")}"
            respond messages[-1] if !publish_results
          end
          respond messages.join("\n") unless !publish_results
        end
      rescue Exception => stack
        respond "Sorry, I can't get the public holidays for #{country_name} #{location} in #{date}. Error: #{stack.message}"
        @logger.fatal stack
      end
      return (found_location==true and !country.nil?) if !publish_results
    end
  end
end