module Lookbook::Params

def boolean?(value)

def boolean?(value)
  value == true || value == false
end

def build_param(param, default)

def build_param(param, default)
  input, options_str = param.text.present? ? param.text.split(" ", 2) : [nil, ""]
  type = param.types&.first
  options = YAML.safe_load(options_str || "~")
  input ||= guess_input(type, default)
  type ||= guess_type(input, default)
  {
    name: param.name,
    input: input_text?(input) ? "text" : input,
    input_type: (input if input_text?(input)),
    options: options,
    type: type,
    default: default
  }
end

def cast(value, type = "String")

def cast(value, type = "String")
  case type.downcase
  when "symbol"
    value.delete_prefix(":").to_sym
  when "hash"
    result = safe_parse_yaml(value, {})
    unless result.is_a? Hash
      Lookbook.logger.debug "Failed to parse '#{value}' into a Hash"
      result = {}
    end
    result
  when "array"
    result = safe_parse_yaml(value, [])
    unless result.is_a? Array
      Lookbook.logger.debug "Failed to parse '#{value}' into an Array"
      result = []
    end
    result
  else
    begin
      type_class = "ActiveModel::Type::#{type}".constantize
      type_class.new.cast(value)
    rescue NameError
      raise ArgumentError, "'#{type}' is not a valid param type to cast to."
    end
  end
end

def guess_input(type, default)

def guess_input(type, default)
  if type&.downcase == "boolean" || (type.blank? && boolean?(default))
    "toggle"
  else
    "text"
  end
end

def guess_type(input, default)

def guess_type(input, default)
  if input&.downcase == "toggle"
    "Boolean"
  elsif input&.downcase == "number"
    "Integer"
  elsif boolean?(default)
    "Boolean"
  elsif default.is_a? Symbol
    "Symbol"
  else
    "String"
  end
end

def input_text?(input)

def input_text?(input)
  [
    "email",
    "number",
    "tel",
    "text",
    "url"
  ].include? input
end

def parse_method_param_str(param_str)

def parse_method_param_str(param_str)
  return nil if param_str[0].nil? || param_str[1].nil?
  name = param_str[0].chomp(":")
  value = param_str[1]&.strip
  value = case value
  when "nil"
    nil
  else
    if value&.first == ":"
      value.delete_prefix(":").to_sym
    else
      YAML.safe_load(value)
    end
  end
  [name, value]
end

def safe_parse_yaml(value, fallback)

def safe_parse_yaml(value, fallback)
  value.present? ? YAML.safe_load(value) : fallback
rescue Psych::SyntaxError
  fallback
end