import uniq from 'lodash/uniq';

export function Enum(values = [], obj = {}) {
  let type;
  const choices = values;

  if (obj.type && Array.isArray(obj.type)) {
    if (obj.type.includes(Boolean)) choices.push('');
    type = uniq([...obj.type, String]);
  } else if (obj.type) {
    if (obj.type === Boolean) choices.push('');
    type = [String, obj.type];
  } else {
    type = String;
  }

  return {
    ...obj,
    choices,
    type,
    validator: value => typeof value !== 'string' || choices.includes(value),
  };
}

Object.defineProperty(Enum, 'Extend', {
  value: values => (obj = {}) => Enum(values, obj),
});

Enum.State = Enum.Extend(['active', 'disabled', 'error', 'warning', 'success']);
Enum.Size = Enum.Extend(['mini', 'tiny', 'small', 'standard', 'medium', 'large', 'big', 'huge', 'massive']);
Enum.Color = Enum.Extend([
  'red', 'orange', 'yellow', 'olive', 'green', 'teal', 'blue',
  'violet', 'purple', 'pink', 'brown', 'grey', 'black',
]);
Enum.TextAlign = Enum.Extend(['left', 'right', 'center', 'justify']);
Enum.VerticalAlign = Enum.Extend(['top', 'middle', 'bottom']);
Enum.Social = Enum.Extend(['facebook', 'twitter', 'google', 'google plus', 'vk', 'instagram', 'linkedin', 'youtube']);

@@ -102,22 +102,27 @@
 oices = 
+%5B...
 values
+%5D
 ;%0A%0A  if 
@@ -126,20 +126,166 @@
 if (
-obj.type && 
+Array.isArray(obj.choices)) %7B%0A    choices.push(...obj.choices);%0A  %7D%0A%0A  const types = uniq(values.map(value =%3E value.constructor));%0A%0A  if (obj.type) %7B%0A    if (
 Arra
@@ -303,24 +303,26 @@
 bj.type)) %7B%0A
+  
     if (obj.
@@ -354,33 +354,118 @@
 hoices.push('');
-%0A
+ // TODO: Change to true when https://github.com/vuejs/vue/pull/7583 will be merged%0A  
     type = uniq(
@@ -482,18 +482,22 @@
 pe, 
-String
+...types
 %5D);%0A
+  
   %7D 
@@ -501,32 +501,20 @@
  %7D else 
-if (obj.type) 
 %7B%0A
+  
     if (
@@ -561,63 +561,110 @@
     
+  
 type = 
-%5BString, obj.type%5D;%0A  %7D else %7B%0A    type = String
+uniq(%5Bobj.type, ...types%5D);%0A    %7D%0A  %7D else %7B%0A    type = types.length === 1 ? types%5B0%5D : types
 ;%0A  
@@ -740,33 +740,42 @@
  =%3E 
+!
 type
-of value !== 'string'
+s.includes(value.constructor)
  %7C%7C 
@@ -1492,12 +1492,252 @@
 youtube'%5D);%0A
+Enum.Number = Enum.Extend(%5B%0A  1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,%0A  'one', 'two', 'three', 'four', 'five', 'six', 'seven',%0A  'eight', 'nine', 'ten', 'eleven', 'twelve', 'thirteen',%0A  'fourteen', 'fifteen', 'sixteen',%0A%5D);%0A

Improve enum (#122)