export const adjectives: string[] = ["afraid", "all", "beige", "better", "big", "blue", "bold", "brave", "breezy", "bright", "brown", "bumpy", "busy", "calm", "chatty", "chilly", "chubby", "clean", "clear", "clever", "cold", "common", "cool", "cozy", "crisp", "cuddly", "curly", "curvy", "cute", "cyan", "dark", "deep", "dirty", "dry", "dull", "eager", "early", "easy", "eight", "eighty", "eleven", "empty", "every", "fair", "famous", "fancy", "fast", "few", "fiery", "fifty", "fine", "five", "flat", "floppy", "fluffy", "forty", "four", "frank", "free", "fresh", "fruity", "full", "funky", "funny", "fuzzy", "gentle", "giant", "gold", "good", "goofy", "great", "green", "grumpy", "happy", "heavy", "hip", "honest", "hot", "huge", "humble", "hungry", "icy", "itchy", "jolly", "khaki", "kind", "large", "late", "lazy", "legal", "lemon", "light", "little", "long", "loose", "loud", "lovely", "lucky", "major", "many", "metal", "mighty", "modern", "moody", "neat", "new", "nice", "nine", "ninety", "odd", "old", "olive", "open", "orange", "perky", "petite", "pink", "plain", "plenty", "polite", "pretty", "proud", "public", "puny", "purple", "quick", "quiet", "rare", "ready", "real", "red", "rich", "ripe", "salty", "seven", "shaggy", "shaky", "sharp", "shiny", "short", "shy", "silent", "silly", "silver", "six", "sixty", "slick", "slimy", "slow", "small", "smart", "smooth", "social", "soft", "solid", "some", "sour", "sparkly", "spicy", "spotty", "stale", "strict", "strong", "sunny", "sweet", "swift", "tall", "tame", "tangy", "tasty", "ten", "tender", "thick", "thin", "thirty", "three", "tidy", "tiny", "tired", "tough", "tricky", "true", "twelve", "twenty", "two", "upset", "vast", "violet", "wacky", "warm", "wet", "whole", "wicked", "wide", "wild", "wise", "witty", "yellow", "young", "yummy"]

export const nouns: string[] = ["actors", "ads", "adults", "aliens", "animals", "ants", "apes", "apples", "areas", "baboons", "badgers", "bags", "balloons", "bananas", "banks", "bars", "baths", "bats", "beans", "bears", "beds", "beers", "bees", "berries", "bikes", "birds", "boats", "bobcats", "books", "bottles", "boxes", "breads", "brooms", "buckets", "bugs", "buses", "bushes", "buttons", "camels", "cameras", "candies", "candles", "canyons", "carpets", "carrots", "cars", "cases", "cats", "chairs", "chefs", "chicken", "cities", "clocks", "cloths", "clouds", "clowns", "clubs", "coats", "cobras", "coins", "colts", "comics", "cooks", "corners", "cougars", "cows", "crabs", "crews", "cups", "cycles", "dancers", "days", "deer", "deserts", "dingos", "dodos", "dogs", "dolls", "donkeys", "donuts", "doodles", "doors", "dots", "dragons", "drinks", "dryers", "ducks", "eagles", "ears", "eels", "eggs", "emus", "ends", "experts", "eyes", "facts", "falcons", "fans", "feet", "files", "flies", "flowers", "forks", "foxes", "friends", "frogs", "games", "garlics", "geckos", "geese", "ghosts", "gifts", "glasses", "goats", "grapes", "groups", "guests", "hairs", "hands", "hats", "heads", "hoops", "hornets", "horses", "hotels", "hounds", "houses", "humans", "icons", "ideas", "impalas", "insects", "islands", "items", "jars", "jeans", "jobs", "jokes", "keys", "kids", "kings", "kiwis", "knives", "lamps", "lands", "laws", "lemons", "lies", "lights", "lilies", "lines", "lions", "lizards", "llamas", "loops", "mails", "mammals", "mangos", "maps", "masks", "meals", "melons", "memes", "meteors", "mice", "mirrors", "moles", "moments", "monkeys", "months", "moons", "moose", "mugs", "nails", "needles", "news", "nights", "numbers", "olives", "onions", "oranges", "otters", "owls", "pandas", "pans", "pants", "papayas", "papers", "parents", "parks", "parrots", "parts", "paths", "paws", "peaches", "pears", "peas", "pens", "pets", "phones", "pianos", "pigs", "pillows", "places", "planes", "planets", "plants", "plums", "poems", "poets", "points", "pots", "pugs", "pumas", "queens", "rabbits", "radios", "rats", "ravens", "readers", "regions", "results", "rice", "rings", "rivers", "rockets", "rocks", "rooms", "roses", "rules", "sails", "schools", "seals", "seas", "sheep", "shirts", "shoes", "showers", "shrimps", "sides", "signs", "singers", "sites", "sloths", "snails", "snakes", "socks", "spiders", "spies", "spoons", "squids", "stamps", "stars", "states", "steaks", "streets", "suits", "suns", "swans", "symbols", "tables", "taxes", "taxis", "teams", "teeth", "terms", "things", "ties", "tigers", "times", "tips", "tires", "toes", "tools", "towns", "toys", "trains", "trams", "trees", "turkeys", "turtles", "vans", "views", "walls", "wasps", "waves", "ways", "webs", "weeks", "windows", "wings", "wolves", "wombats", "words", "worlds", "worms", "yaks", "years", "zebras", "zoos"
]

export const verbs: string[] = ["accept", "act", "add", "admire", "agree", "allow", "appear", "argue", "arrive", "ask", "attack", "attend", "bake", "bathe", "battle", "beam", "beg", "begin", "behave", "bet", "boil", "bow", "brake", "brush", "build", "burn", "buy", "call", "camp", "care", "carry", "change", "cheat", "check", "cheer", "chew", "clap", "clean", "cough", "count", "cover", "crash", "create", "cross", "cry", "cut", "dance", "decide", "deny", "design", "dig", "divide", "do", "double", "doubt", "draw", "dream", "dress", "drive", "drop", "drum", "eat", "end", "enjoy", "enter", "exist", "fail", "fall", "feel", "fetch", "film", "find", "fix", "flash", "float", "flow", "fly", "fold", "follow", "fry", "give", "glow", "go", "grab", "greet", "grin", "grow", "guess", "hammer", "hang", "happen", "heal", "hear", "help", "hide", "hope", "hug", "hunt", "invent", "invite", "itch", "jam", "jog", "join", "joke", "judge", "juggle", "jump", "kick", "kiss", "kneel", "knock", "know", "laugh", "lay", "lead", "learn", "leave", "lick", "lie", "like", "listen", "live", "look", "lose", "love", "make", "march", "marry", "mate", "matter", "melt", "mix", "move", "nail", "notice", "obey", "occur", "open", "own", "pay", "peel", "pick", "play", "poke", "post", "press", "prove", "pull", "pump", "punch", "push", "raise", "read", "refuse", "relate", "relax", "remain", "repair", "repeat", "reply", "report", "rescue", "rest", "retire", "return", "rhyme", "ring", "roll", "rule", "run", "rush", "say", "scream", "search", "see", "sell", "send", "serve", "shake", "share", "shave", "shine", "shop", "shout", "show", "sin", "sing", "sink", "sip", "sit", "sleep", "slide", "smash", "smell", "smile", "smoke", "sneeze", "sniff", "sort", "speak", "spend", "stand", "stare", "start", "stay", "stick", "stop", "strive", "study", "swim", "switch", "take", "talk", "tan", "tap", "taste", "teach", "tease", "tell", "thank", "think", "throw", "tickle", "tie", "trade", "train", "travel", "try", "turn", "type", "unite", "vanish", "visit", "wait", "walk", "warn", "wash", "watch", "wave", "wear", "win", "wink", "wish", "wonder", "work", "worry", "write", "yawn", "yell"]

export const adverbs: string[] = ["bravely", "brightly", "busily", "daily", "freely", "hungrily", "joyously", "knowingly", "lazily", "noisily", "oddly", "politely", "quickly", "quietly", "rapidly", "safely", "sleepily", "slowly", "truly", "yearly"]

function random(arr: string[]): string { return arr[Math.floor(Math.random()*arr.length)] }
function longest(arr: string[]){ return arr.reduce((a, b) => a.length > b.length ? a : b) }
function shortest(arr: string[]){ return arr.reduce((a, b) => a.length < b.length ? a : b) }

export interface Options {
	separator?: string
	capitalize?: boolean
	adjectiveCount?: number
	addAdverb?: boolean
}

/**
 * Returns the human-id
 *
 * @param {Options|string|boolean} [options = {}]
 * @returns {string}
 */
export function humanId(options: Options | string | boolean = {}): string {
	if(typeof options === 'string') options = { separator: options }
  if(typeof options === 'boolean') options = { capitalize: options }
	const {
    separator = '',
    capitalize = true,
    adjectiveCount = 1,
    addAdverb = false
  } = options

	let res = [
		...[...Array(adjectiveCount)].map(_ => random(adjectives)),
		random(nouns),
		random(verbs),
		...( (addAdverb) ? [random(adverbs)] : []),
	]

	if(capitalize)
		res = res.map(r => r.charAt(0).toUpperCase() + r.substr(1))

	return res.join(separator)
}

/**
 * Returns the pool size for a set of options
 *
 * @param {Options} [options = {}]
 * @returns {number}
 */
export function poolSize(options: Options = {}): number {
  const { adjectiveCount = 1, addAdverb = false } = options
  return (adjectives.length * adjectiveCount) * nouns.length * verbs.length * (addAdverb ? adverbs.length : 1)
}

/**
 * Returns the max length for a set of options
 *
 * @param {Options} [options = {}]
 * @returns {number}
 */
export function maxLength(options: Options = {}): number {
  const { adjectiveCount = 1, addAdverb = false, separator = '' } = options
  return (longest(adjectives).length * adjectiveCount) +
    (adjectiveCount * separator.length) +
    longest(nouns).length +
    separator.length +
    longest(verbs).length +
    (addAdverb ? longest(adverbs).length + separator.length : 0)
}

/**
 * Returns the min length for a set of options
 *
 * @param {Options} [options = {}]
 * @returns {number}
 */
export function minLength(options: Options = {}): number {
  const { adjectiveCount = 1, addAdverb = false, separator = '' } = options
  return (shortest(adjectives).length * adjectiveCount) +
    (adjectiveCount * separator.length) +
    shortest(nouns).length +
    separator.length +
    shortest(verbs).length +
    (addAdverb ? shortest(adverbs).length + separator.length : 0)
}

export default humanId