<template>
  <template v-for="item in formItems" :key="item.title">
    <form-cell v-if="item.cellType === 'formCellItem'" v-bind="item" :form="form"
      :disableChange="isDisableChange(item)" @change="change" @addRule="addRule" />
  </template>
  <form-cell />
</template>
<script setup>
import { computed, provide, ref, watch } from 'vue';
import verifyForm from './verify.js';
import { collectAutoFillChanges } from './auto-fill.mjs';

import FormCell from './form-cell/index.vue';
// import CustomCell from './custom-cell/index.vue';

const emits = defineEmits(['change']);
const props = defineProps({
  form: {
    type: Object,
    default: () => ({})
  },
  items: {
    type: Array,
    default: () => []
  },
  disableTitles: {
    type: Array,
    default: () => ([])
  },
  rule: {
    type: Object,
    default: () => ({})
  }
})

const formCellType = ['input', 'select', 'date', 'radio', 'region', 'textarea', 'multiSelectAndOther', 'selfMultipleDiseases', 'files','diagnosis','positiveFind'];
const formCellTitle = ['surgicalHistory'];
const customCellType = ['BMI', 'bloodPressure'];
const disabledMap = computed(() => props.disableTitles.reduce((m, i) => {
  if (typeof i === 'string' && i.trim()) {
    m[i] = true;
  }
  return m
}, {}))


const customRule = ref({});

const formItems = computed(() => {
  return props.items.map(i => {
    let cellType = '';
    if (customCellType.includes(i.type)) {
      cellType = 'customCellItem';
    } else if (formCellType.includes(i.type) || formCellTitle.includes(i.title)) {
      cellType = 'formCellItem';
    }
    return { ...i, cellType }
  })
})

const rules = computed(() => ({ ...customRule.value, ...props.rule }));

function addRule({ title, fn }) {
  if (title && props.items.some(i => i.title === title) && typeof fn === 'function') {
    customRule.value[title] = fn;
  }
}

function change(data) {
  emits('change', data)
}

function isDisableChange(item) {
  return Boolean(disabledMap.value[item.title] || item.readonly === true || item.readonly === 'true');
}

function syncAutoFill() {
  const changes = collectAutoFillChanges(formItems.value, props.form);
  changes.forEach(change);
}

watch(
  () => [props.items, props.form],
  syncAutoFill,
  { deep: true, immediate: true }
);

function verify() {
  return verifyForm(props.items, rules.value, props.form)
}

defineExpose({ verify })

</script>

<style>
@import './cell-style.css';
</style>
