lib/wolf_core/utils/string_utils.rb



module WolfCore
  module StringUtils
    def camelcase_to_spaces(str)
      return if str.nil?

      str.to_s.gsub(/([A-Z])/, ' \1').strip.downcase.capitalize
    end

    def to_snake_case(str)
      return if str.nil?

      str.to_s.gsub(/\s+/, "_").downcase
    end

    def to_kebab_case(str)
      return if str.nil?

      str.to_s.gsub(/\s+/, "-").downcase
    end

    def remove_non_alphanumeric_chars(str, exceptions: nil)
      return if str.nil?

      exceptions ||= []
      exceptions = Array(exceptions)
      escaped_exceptions = exceptions.map { |char| Regexp.escape(char) }.join
      regex = /[^a-zA-Z0-9#{escaped_exceptions}]/
      str.to_s.gsub(regex, "")
    end

    def clean_phone_number(phone)
      return if phone.nil?

      cleaned_phone = phone.to_s.gsub(/\D/, "")
      cleaned_phone[-10, 10]
    end

    def remove_blank_spaces(str)
      return if str.nil?

      str.to_s.gsub(/\s+/, "")
    end

    def hash_str_to_json(hash_str)
      hash_str&.to_s&.gsub("=>", ":")&.gsub('\"', '"')&.gsub("{", "{")&.gsub("}", "}")&.gsub(/(\w+)(?=\s*:)/) do |key|
        "\"#{key}\""
      end
    end

    def deep_parse_json(input)
      while input.is_a?(String)
        begin
          input = JSON.parse(input)
        rescue JSON::ParserError
          break
        end
      end

      input || {}
    end

    def valid_url?(url)
      return false unless url.instance_of?(String)

      uri = URI.parse(url)
      uri.is_a?(URI::HTTP) || (uri.is_a?(URI::HTTPS) && !uri.host.nil?)
    rescue URI::InvalidURIError
      false
    end

    def base64_encoded?(str)
      return false unless str.is_a?(String) && str.length % 4 == 0

      base64_regex = %r{^[A-Za-z0-9+/]+={0,2}$}
      str.match?(base64_regex)
    end

    def valid_json?(str)
      return false unless str.is_a?(String)

      JSON.parse(str)
      true
    rescue JSON::ParserError
      false
    end

    def split_address(address_string)
      address_string = address_string&.dup
      address_string ||= ""
      address = { street: nil, city: nil, state: nil, zip: nil }
      city_and_state_regex_found = false

      city_and_state_regex = /\b([A-Za-z\s]+),\s*([A-Za-z]{2})\b/
      zip_regex = /\d{5}(?:-\d{4})?$/
      street_regex = /\A([^,]+)/
      state_regex = /\b[A-Za-z]{2}\b/
      city_regex = /\b[a-zA-Z0-9\s]{2,}\b/

      if match_data = address_string.match(city_and_state_regex)
        address[:city] = match_data[1].strip
        address[:state] = match_data[2].strip
        address_string.sub!(city_and_state_regex, "")
        city_and_state_regex_found = true
      end

      if zip_match = address_string.match(zip_regex)
        address[:zip] = zip_match[0].strip
        address_string.sub!(zip_regex, "")
      end

      if street_match = address_string.match(street_regex)
        address[:street] = street_match[0].strip
        address[:street] = nil if address[:street].empty?
        address_string.sub!(street_regex, "")
      end

      return address if city_and_state_regex_found

      if state_match = address_string.match(state_regex)
        address[:state] = state_match[0].strip
        address_string.sub!(state_regex, "")
      end

      if city_match = address_string.match(city_regex)
        address[:city] = city_match[0].strip
        address_string.sub!(city_regex, "")
      end

      address
    end

    def split_name(full_name, name_range: nil, lastname_range: nil, if_one_word: nil)
      if_one_word = {} unless if_one_word.is_a?(Hash)
      if_one_word.merge!(lastname: "-") if if_one_word[:lastname].nil?
      words = full_name.strip.split

      return { first_name: words[0], last_name: if_one_word[:lastname] } if words.length == 1
      return { first_name: words[0], last_name: words[1] } if words.length == 2

      name_range ||= 0..-2
      lastname_range ||= -1..-1

      name = words[name_range].join(" ")
      lastname = words[lastname_range].join(" ")
      { first_name: name, last_name: lastname }
    end
  end
end