<script setup>
import { computed, ref, watchEffect } from "vue";
import { cloneDeep, isEqual } from "lodash-es";
import FormPadComponent from "./Pad.vue";
const props = defineProps({
  title: { type: String, required: false },
  initialData: { type: Object, required: false },
  saveCaption: { type: String, required: false, default: "\u0E1A\u0E31\u0E19\u0E17\u0E36\u0E01" },
  cancelCaption: { type: String, required: false, default: "\u0E22\u0E01\u0E40\u0E25\u0E34\u0E01" },
  readonly: { type: Boolean, required: false, default: false },
  showTitle: { type: Boolean, required: false, default: false },
  skipValidation: { type: Boolean, required: false, default: false }
});
const isSaving = ref(false);
const formPadRef = ref();
const formData = ref({});
const formDataOriginalValue = ref();
const emit = defineEmits(["create", "update"]);
function save() {
  formPadRef.value?.flushSanitize?.();
  if (props.skipValidation || formPadRef.value?.isValid) {
    isSaving.value = true;
    emit(isCreating.value ? "create" : "update", cloneDeep(formData.value), callback);
  }
}
function cancel() {
  reset();
}
function reset() {
  formDataOriginalValue.value = void 0;
  formPadRef.value?.reset();
  loadFormData();
}
const callback = {
  done: function() {
    isSaving.value = false;
    reset();
  },
  error: function() {
    isSaving.value = false;
  }
};
const isDataChange = computed(() => {
  return !(isCreating.value ? isEqual(formData.value, createOriginalValue.value) : isEqual(formData.value, formDataOriginalValue.value));
});
const isCreating = computed(() => {
  return !formDataOriginalValue.value;
});
const createOriginalValue = computed(() => {
  return Object.assign({}, props.initialData);
});
const loadFormData = () => {
  if (formDataOriginalValue.value) {
    formData.value = cloneDeep(formDataOriginalValue.value);
  } else {
    formData.value = Object.assign({}, cloneDeep(props.initialData));
  }
};
const operation = ref({ isDataChange, isCreating, isSaving, save, cancel });
watchEffect(loadFormData);
function setOriginalData(originalData) {
  formDataOriginalValue.value = originalData;
}
defineExpose({ setOriginalData, operation, formPad: formPadRef });
</script>

<template>
    <VCard flat>
      <VToolbar v-if="showTitle">
        <slot name="titleToolbar" :operation="operation">
          <VToolbarTitle>
            <slot name="title" :operation="operation">
              {{ isCreating ? "New" : "Edit" }} {{ title }}
            </slot>
          </VToolbarTitle>
        </slot>
      </VToolbar>
      <VCardText>
        <form-pad
            ref="formPadRef"
            v-model="formData"
            :originalData="formDataOriginalValue"
            :readonly="readonly"
            isolated
            v-bind="$attrs"
        >
          <template #default="slotData">
            <slot
                v-bind="slotData"
                :is-creating="isCreating"
                :is-data-change="isDataChange"
            />
          </template>
        </form-pad>
      </VCardText>
      <VCardActions>
        <slot name="action" :operation="operation">
          <VSpacer />
          <VBtn
              color="primary"
              variant="flat"
              :loading="isSaving"
              :disabled="!isDataChange"
              @click="save"
              v-if="!readonly"
          >
            {{ saveCaption }}
          </VBtn>
          <VBtn
              color="error"
              variant="flat"
              :disabled="isSaving"
              @click="cancel"
          >
            {{ cancelCaption }}
          </VBtn>
        </slot>
      </VCardActions>
    </VCard>
</template>
