#!/usr/bin/env ruby

require_relative 'shared_constants'
require_relative 'lut_helper'

# Data cleaning and normalization module
module DataCleaner
  extend self

  # Clean a field value based on its type
  def clean_field(value, type = :general)
    return nil if value.nil?
    
    # Remove non-printable characters and strip whitespace
    cleaned = value.to_s.gsub(/\p{C}/, '').strip
    return nil if cleaned.empty?
    
    case type
    when :user
      normalize_user(cleaned)
    when :substance
      normalize_substance(cleaned)
    when :route
      normalize_route(cleaned)
    when :dose
      normalize_dose(cleaned)
    when :timestamp
      normalize_timestamp(cleaned)
    else
      cleaned
    end
  end

  # Clean a complete entry hash
  def clean_entry(entry)
    return nil if entry.nil?
    
    {
      user: clean_field(entry['user'] || entry[:user], :user),
      substance: clean_field(entry['med'] || entry['substance'] || entry[:substance], :substance),
      route: clean_field(entry['ROA'] || entry['route'] || entry[:route], :route),
      dose: clean_field(entry['amount'] || entry['dose'] || entry[:dose], :dose),
      timestamp: clean_field(entry['timestamp'] || entry['date'] || entry[:timestamp], :timestamp)
    }
  end

  # Validate that an entry has required fields
  def valid_entry?(entry)
    return false if entry.nil?
    
    required_fields = [:user, :substance, :timestamp]
    required_fields.all? { |field| !entry[field].nil? && !entry[field].empty? }
  end

  # Safely parse a value with error handling
  def safe_parse(value, type, default = nil)
    return default if value.nil?
    
    case type
    when :time
      Time.parse(value.to_s)
    when :datetime
      DateTime.parse(value.to_s)
    when :date
      Date.parse(value.to_s)
    when :float
      Float(value.to_s)
    when :integer
      Integer(value.to_s)
    when :year
      year = Integer(value.to_s)
      validate_year(year) ? year : default
    else
      value.to_s
    end
  rescue ArgumentError, TypeError, StandardError
    default
  end

  # Validate input parameters
  def validate_user(user)
    return false if user.nil? || user.empty?
    
    user = user.to_s.strip
    return false if user.length < SharedConstants::Validation::MIN_USERNAME_LENGTH
    return false if user.length > SharedConstants::Validation::MAX_USERNAME_LENGTH
    return false unless user.match?(SharedConstants::Validation::USERNAME_PATTERN)
    
    true
  end

  def validate_year(year)
    return false unless year.is_a?(Integer)
    return false if year < SharedConstants::Validation::MIN_YEAR
    return false if year > SharedConstants::Validation::MAX_YEAR
    
    true
  end

  def validate_substance(substance)
    return false if substance.nil? || substance.empty?
    
    substance = substance.to_s.strip
    return false if substance.length < SharedConstants::Validation::MIN_SUBSTANCE_LENGTH
    return false if substance.length > SharedConstants::Validation::MAX_SUBSTANCE_LENGTH
    
    true
  end

  private

  # Normalize user names (lowercase, no special chars for matching)
  def normalize_user(user)
    user.to_s.downcase.strip
  end

  # Normalize substance names using LUT
  def normalize_substance(substance)
    LutHelper.normalize_substance_with_lut(substance)
  end

  # Normalize route names using LUT
  def normalize_route(route)
    LutHelper.normalize_route_with_lut(route)
  end

  # Normalize dose strings
  def normalize_dose(dose)
    dose.to_s.strip.gsub(/\s+/, ' ')
  end

  # Normalize timestamp strings
  def normalize_timestamp(timestamp)
    timestamp.to_s.strip
  end
end