<template>
  <form-item-wrapper
    :designer="designer"
    :field="field"
    :rules="rules"
    :design-state="designState"
    :parent-widget="parentWidget"
    :parent-list="parentList"
    :index-of-parent-list="indexOfParentList"
    :sub-form-row-index="subFormRowIndex"
    :sub-form-col-index="subFormColIndex"
    :sub-form-row-id="subFormRowId"
  >
    <el-input
      v-if="designState"
      class="full-width-input design-area-preview"
      :style="widgetStyle"
      readonly
      disabled
      :size="field.options.size || 'small'"
      :placeholder="getI18nLabel(field.options.placeholder || '请选择地区')"
    />
    <baseArea
      v-else
      ref="baseAreaRef"
      v-show="!isReadMode"
      class="full-width-input"
      :style="widgetStyle"
      :value="fieldModel"
      :label-value="areaNameLabel"
      @update:labelValue="handleAreaLabelUpdate"
      :max-level="maxLevel"
      :locale="field.options.locale"
      :disabled="field.options.disabled"
      :readonly="field.options.readonly"
      :clearable="field.options.clearable"
      :placeholder="getI18nLabel(field.options.placeholder || '请选择地区')"
      :size="field.options.size || 'small'"
      @input="handleAreaInput"
      @change="handleAreaChange"
      @popover-open="handleAreaPopoverOpen"
    />
    <template v-if="isReadMode">
      <span class="readonly-mode-field">{{ readModeText }}</span>
    </template>
  </form-item-wrapper>
</template>

<script>
import FormItemWrapper from "./form-item-wrapper";
import emitter from "../../../../../components/xform/utils/emitter";
import i18n from "../../../../../components/xform/utils/i18n";
import fieldMixin from "../../../../../components/xform/form-designer/form-widget/field-widget/fieldMixin";
import baseArea from "@base/components/baseArea/index.vue";
import { deepClone } from "../../../../../components/xform/utils/util";

export default {
  name: "area-select-widget",
  componentName: "FieldWidget",
  mixins: [emitter, fieldMixin, i18n],
  components: {
    FormItemWrapper,
    baseArea,
  },
  props: {
    field: Object,
    parentWidget: Object,
    parentList: Array,
    indexOfParentList: Number,
    designer: Object,
    designState: {
      type: Boolean,
      default: false,
    },
    subFormRowIndex: {
      type: Number,
      default: -1,
    },
    subFormColIndex: {
      type: Number,
      default: -1,
    },
    subFormRowId: {
      type: String,
      default: "",
    },
  },
  inject: ["refList", "globalOptionData", "globalModel"],
  data() {
    return {
      oldFieldValue: null,
      fieldModel: null,
      areaLabel: null,
      rules: [],
    };
  },
  computed: {
    currentData() {
      let tableParam = this.tableParam;
      return tableParam && tableParam.row ? tableParam.row : this.formModel;
    },
    areaNameField() {
      return this.field.options.areaName || null;
    },
    maxLevel() {
      const areaDataType = this.field.options.areaDataType;
      const type =
        areaDataType == null || areaDataType === "" ? 3 : areaDataType * 1;
      if (type >= 0 && type <= 3) {
        return type + 1;
      }
      return 4;
    },
    readModeText() {
      return this.areaNameLabel || "--";
    },
    widgetStyle() {
      const widgetWidth = this.field.options.widgetWidth;
      if (widgetWidth != null && widgetWidth !== "") {
        return { width: widgetWidth };
      }
      return { width: "100%" };
    },
    currentAreaNameValue() {
      if (!this.areaNameField) {
        return null;
      }
      return this.currentData[this.areaNameField] ?? null;
    },
    areaNameLabel() {
      const formLabel = this.currentAreaNameValue;
      if (formLabel != null && formLabel !== "") {
        return formLabel;
      }
      return this.areaLabel;
    },
  },
  created() {
    this.initFieldModel();
    this.registerToRefList();
    this.initEventHandler();
    this.buildFieldRules();
    this.handleOnCreated();
  },
  mounted() {
    this.handleOnMounted();
  },
  beforeDestroy() {
    this.unregisterFromRefList();
  },
  methods: {
    handleAreaLabelUpdate(label) {
      if (this.designState) {
        return;
      }
      this.areaLabel = label;
      this.syncAreaName(label);
    },
    syncAreaName(label) {
      if (this.areaNameField) {
        this.$set(this.currentData, this.areaNameField, label);
      }
    },
    syncAreaLabelFromForm() {
      if (this.areaNameField) {
        this.areaLabel = this.currentData[this.areaNameField] ?? null;
      }
    },
    commitAreaValue(value, label) {
      this.fieldModel = value;
      this.$set(this.currentData, this.fieldKeyName, value);
      this.syncUpdateFormModel(value);
      if (label !== undefined) {
        this.areaLabel = label;
        this.syncAreaName(label);
      }
    },
    handleAreaInput(val) {
      if (this.designState) {
        return;
      }
      this.commitAreaValue(val);
    },
    handleAreaPopoverOpen() {
      if (this.designState) {
        return;
      }
      this.oldFieldValue = deepClone(this.fieldModel);
    },
    handleAreaChange(payload) {
      if (this.designState) {
        return;
      }
      const value =
        payload && Object.prototype.hasOwnProperty.call(payload, "value")
          ? payload.value
          : this.fieldModel;
      this.handleChangeEvent(value);
    },
    createEmptyAreaPathResult(value) {
      return {
        value: value != null && value !== "" ? value : null,
        label: null,
        path: [],
        province: null,
        city: null,
        district: null,
        town: null,
      };
    },
    async getAreaPath(value) {
      if (this.designState) {
        return this.createEmptyAreaPathResult(value);
      }
      const areaRef = this.$refs.baseAreaRef;
      if (areaRef && areaRef.getAreaPath) {
        const targetValue =
          value !== undefined && value !== null ? value : this.getValue();
        return areaRef.getAreaPath(targetValue);
      }
      return this.createEmptyAreaPathResult(value);
    },
    getValue() {
      const fieldKey = this.fieldKeyName;
      if (this.fieldModel != null && this.fieldModel !== "") {
        return this.fieldModel;
      }
      const formVal = this.currentData[fieldKey];
      if (formVal != null && formVal !== "") {
        return formVal;
      }
      return this.fieldModel;
    },
    setValue(val) {
      if (!this.field.formItemFlag) {
        return;
      }
      const oldVal = deepClone(this.fieldModel);
      const value = val ?? null;
      this.commitAreaValue(value);
      this.syncAreaLabelFromForm();
      this.emitFieldDataChange(value, oldVal);
    },
    fieldModelLabel() {
      return this.areaNameLabel || this.getValue() || "";
    },
  },
};

</script>

<style lang="scss" scoped>
@import "~@/styles/global.scss";

.full-width-input {
  width: 100% !important;
  display: block !important;
  box-sizing: border-box;
}
</style>
