<template>
  <div class="m-fields-key-value">
    <div v-if="!showCode">
      <div class="m-fields-key-value-item" v-for="(item, index) in records" :key="index">
        <TMagicInput
          placeholder="key"
          v-model="records[index][0]"
          :disabled="disabled"
          :size="size"
          @change="keyChangeHandler"
        ></TMagicInput>
        <span class="m-fields-key-value-delimiter">:</span>
        <TMagicInput
          placeholder="value"
          v-model="records[index][1]"
          :disabled="disabled"
          :size="size"
          @change="valueChangeHandler"
        ></TMagicInput>

        <TMagicButton
          v-if="!isCompare"
          class="m-fields-key-value-delete"
          type="danger"
          :size="size"
          :disabled="disabled"
          circle
          plain
          :icon="Delete"
          @click="deleteHandler(index)"
        ></TMagicButton>
      </div>

      <TMagicButton
        v-if="!isCompare"
        type="primary"
        :size="size"
        :disabled="disabled"
        plain
        :icon="Plus"
        @click="addHandler"
        >添加</TMagicButton
      >
    </div>

    <MagicCodeEditor
      v-if="config.advanced && showCode"
      editor-custom-type="m-fields-key-value"
      language="javascript"
      :init-values="model[name]"
      :options="{
        readOnly: disabled,
      }"
      :autosize="{
        minRows: 1,
        maxRows: 20,
      }"
      :parse="true"
      @save="save"
    ></MagicCodeEditor>

    <TMagicButton
      v-if="config.advanced && !isCompare"
      size="default"
      :disabled="disabled"
      link
      :icon="CodeIcon"
      @click="showCode = !showCode"
    ></TMagicButton>
  </div>
</template>

<script setup lang="ts">
import { computed, inject, ref, watchEffect } from 'vue';
import { Delete, Plus } from '@element-plus/icons-vue';

import { TMagicButton, TMagicInput } from '@tmagic/design';
import type { FieldProps, FormState, KeyValueConfig } from '@tmagic/form';

import CodeIcon from '@editor/icons/CodeIcon.vue';
import MagicCodeEditor from '@editor/layouts/CodeEditor.vue';

defineOptions({
  name: 'MFieldsKeyValue',
});

const props = withDefaults(defineProps<FieldProps<KeyValueConfig>>(), {
  disabled: false,
});

const emit = defineEmits<{
  change: [value: Record<string, any>];
}>();

const mForm = inject<FormState | undefined>('mForm');

/** 对比模式下隐藏增删/代码切换等操作按钮，仅保留只读展示。 */
const isCompare = computed(() => Boolean(mForm?.isCompare));

const records = ref<[string, string][]>([]);
const showCode = ref(false);

watchEffect(() => {
  if (typeof props.model[props.name] === 'function') {
    showCode.value = true;
  } else {
    const initValues: [string, any][] = Object.entries(props.model[props.name] || {});

    for (const [, value] of initValues) {
      if (typeof value !== 'string') {
        showCode.value = true;
        break;
      }
    }
    records.value = initValues;
  }
});

const getValue = () => {
  const record: Record<string, string> = {};
  records.value.forEach(([key, value]) => {
    if (key) {
      record[key] = value;
    }
  });
  return record;
};

const keyChangeHandler = () => {
  emit('change', getValue());
};

const valueChangeHandler = () => {
  emit('change', getValue());
};

const addHandler = () => {
  records.value.push(['', '']);
};

const deleteHandler = (index: number) => {
  records.value.splice(index, 1);
  emit('change', getValue());
};

const save = (v: string | any) => {
  emit('change', v);
};
</script>
