<template>
  <n-modal
    :autoFocus="false"
    :closeOnEsc="false"
    :mask-closable="false"
    :show="props.visible"
    :to="app"
  >
    <n-card
      style="width: 975px; margin-top: 30px; margin-bottom: 30px"
      :bordered="false"
      size="large"
      role="dialog"
      aria-modal="true"
    >
      <template #header>
        <div class="flex items-center justify-center">
          <div class="modal-title">设置展示列</div>
          <div class="close-box">
            <n-button
              @click="() => handleChose(false)"
              text
              style="font-size: 24px"
            >
              <n-icon>
                <close-icon />
              </n-icon>
            </n-button>
          </div>
        </div>
        <n-divider style="margin-top: 19px" />
      </template>
      <div class="text-[#999999] text-[14px] mb-[5px]">
        可拖动表格调整序号顺序，列表中字段将根据序号进行排序
      </div>
      <div
        ref="tableRef"
        class="w-full s-table"
        style="margin-bottom: 20px; min-height: 420px"
      >
        <x-n-data-table
          :remote="true"
          :loading="state.loading"
          :bordered="false"
          :columns="columns"
          :data="state.tableData"
          :scroll-x="tableScrollX"
          :max-height="600"
          :pagination="false"
          :row-key="(row) => row.columnId"
        >
          <template #index="{ row, index }">
            <div class="Drag">{{ index + 1 }}</div>
          </template>
          <template #columnName="{ row, index }">
            <div class="Drag">{{ row.columnName }}</div>
          </template>
          <template #wide="{ row, index }">
            <div class="flex w-full justify-center">
              <n-input-number
                v-model:value="row.wide"
                style="width: 100%"
                :show-button="false"
                :min="50"
                :max="500"
                :precision="0"
                @update:value="(value) => handleNumChange(value, index)"
                clearable
              />
            </div>
          </template>
          <template #showOrNot="{ row }">
            <div class="Drag">
              <n-switch v-model:value="row.showOrNot" />
            </div>
          </template>
          <template #operate="{ row, index }">
            <div class="Drag">
              <n-button
                @click="() => handleUp(index)"
                :disabled="index === 0"
                text
                type="info"
              >
                <template #icon>
                  <n-icon>
                    <ArrowUp28Filled />
                  </n-icon>
                </template>
              </n-button>
              <n-button
                @click="() => handleDown(index)"
                :disabled="index === state.tableData.length - 1"
                text
                type="info"
              >
                <template #icon>
                  <n-icon>
                    <ArrowDown28Filled />
                  </n-icon>
                </template>
              </n-button>
            </div>
          </template>
        </x-n-data-table>
      </div>
      <template #footer>
        <div class="flex items-center justify-center">
          <n-button
            size="large"
            @click="() => handleChose(false)"
            class="footer-btn"
            style="margin-right: 35px"
          >
            取消
          </n-button>
          <n-button
            @click="handleValidateClick"
            :loading="
              state.confirmLoading ||
              state.trainContentUploading ||
              state.trainFilesUploading
            "
            class="footer-btn"
            v-if="props.openModal !== 'detail'"
            size="large"
            type="primary"
          >
            确定
          </n-button>
        </div>
      </template>
    </n-card>
  </n-modal>
</template>
<script setup>
import {
  ref,
  reactive,
  onBeforeMount,
  onMounted,
  computed,
  defineProps,
  defineEmits,
  h,
  watchEffect,
  nextTick,
  getCurrentInstance,
} from "vue";
import { NButton, useMessage } from "naive-ui";
import { Close as CloseIcon } from "@vicons/ionicons5";
import { ArrowDown28Filled, ArrowUp28Filled } from "@vicons/fluent";
import Sortable from "sortablejs";
import dayjs from "dayjs";
import { cloneDeep } from "lodash-es";
import { NCheckbox } from "naive-ui";

const tableRef = ref();
const sortable = ref();
const instance = getCurrentInstance();
const app = document.getElementById("app");
const message = useMessage();
const props = defineProps({
  visible: {
    type: Boolean,
    default: false,
    required: true,
  },
  allColumns: {
    type: Array,
    default: [],
    required: true,
  },
  saveFn: {
    type: Function,
    default: () => {},
    required: true,
  },
});

const emits = defineEmits(["update:visible", "onCloseCB"]);

const state = reactive({
  loading: false,
  confirmLoading: false,
  tableData: [],
  //表格参数
  tableConfig: {
    rowKey: (row) => row.id,
  },
});

const tableScrollX = computed(() => {
  let scrollx = 0;
  columns.value.forEach((v) => {
    if (v.width) {
      scrollx += v.width;
    }
  });
  return scrollx;
});

const columns = ref([
  {
    title: "序号",
    key: "index",
    width: 80,
  },
  {
    title: "字段名称",
    key: "columnName",
    width: 150,
  },
  {
    title: "宽度",
    key: "wide",
    width: 120,
  },
  {
    key: "showOrNot",
    width: 150,
    title() {
      return h(
        NCheckbox,
        {
          checked: state.tableData.every((row) => row.showOrNot),
          onUpdateChecked: handleAllCheck,
        },
        {
          default: () => h("span", { style: "color:#fff;" }, "是否展示"),
        }
      );
    },
  },
  {
    title: "顺序",
    key: "operate",
    width: 150,
  },
]);

// 表单验证form
const noSideSpace = (value) => !value.startsWith(" ") && !value.endsWith(" ");

const handleChose = (flag) => {
  if (flag) {
    emits("onCloseCB", true);
  } else {
    emits("onCloseCB", false);
  }
};

const handleNumChange = (value, index) => {
  if (!value) {
    state.tableData[index].wide = 50;
  }
};

const handleValidateClick = async () => {
  state.loading = true;
  const res = await props.saveFn(state.tableData);
  state.loading = false;
  if (res.status === 0) {
    message.success("保存成功");
    handleChose(true);
  } else {
    message.error(res.msg);
  }
};

const handleAllCheck = (checked) => {
  state.tableData.forEach((v) => {
    v.showOrNot = checked;
  });
};

const setSort = () => {
  if (!tableRef.value) {
    return false;
  }
  const el = tableRef.value?.querySelectorAll(".n-data-table-tbody ")[0];

  sortable.value = Sortable.create(el, {
    handle: ".Drag",
    onEnd: (evt) => {
      const listT = cloneDeep(state.tableData);
      const currRow = listT.splice(evt.oldIndex, 1)[0];
      listT.splice(evt.newIndex, 0, currRow);
      state.tableData = listT;
      console.log(state.tableData);

      instance.proxy.$forceUpdate();
    },
  });
};

const handleUp = (index) => {
  let objT = state.tableData[index - 1];
  state.tableData[index - 1] = state.tableData[index];
  state.tableData[index] = objT;
};

const handleDown = (index) => {
  let objT = state.tableData[index + 1];
  state.tableData[index + 1] = state.tableData[index];
  state.tableData[index] = objT;
};

watch(
  () => tableRef.value,
  (newValue, oldValue) => {
    if (newValue) {
      setSort();
    }
  }
);

watch(
  () => props.visible,
  (newValue, oldValue) => {
    if (newValue) {
      state.tableData = cloneDeep(props.allColumns);
      state.newTableData = cloneDeep(props.allColumns);
    }
  }
);

onBeforeMount(() => {});
onMounted(() => {});
</script>
<style lang="scss" scoped>
.modal-title {
  // color: #7650fe;
  font-size: 16px;
  font-weight: bold;
}
.close-box {
  width: 30px;
  height: 20px;
  position: absolute;
  right: 40px;
  top: 27px;
}
.footer-btn {
  width: 140px;
}
.theme-tips {
  margin-left: 10px;
  color: #999999;
  font-size: 14px;
}

:deep(.n-divider) {
  margin-top: 0;
  margin-bottom: 0;
}
:deep(.n-form-item-feedback-wrapper) {
  min-height: 12px;
}
:deep(.sortable-ghost) {
  opacity: 0.8;
  color: #fff !important;
  background: #42b983 !important;
}
</style>
