<template>
  <div>
    <van-form
      @submit="onSubmit"
      :disabled="formOption.disabled"
      :readonly="formOption.readonly"
      :label-width="formOption.labelWidth"
      :label-align="formOption.labelAlign || 'top'"
      :scroll-to-error="formOption.scroll"
      ref="testForm"
    >
      <van-cell-group inset>
        <div v-for="(i, index) in formConfig" :key="index">
          <van-field
            v-if="i.type == 'input'"
            v-model="formData[i.prop]"
            :label="i.label"
            :name="i.prop"
            :type="i.itemType ? i.itemType : 'text'"
            :placeholder="i.placeholder ? i.placeholder : '请输入'"
            :clearable="i.clearable ? i.clearable : false"
            :rules="getRules(i.prop)"
          >
          </van-field>
          <van-field v-if="i.type == 'switch'" :label="i.label" :name="i.prop">
            <template #input>
              <van-switch v-model="formData[i.prop]" />
            </template>
          </van-field>
          <!-- 多选checkbox -->
          <van-field
            v-if="i.type == 'checkbox'"
            :label="i.label"
            :name="i.prop"
            :rules="getRules(i.prop)"
          >
            <template #input>
              <van-checkbox-group
                v-model="formData[i.prop]"
                direction="horizontal"
              >
                <van-checkbox
                  shape="square"
                  v-for="j in i.data"
                  :key="j.value"
                  :name="j.value"
                  >{{ j.text }}</van-checkbox
                >
              </van-checkbox-group>
            </template>
          </van-field>
          <!-- 单选radio -->
          <van-field
            v-if="i.type == 'radio'"
            :label="i.label"
            :name="i.prop"
            :rules="getRules(i.prop)"
          >
            <template #input>
              <van-radio-group
                v-model="formData[i.prop]"
                direction="horizontal"
              >
                <van-radio
                  v-for="j in i.data"
                  :key="j.value"
                  :name="j.value || j.id"
                  >{{ j.label || j.title }}</van-radio
                >
              </van-radio-group>
            </template>
          </van-field>
          <!-- 单选 -->
          <van-field
            v-if="i.type == 'picker' && i.itemType == 'onePicker'"
            :label="i.label"
            :name="i.prop"
            v-model="formData[i.prop + 'Name']"
            is-link
            readonly
            @click="i.showPicker = true"
            :rules="getRules(i.prop)"
          >
          </van-field>
          <van-popup
            v-model:show="i.showPicker"
            round
            position="bottom"
            v-if="i.type == 'picker' && i.itemType == 'onePicker'"
          >
            <van-picker
              :columns="i.pickerOption.columns"
              @cancel="i.showPicker = false"
              @confirm="(option) => onConfirmPicker(option, i, index)"
            />
          </van-popup>
          <!-- 时间选择器 -->
          <van-field
            v-if="i.type == 'picker' && i.itemType == 'datePicker'"
            :label="i.label"
            :name="i.prop"
            v-model="formData[i.prop]"
            is-link
            readonly
            @click="i.showPicker = true"
            :rules="getRules(i.prop)"
          >
          </van-field>
          <van-popup
            v-model:show="i.showPicker"
            round
            position="bottom"
            v-if="i.type == 'picker' && i.itemType == 'datePicker'"
          >
            <van-date-picker
              @confirm="(option) => onConfirmPicker(option, i, index)"
              @cancel="i.showPicker = false"
              :min-date="i.minDate"
              :max-date="i.maxDate"
              :columns-type="i.columnsType"
            />
          </van-popup>
          <!-- 级联 城市 -->
          <van-field
            v-if="i.type == 'cascader' && i.itemType == 'city'"
            :label="i.label"
            :name="i.prop"
            v-model="formData[i.prop + 'Name']"
            is-link
            readonly
            @click="i.showPicker = true"
            :rules="getRules(i.prop)"
          />
          <van-popup
            v-if="i.type == 'cascader' && i.itemType == 'city'"
            v-model:show="i.showPicker"
            round
            position="bottom"
          >
            <van-cascader
              v-model="formData[i.prop]"
              :title="i.title ? i.title : '请选择'"
              :options="cityOption"
              @close="i.showPicker = false"
              @change="(option) => cityOnChange(option, i, index)"
              @finish="(option) => (i.finishFn ? i.finishFn(option) : () => {})"
            />
          </van-popup>

          <!-- 级联 公共 -->
          <van-field
            v-if="i.type == 'cascader' && i.itemType == 'common'"
            :label="i.label"
            :name="i.prop"
            v-model="formData[i.prop + 'Name']"
            is-link
            readonly
            @click="i.showPicker = true"
            :rules="getRules(i.prop)"
          />
          <van-popup
            v-if="i.type == 'cascader' && i.itemType == 'common'"
            v-model:show="i.showPicker"
            round
            position="bottom"
          >
            <van-cascader
              v-model="formData[i.prop]"
              :title="i.title ? i.title : '请选择'"
              :options="i.options"
              :field-names="i.fieldNames ? i.fieldNames : fieldNames"
              @close="i.showPicker = false"
              @change="(option) => commonOnChange(option, i, index)"
              @finish="
                (option) => (i.finishFn ? i.finishFn(i, option) : () => {})
              "
            />
            <!-- @change="
                (option) => (i.onChangeFn ? i.onChangeFn(i, option) : () => {})
              "
              @finish="
                (option) => (i.finishFn ? i.finishFn(i, option) : () => {})
              " -->
          </van-popup>

          <!-- 插槽 -->
          <van-field v-if="i.type == 'slot'" :label="i.label">
            <template #input>
              <div>
                <slot :name="i.slotName"> {{ i.slotName }}插槽占位符 </slot>
              </div>
            </template>
          </van-field>
        </div>
      </van-cell-group>
      <!-- 循环业务数据 -->
      <van-cell-group
        inset
        v-for="(item, index) in formData[btnConfigCopy.prop]"
        :key="index"
        style="margin-top: 10px !important"
      >
        <div>
          明细{{ index + 1 }} <span @click="handleRemove(index)">删除</span>
        </div>
        <!-- 循环表单数据 -->
        <div v-for="(i, sonIndex) in btnConfigCopy.listConfig" :key="i.prop">
          <van-field
            v-if="i.type == 'input'"
            v-model="formData[btnConfigCopy.prop][index][i.prop]"
            :label="i.label"
            :name="i.prop"
            :type="i.itemType ? i.itemType : 'text'"
            :placeholder="i.placeholder ? i.placeholder : '请输入'"
            :clearable="i.clearable ? i.clearable : false"
            :rules="getRules(i.prop)"
          >
          </van-field>
          <!-- 单选 -->
          <van-field
            v-if="i.type == 'picker' && i.itemType == 'onePicker'"
            :label="i.label"
            :name="i.prop"
            v-model="formData[btnConfigCopy.prop][index][i.prop + 'Name']"
            is-link
            readonly
            @click="handleListItemClick(i, index, sonIndex)"
            :rules="getRules(i.prop)"
          >
          </van-field>
          <!-- 时间选择器 -->
          <van-field
            v-if="i.type == 'picker' && i.itemType == 'datePicker'"
            :label="i.label"
            :name="i.prop"
            v-model="formData[btnConfigCopy.prop][index][i.prop]"
            is-link
            readonly
            @click="handleListItemClick(i, index, sonIndex)"
            :rules="getRules(i.prop)"
          >
          </van-field>
        </div>
      </van-cell-group>
      <!-- 单独写个循环，保证弹窗唯一 -->
      <div v-for="(item, index) in btnConfigCopy.listConfig" :key="index">
        <van-popup
          v-model:show="item.showPicker"
          round
          position="bottom"
          v-if="item.type == 'picker' && item.itemType == 'onePicker'"
        >
          <van-picker
            :columns="item.pickerOption.columns"
            @cancel="item.showPicker = false"
            @confirm="(option) => onConfirmListPicker(option, item)"
          />
        </van-popup>
        <van-popup
          v-model:show="item.showPicker"
          round
          position="bottom"
          v-if="item.type == 'picker' && item.itemType == 'datePicker'"
        >
          <van-date-picker
            @confirm="(option) => onConfirmListPicker(option, item)"
            @cancel="item.showPicker = false"
            :min-date="item.minDate"
            :max-date="item.maxDate"
            :columns-type="item.columnsType"
          />
        </van-popup>
      </div>

      <!-- 按钮 -->
      <div class="btn-box">
        <van-button
          :plain="btnConfigCopy.plain ? btnConfigCopy.plain : false"
          :type="btnConfigCopy.itemType ? btnConfigCopy.itemType : 'primary'"
          :size="btnConfigCopy.size ? btnConfigCopy.size : 'small'"
          style="width: 100%; border: none"
          @click="handlePush()"
        >
          <template #icon>
            <van-icon
              :name="btnConfigCopy.icon ? btnConfigCopy.icon : 'plus'"
              :size="12"
            />
          </template>
          {{
            btnConfigCopy.btnName ? btnConfigCopy.btnName : "添加"
          }}</van-button
        >
      </div>
      <div style="margin: 16px">
        <van-button round block type="primary" native-type="submit">
          提交
        </van-button>
      </div>
    </van-form>
  </div>
</template>

<script setup>
import { showLoadingToast, closeToast, showNotify } from "vant";
import {
  ref,
  getCurrentInstance,
  onMounted,
  reactive,
  computed,
  toRefs,
  watch,
} from "vue";

const props = defineProps({
  modelValue: {
    type: Object,
    default: false,
  },
  formConfig: {
    type: Array,
    default: false,
  },
  formOption: {
    type: Object,
    default: false,
  },
  rules: {
    type: Object,
    default: false,
  },
});
const proxy = getCurrentInstance().proxy;
const { formConfig, formOption, rules } = toRefs(props);
const formData = computed(() => {
  return proxy.modelValue;
});
//
const fieldNames = { text: "label", value: "id" };
const emit = defineEmits(["update:modelValue"]);

const onSubmit = () => {
  emit("onSubmit");
};

// 获取验证规则
const getRules = (prop) => {
  if (rules.value.hasOwnProperty(prop) && rules.value[prop]) {
    return rules.value[prop];
  }
};
const getReadonly = (i) => {
  return i.readonly ? i.readonly : i.name == "picker" ? true : false;
};

// 国家初始化
const cityOption = ref([]);
const cityOptionInit = () => {
  proxy.post("/areaInfo/list", formData.value).then((res) => {
    cityOption.value = res.data.map((item, index) => {
      return {
        ...item,
        index: index,
        text: item.chineseName,
        value: item.id,
        children: [],
      };
    });
  });
};

let btnConfigCopy = {};
const btnPickerList = ref([]);
const formDataInit = () => {
  var map = {
    input: "",
    radio: "",
    switch: false,
    checkbox: [],
    date: "",
    picker: "",
    cascader: "",
  };
  // 判断是否需要按钮
  if (formOption.value.btnConfig && formOption.value.btnConfig.isNeed) {
    formData.value[formOption.value.btnConfig.prop] = [];
    btnConfigCopy = { ...formOption.value.btnConfig };
    if (
      formOption.value.btnConfig.listConfig &&
      formOption.value.btnConfig.listConfig.length > 0
    ) {
      btnPickerList.value = formOption.value.btnConfig.listConfig
        .filter((x) => x.type === "picker")
        .map((x) => x.itemType);
    }
  }
  for (let i = 0; i < formConfig.value.length; i++) {
    const element = formConfig.value[i];
    if (element.type === "slot") {
      continue;
    }
    if (element.type === "cascader" && element.itemType === "city") {
      cityOptionInit();
    }
    if (element.type === "picker" || element.type === "cascader") {
      formData.value[element.prop] = map[element.type];
      formData.value[element.prop + "Name"] = map[element.type];
    }
    if (map[element.type] != undefined) {
      formData.value[element.prop] = map[element.type];
    }
  }
  emit("update:modelValue", formData.value);
  console.log(formData.value, "aws");
};

formDataInit();
// 选择框  确定事件
const onConfirmPicker = (option, item, index) => {
  switch (item.itemType) {
    case "onePicker": {
      formData.value[item.prop + "Name"] = option.selectedOptions[0].text;
      formData.value[item.prop] = option.selectedOptions[0].value;
      formConfig.value[index].showPicker = false;
    }
    case "datePicker": {
      formData.value[item.prop] = option.selectedValues.join(
        item.split ? item.split : "-"
      );
      formConfig.value[index].showPicker = false;
    }
  }
};
const currentIndex = ref(-1);
const currentSonIndex = ref(-1);
const handleListItemClick = (i, index, sonIndex) => {
  currentIndex.value = index;
  currentSonIndex.value = sonIndex;
  btnConfigCopy.listConfig[sonIndex].showPicker = true;
};
const onConfirmListPicker = (option, item) => {
  switch (item.itemType) {
    case "onePicker": {
      formData.value[btnConfigCopy.prop][currentIndex.value][
        item.prop + "Name"
      ] = option.selectedOptions[0].text;
      formData.value[btnConfigCopy.prop][currentIndex.value][item.prop] =
        option.selectedOptions[0].value;
      btnConfigCopy.listConfig[currentSonIndex.value].showPicker = false;
    }
    case "datePicker": {
      formData.value[btnConfigCopy.prop][currentIndex.value][item.prop] =
        option.selectedValues.join(item.split ? item.split : "-");
      btnConfigCopy.listConfig[currentSonIndex.value].showPicker = false;
    }
  }
};

// push事件
const handlePush = () => {
  if (btnConfigCopy.clickFn && typeof btnConfigCopy.clickFn == "function") {
    btnConfigCopy.clickFn();
  }
};
// remove
const handleRemove = (index) => {
  formData.value[btnConfigCopy.prop].splice(index, 1);
};
// 拉去城市最近数据及处理
const getAreaInfo = (selectedOptions, item, index) => {
  showLoadingToast("加载中...");
  proxy
    .post("/areaInfo/list", { parentId: selectedOptions.value })
    .then((res) => {
      let countryIndex = selectedOptions.selectedOptions[0].index;
      let provinceIndex =
        selectedOptions.tabIndex === 1
          ? selectedOptions.selectedOptions[1].index
          : null;
      let cityIndex =
        selectedOptions.tabIndex === 2
          ? selectedOptions.selectedOptions[2].index
          : null;
      //已经没有下级数据
      if (res.data.length === 0) {
        if (selectedOptions.tabIndex === 1) {
          formData.value[item.prop + "Name"] = selectedOptions.selectedOptions
            .map((item) => item.text)
            .join(" ");
          formConfig.value[index].showPicker = false;
          formData.value.selectedOptions = selectedOptions;
          return;
        }
      }
      if (selectedOptions.tabIndex === 2) {
        formData.value[item.prop + "Name"] = selectedOptions.selectedOptions
          .map((item) => item.text)
          .join(" ");
        formConfig.value[index].showPicker = false;
        formData.value.selectedOptions = selectedOptions;
        return;
      }
      if (selectedOptions.tabIndex === 0) {
        cityOption.value[countryIndex].children = res.data.map(
          (item, index) => {
            return {
              ...item,
              index: index,
              text: item.name,
              value: item.id,
            };
          }
        );
      } else if (selectedOptions.tabIndex === 1) {
        cityOption.value[countryIndex].children[provinceIndex].children =
          res.data.map((item, index) => {
            return {
              ...item,
              index: index,
              text: item.name,
              value: item.id,
            };
          });
      } else if (selectedOptions.tabIndex === 2) {
        cityOption.value[countryIndex].children[provinceIndex].children[
          cityIndex
        ].children = res.data.map((item, index) => {
          return {
            ...item,
            index: index,
            text: item.name,
            value: item.id,
          };
        });
      }
      closeToast();
    });
};
// 城市变动事件
const cityOnChange = (selectedOptions, item, index) => {
  getAreaInfo(selectedOptions, item, index);
};

const commonOnChange = ({ selectedOptions }, item, index) => {
  formData.value[item.prop + "Name"] =
    selectedOptions[selectedOptions.length - 1].label;
};
const testForm = ref(null); // 延迟使用，因为还没有返回跟挂载
watch(
  formData.value,
  (val) => {
    emit("update:modelValue", val);
  },
  {
    deep: true,
  }
);
</script>

<style lang="scss" scoped>
.btn-box {
  margin-top: 10px;
  width: 100%;
  text-align: center;
}
</style>