<script setup>
import { computed, reactive } from "vue";
import { useRuntimeConfig, useNuxtApp } from "#app";
import { useNctDynamicZodSchema, nctHasPermission } from "#imports";
import { useChangeCase } from "@vueuse/integrations/useChangeCase";
const props = defineProps({
  schema: { type: Object, required: true },
  initialState: { type: Object, required: false },
  loading: { type: Boolean, required: false }
});
const emit = defineEmits(["submit", "close"]);
const config = useRuntimeConfig();
const { formHiddenFields } = config.public.crudTable;
const filteredFields = props.schema.fields.filter((field) => {
  if (formHiddenFields.includes(field.name)) return false;
  if (field.name === "status" && !props.initialState) return false;
  return true;
});
const { $nctUser } = useNuxtApp();
const user = $nctUser;
const canUpdateStatus = computed(() => nctHasPermission(user.value, props.schema.resource, "update_status"));
const formSchema = useNctDynamicZodSchema(filteredFields, !!props.initialState);
const state = reactive(
  filteredFields.reduce(
    (acc, field) => {
      let value = props.initialState?.[field.name];
      if ((field.name.endsWith("_id") || field.name.endsWith("Id")) && value && typeof value === "object" && "id" in value) {
        value = value.id;
      } else if ((field.name.endsWith("_id") || field.name.endsWith("Id")) && value === void 0) {
        const relationName = field.name.endsWith("_id") ? field.name.replace("_id", "") : field.name.replace("Id", "");
        const relationValue = props.initialState?.[relationName];
        if (relationValue && typeof relationValue === "object" && "id" in relationValue) {
          value = relationValue.id;
        }
      }
      acc[field.name] = value ?? (field.type === "boolean" ? false : void 0);
      return acc;
    },
    {}
  )
);
const processedFields = computed(
  () => filteredFields.map((field) => {
    let label = field.name;
    if (label.endsWith("_id")) {
      label = label.replace("_id", "");
    } else if (label.endsWith("Id")) {
      label = label.replace("Id", "");
    }
    label = useChangeCase(label, "capitalCase").value;
    return {
      ...field,
      label
    };
  })
);
function handleSubmit(event) {
  const data = { ...event.data };
  if (props.initialState && "password" in data) {
    delete data.password;
  }
  emit("submit", data);
  emit("close");
}
</script>

<template>
  <div class="max-h-[80vh] overflow-y-auto p-4">
    <UForm
      :schema="formSchema"
      :state="state"
      class="space-y-4"
      @submit="handleSubmit"
    >
      <template
        v-for="field in processedFields"
        :key="field.name"
      >
        <UFormField
          :label="field.label"
          :name="field.name"
        >
          <UCheckbox
            v-if="field.type === 'boolean'"
            :id="field.name"
            v-model="state[field.name]"
          />

          <NctCrudNameList
            v-else-if="field.name.endsWith('_id') || field.name.endsWith('Id')"
            v-model="state[field.name]"
            :field-name="field.name"
            :table-name="field.references"
          />

          <template v-else-if="field.name === 'password'">
            <NctCommonPassword
              v-if="!props.initialState"
              v-model="state[field.name]"
              type="password"
            />
            <span
              v-else
              class="text-gray-500 italic text-sm"
            >
              Password can only be set on creation.
            </span>
          </template>
          <UInput
            v-else-if="field.type === 'date'"
            v-model="state[field.name]"
            type="datetime-local"
          />

          <USelect
            v-else-if="field.type === 'enum'"
            v-model="state[field.name]"
            :items="field.selectOptions"
            placeholder="Select "
            class="w-full"
            :disabled="field.name === 'status' && !canUpdateStatus"
          />

          <UTextarea
            v-else-if="field.type === 'textarea'"
            v-model="state[field.name]"
            :required="field.required"
            autoresize
          />

          <UInput
            v-else
            v-model="state[field.name]"
            :type="field.type"
            :required="field.required"
            :disabled="field.name === 'status' && !canUpdateStatus"
          />
        </UFormField>
      </template>

      <UButton
        type="submit"
        :loading="loading"
      >
        Submit
      </UButton>
    </UForm>
  </div>
</template>
