<script setup lang="ts">
import draggable from 'vuedraggable';
import { CloseOutlined, HolderOutlined } from '@ant-design/icons-vue';
import { analysisRegisterFields, Field_Card, Field_Phone } from '../tool';

interface Option {
  id: string;
  name: string;
  required?: boolean;
}
const props = defineProps<{ id: string }>();
const requestData = defineModel<string[]>('requestData', { default: [] });

let getConfigItemLabel = (id: string) => id;

const options = ref<Option[]>([]);
const selected = ref<Option[]>([]);

watchEffect(() => reset());

const append = (option: Option, index: number) => {
  options.value.splice(index, 1);
  if (option.required) selected.value.unshift(option);
  else selected.value.push(option);
};

const remove = (option: Option, index: number) => {
  selected.value.splice(index, 1);
  if (option.required) options.value.unshift(option);
  else options.value.push(option);
};

const error = ref('');
watch(
  [selected, options],
  () => {
    error.value = '';
  },
  { deep: true }
);
function save() {
  error.value = '';
  const fieldCard = selected.value.find((option) => option.id === Field_Card);
  const fieldPhone = selected.value.find((option) => option.id === Field_Phone);

  if (fieldCard && !fieldCard.required && fieldPhone && !fieldPhone.required) {
    error.value = `字段 [${getConfigItemLabel(Field_Card)}] [${getConfigItemLabel(Field_Phone)}] 至少需要一个是必填的`;
  } else if (fieldCard && !fieldCard.required && !fieldPhone) {
    fieldCard.required = true;
    nextTick(() => {
      error.value = `字段 [${getConfigItemLabel(Field_Card)}] 需要是必填的 (请重试)`;
    });
  } else if (fieldPhone && !fieldPhone.required && !fieldCard) {
    fieldPhone.required = true;
    nextTick(() => {
      error.value = `字段 [${getConfigItemLabel(Field_Phone)}] 需要是必填的 (请重试)`;
    });
  } else if (!fieldCard && !fieldPhone) {
    error.value = `至少需要 [${getConfigItemLabel(Field_Card)}] 或 [${getConfigItemLabel(Field_Card)}] 字段，且有一个需要是必填的`;
  } else {
    requestData.value = selected.value.map((option) => [option.id, option.required ? 'required' : ''].filter(Boolean).join(':'));
  }
}

function reset() {
  const values = analysisRegisterFields(requestData.value);
  selected.value = values.selected;
  options.value = values.options;
  getConfigItemLabel = (id: string) => values.config.find((item) => item[0] === id)?.[1] ?? id;
}
</script>

<template>
  <div>
    <draggable class="draggable-list selected" :class="{ empty: selected.length === 0 }" :list="selected" group="fields" item-key="id">
      <template #item="{ element, index }">
        <div class="draggable-list-item has-icon">
          <div>
            <HolderOutlined class="icon left" />
            <span>{{ element.name }}</span>
          </div>
          <div>
            <a-switch v-model:checked="element.required" checked-children="必填" un-checked-children="可选" />
            <CloseOutlined class="icon right" style="cursor: pointer" @click.prevent="remove(element, index)" />
          </div>
        </div>
      </template>
      <template #header>
        <div class="draggable-list-header">配置字段</div>
      </template>
    </draggable>
    <draggable class="draggable-list options" :class="{ empty: options.length === 0 }" :list="options" group="fields" item-key="id">
      <template #header>
        <div class="draggable-list-header">备选字段</div>
      </template>
      <template #item="{ element, index }">
        <a-tag :color="element.required ? '#f50' : '#108ee9'" class="draggable-list-item" @click="append(element, index)">
          {{ element.name }}
        </a-tag>
      </template>
    </draggable>
    <div class="flex items-center" style="margin-top: 10px">
      <div class="flex-auto error">{{ error }}</div>
      <div class="flex-none">
        <vxe-button type="reset" content="重置" @click="reset()"></vxe-button>
        <vxe-button type="submit" status="primary" content="确定" @click="save()"></vxe-button>
      </div>
    </div>
  </div>
</template>

<style scoped lang="scss">
.draggable-list-header {
  padding: 8px 0;
  font-size: 16px;
}
.draggable-list.empty {
  border-radius: 8px;
  border: 1px #111 dashed;
  height: 100px;
  > .draggable-list-header {
    display: none;
  }

  &::after {
    content: var(--empty);
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100%;
    color: rgba(0, 0, 0, 0.45);
  }
}

.draggable-list.selected {
  --empty: '点击或拖拽下方标签至此区域以配置';

  .draggable-list-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 8px 16px;
    &.has-icon {
      padding-left: 8px;
      padding-right: 8px;
    }
    cursor: move;
    border-collapse: collapse;
    border: 1px solid rgba(0, 0, 0, 0.5);
    .icon {
      &.left {
        padding-right: 8px;
      }
      &.right {
        padding-left: 8px;
      }
    }
  }
}

.draggable-list.options {
  --empty: '拖拽至此区域以取消配置';
  .draggable-list-header {
    padding-bottom: 0;
  }
  &.empty {
    margin-top: 12px;
  }
  .draggable-list-item {
    margin-top: 8px;
    cursor: pointer;
  }
}

.error {
  font-size: 12px;
  color: #ff4d4f;
}
</style>
