<template>
  <div class="form-item-render">
    <!-- Input -->
    <a-input
      v-if="item.type === 'input'"
      v-model:value="modelValue"
      :placeholder="resolveInputPlaceholder()"
      v-bind="item.props"
      @update:value="handleChange"
    />

    <!-- Password -->
    <a-input-password
      v-else-if="item.type === 'password'"
      v-model:value="modelValue"
      :placeholder="resolveInputPlaceholder()"
      v-bind="item.props"
      @update:value="handleChange"
    />

    <!-- Textarea -->
    <a-textarea
      v-else-if="item.type === 'textarea'"
      v-model:value="modelValue"
      :placeholder="resolveInputPlaceholder()"
      :rows="4"
      v-bind="item.props"
      @update:value="handleChange"
    />

    <!-- Number -->
    <a-input-number
      v-else-if="item.type === 'number'"
      v-model:value="modelValue"
      :placeholder="resolveInputPlaceholder()"
      style="width: 100%"
      v-bind="item.props"
      @update:value="handleChange"
    />

    <!-- Select -->
    <a-select
      v-else-if="item.type === 'select'"
      v-model:value="modelValue"
      :placeholder="resolveSelectPlaceholder()"
      :options="resolvedOptions"
      v-bind="item.props"
      @update:value="handleChange"
    />

    <!-- Radio -->
    <a-radio-group
      v-else-if="item.type === 'radio'"
      v-model:value="modelValue"
      :options="resolvedOptions"
      v-bind="item.props"
      @update:value="handleChange"
    />

    <!-- Checkbox -->
    <a-checkbox-group
      v-else-if="item.type === 'checkbox'"
      v-model:value="modelValue"
      :options="resolvedOptions"
      v-bind="item.props"
      @update:value="handleChange"
    />

    <!-- Switch -->
    <a-switch
      v-else-if="item.type === 'switch'"
      v-model:checked="modelValue"
      v-bind="item.props"
      @update:checked="handleChange"
    />

    <!-- Date Picker -->
    <a-date-picker
      v-else-if="item.type === 'datePicker'"
      v-model:value="modelValue"
      :placeholder="resolveSelectPlaceholder()"
      style="width: 100%"
      v-bind="item.props"
      @update:value="handleChange"
    />

    <!-- Time Picker -->
    <a-time-picker
      v-else-if="item.type === 'timePicker'"
      v-model:value="modelValue"
      :placeholder="resolveSelectPlaceholder()"
      style="width: 100%"
      v-bind="item.props"
      @update:value="handleChange"
    />

    <!-- Date Range -->
    <a-range-picker
      v-else-if="item.type === 'dateRange'"
      v-model:value="modelValue"
      style="width: 100%"
      v-bind="item.props"
      @update:value="handleChange"
    />

    <!-- Upload -->
    <ProUpload
      v-else-if="item.type === 'upload'"
      :value="modelValue"
      mode="button"
      :button-text="item.placeholder"
      v-bind="item.props"
      @update:value="handleChange"
    />

    <!-- Image Upload -->
    <ProUpload
      v-else-if="item.type === 'imageUpload'"
      :value="modelValue"
      mode="image"
      :button-text="item.placeholder"
      v-bind="item.props"
      @update:value="handleChange"
    />

    <!-- Avatar Upload -->
    <ProUpload
      v-else-if="item.type === 'avatarUpload'"
      :value="modelValue"
      mode="avatar"
      v-bind="item.props"
      @update:value="handleChange"
    />

    <!-- Slider -->
    <a-slider
      v-else-if="item.type === 'slider'"
      v-model:value="modelValue"
      v-bind="item.props"
      @update:value="handleChange"
    />

    <!-- Rate -->
    <a-rate
      v-else-if="item.type === 'rate'"
      v-model:value="modelValue"
      v-bind="item.props"
      @update:value="handleChange"
    />

    <!-- Cascader -->
    <a-cascader
      v-else-if="item.type === 'cascader'"
      v-model:value="modelValue"
      :placeholder="resolveSelectPlaceholder()"
      :options="resolvedOptions"
      style="width: 100%"
      v-bind="item.props"
      @update:value="handleChange"
    />

    <!-- Tree Select -->
    <a-tree-select
      v-else-if="item.type === 'treeSelect'"
      v-model:value="modelValue"
      :placeholder="resolveSelectPlaceholder()"
      :tree-data="resolvedOptions"
      style="width: 100%"
      v-bind="item.props"
      @update:value="handleChange"
    />

    <!-- Custom -->
    <component
      v-else-if="item.type === 'custom' && item.render"
      :is="item.render"
      v-model:value="modelValue"
      @update:value="handleChange"
    />

    <!-- Default -->
    <a-input
      v-else
      v-model:value="modelValue"
      :placeholder="resolveInputPlaceholder()"
      v-bind="item.props"
      @update:value="handleChange"
    />
  </div>
</template>

<script setup lang="ts">
import type { ProFormItem } from "@/types/pro";

import { ref, watch, computed } from "vue";

import { $t } from "@/locales";

import ProUpload from "../ProUpload/index.vue";

interface Props {
  value?: unknown;
  item: ProFormItem;
  formData?: Record<string, unknown>;
}

const props = withDefaults(defineProps<Props>(), {
  formData: () => ({}),
});
const emit = defineEmits(["update:value", "change"]);

const modelValue = ref(props.value ?? props.item.initialValue);

const resolvedOptions = computed(() => {
  if (typeof props.item.options === "function") {
    return props.item.options(props.formData);
  }
  return props.item.options;
});

watch(
  () => props.value,
  (val) => {
    modelValue.value = val;
  },
);

watch(modelValue, (val) => {
  emit("update:value", val);
  emit("change", val);
});

const handleChange = (value: unknown) => {
  emit("update:value", value);
  emit("change", value);
};

const resolveLabel = () => {
  return String(props.item.label ?? "");
};

const resolveInputPlaceholder = () => {
  return (
    props.item.placeholder ||
    $t("proForm.enterPlaceholder", { label: resolveLabel() })
  );
};

const resolveSelectPlaceholder = () => {
  return (
    props.item.placeholder ||
    $t("proForm.selectPlaceholder", { label: resolveLabel() })
  );
};
</script>
