<template>
  <div class="ui-input" 
    v-if="types[type]" 
    :style="style" 
    :class="{ require: props.require, error: props.error }">
    <component 
      :is="types[type].component" 
      v-bind="childProps"
      :modelValue="props.modelValue"
      @update:modelValue="newValue => emit('update:modelValue', newValue)"
    >
      <template v-for="(slot, name) in $slots" v-slot:[name]="raw">
        <slot :name="name" v-bind="raw" />
      </template>
    </component>
    <slot />

    <p class="error-msg" v-if="error">{{error}}</p>
  </div>
</template>


<script setup>
import { computed } from 'vue'
import radio from './radio.vue'
import checkbox from './checkbox.vue'
import text from './text.vue'
import select from './select.vue'
import range from './range.vue'
import textarea from './textarea.vue'
import number from './number.vue'
import uiSwitch from './switch.vue'
import file from './file.vue'
import search from './search.vue'
import richtext from './richtext.vue'
import {
  inputPropsDesc, 
  textPropsDesc, 
  selectPropsDesc, 
  checkboxPropsDesc,
  radioPropsDesc,
  rangePropsDesc,
  numberPropsDesc,
  switchPropsDesc,
  textareaPropsDesc,
  filePropsDesc,
  searchPropsDesc,
  richtextPropsDesc
} from './state'

const types = { 
  checkbox: {
    component: checkbox,
    propsDesc: checkboxPropsDesc
  }, 
  text: {
    component: text,
    propsDesc: textPropsDesc
  }, 
  select: {
    component: select,
    propsDesc: selectPropsDesc
  },
  radio: {
    component: radio,
    propsDesc: radioPropsDesc
  },
  range: {
    component: range,
    propsDesc: rangePropsDesc
  },
  number: {
    component: number,
    propsDesc: numberPropsDesc
  },
  switch: {
    component: uiSwitch,
    propsDesc: switchPropsDesc
  },
  textarea: {
    component: textarea,
    propsDesc: textareaPropsDesc
  },
  file: {
    component: file,
    propsDesc: filePropsDesc
    
  },
  search: {
    component: search,
    propsDesc: searchPropsDesc
  },
  richtext: {
    component: richtext,
    propsDesc: richtextPropsDesc
  }
}

const props = defineProps(inputPropsDesc)

const emit = defineEmits(['update:modelValue'])
const type = computed(() => 
  types[props.type] ? props.type : 'text'
)
const childProps = computed(() => {
  const retain = Object.keys(types[type.value].propsDesc)
  const childProps = { }
  for (let key in props) {
    if (retain.includes(key)) {
      childProps[key] = props[key]
    }
  }
  if (!types[props.type]) {
    childProps.type = props.type
  }
  return childProps
})

const style = computed(() => {
  const style = { }
  const keys = Object.keys(childProps.value)

  if (!keys.includes('width')) {
    style.width = props.width
  }

  if (!keys.includes('height')) {
    style.height = props.height
  }

  return style
})

</script>

<script> export default { name: 'ui-input' } </script>