<script lang="ts" setup>
import {
  computed,
  defineOptions,
  h,
  nextTick,
  onUnmounted,
  reactive,
  ref,
  unref,
} from "vue";
import { NDataTable } from "naive-ui";
import type { DataTableColumns, DataTableRowKey } from "naive-ui";
import type { SortableEvent } from "sortablejs";
import Sortable from "sortablejs";
import { debounce } from "lodash-es";
import Action from "../Action.vue";
import { deleteCondition, getConditionList, sort } from "@/api/home/filter";
import type { FilterSearchParam } from "/#/api";

defineOptions({ name: "FilterModal" });

const emit = defineEmits<{
  (e: "showNewFilter"): void;
  (e: "editFilter", filter: any): void;
}>();

const show = ref(false);

const cardStyle = {
  width: "800px",
  height: "830px",
  "--n-padding-bottom": "10px",
  "--n-padding-left": "10px",
};

interface RowData {
  id: string;
  searchname: string;
  createby: string;
  createtime: string;
  updateby: string;
  updatetime: string;
}

const sortData = (row) => {
  console.log("sortData", row);
  if (row.order == "descend") {
    tableData.value.sort(
      (a, b) =>
        new Date(a[row.columnKey]).getTime() - new Date(b[row.columnKey]).getTime()
    );
  } else if (row.order == "ascend") {
    tableData.value.sort(
      (a, b) =>
        new Date(b[row.columnKey]).getTime() - new Date(a[row.columnKey]).getTime()
    );
  } else {
    tableData.value.sort((a, b) => Number((a as any).reorder) - Number((b as any).reorder));
  }
};

const columns: DataTableColumns<RowData> = [
  {
    type: "selection",
  },
  {
    title: "操作",
    key: "action",
    render(row) {
      return h(Action, {
        options: [
          { label: "编辑", key: 1 },
          { label: "删除", key: 2 },
        ],
        id: row.id,
        select,
      });
    },
  },
  {
    title: "名称",
    key: "searchname",
  },
  {
    title: "创建者",
    key: "createby",
  },
  {
    title: "创建时间",
    key: "createtime",
    width: 180,
    sorter: (row1, row2) => {
      // tableData.value.sort(
      //   (a, b) => new Date(a?.createtime).getTime() - new Date(b?.createtime).getTime()
      // );
      return new Date(row1?.createtime).getTime() - new Date(row2?.createtime).getTime();
    },
  },
  {
    title: "更新者",
    key: "updateby",
  },
  {
    title: "更新时间",
    key: "updatetime",
    width: 180,
  },
];
const total = ref(0);
const loading = ref(true);
const pagination = reactive({
  page: 1,
  pageCount: 1,
  pageSize: 10,
  showSizePicker: true,
  pageSizes: [
    {
      label: "10 每页",
      value: 10,
    },
    {
      label: "15 每页",
      value: 15,
    },
    {
      label: "30 每页",
      value: 30,
    },
    {
      label: "50 每页",
      value: 50,
    },
  ],
  showQuickJumper: true,
  prefix: () => `共 ${total.value} 条数据`,
});
const tableData = ref<Array<RowData>>([]);
const keyword = ref("");

async function query(page: number, pageSize: number) {
  const searchParam: FilterSearchParam = {
    search_searchname: { value: keyword.value, op: "like", type: "string" },
  };
  const result = await getConditionList({ pageNo: page, pageSize }, searchParam, 0);
  const { data, pageCount, total: totalCount } = result;
  tableData.value = data;
  pagination.page = page;
  total.value = totalCount;
  pagination.pageCount = pageCount;
  loading.value = false;
}

function afterLeave() {
  pagination.page = 1;
  pagination.pageCount = 1;
  pagination.pageSize = 10;
}

const selectionIds = ref<DataTableRowKey[]>([]);

const rowKey = (row: RowData) => row.id;

function rowProps(row: RowData) {
  return {
    "data-id": row.id,
  };
}

function handleCheck(rowKeys: DataTableRowKey[]) {
  selectionIds.value = rowKeys;
}

function select(key: number, id: string) {
  switch (key) {
    case 1:
      editSelection(id);
      break;
    case 2:
      deleteSelection(id);
      break;
    default:
      break;
  }
}

function editSelection(id) {
  // eslint-disable-next-line dot-notation
  // const $message = window["$message"];
  // if (selectionIds.value.length === 0 || selectionIds.value.length > 1) {
  //   $message.error("请选中一条过滤");
  //   return;
  // }
  const selectedId = id;
  const selectedFilter = tableData.value.find((item: any) => {
    return item.id === selectedId;
  });

  emit("editFilter", selectedFilter);
  // closeModal();
}

function deleteSelection(id = "") {
  // eslint-disable-next-line dot-notation
  if (selectionIds.value.length === 0) {
    deleteCondition({ ids: id }).then(() => {
      query(pagination.page, pagination.pageSize);
    });
    return;
  }

  deleteCondition({ ids: selectionIds.value.join(",") }).then(() => {
    query(pagination.page, pagination.pageSize);
  });
}

async function handlePageChange(currentPage) {
  if (loading.value) return;
  pagination.page = currentPage;
  const { pageSize } = pagination;
  await query(currentPage, pageSize);
}

async function handlePageSizeChange(currentPageSize) {
  if (loading.value) return;

  const { page } = pagination;
  pagination.pageSize = currentPageSize;
  await query(page, currentPageSize);
}

function handleClick() {
  emit("showNewFilter");
  // show.value = false;
}

let sortTable: Sortable | null = null;
const tableRef = ref<InstanceType<typeof NDataTable>>();

async function showModal() {
  show.value = true;

  const { page, pageSize } = pagination;
  await query(page, pageSize);

  nextTick(() => {
    if (sortTable !== null) destory();

    const el: HTMLDivElement = tableRef.value?.$el;
    const tbody: HTMLElement | null = el.querySelector("tbody.n-data-table-tbody")!;
    if (tbody) sortTable = Sortable.create(tbody, { onEnd, onMove });
  });
}
let relatedId = "";
let insertafter = false;

// TODO: 有bug，需跟后端联调
function onEnd(event: SortableEvent) {
  const data = unref(tableData);
  const oldElem = data[event.oldIndex!];
  data.splice(event.oldIndex!, 1);
  data.splice(event.newIndex!, 0, oldElem);

  const dragId = oldElem.id;
  const index = data.findIndex((item) => {
    return item.id === relatedId;
  });

  // 插入到元素后，索引-1；插入到元素前，索引+1
  const order = insertafter ? index - 1 : index + 1;
  // console.log('dragid:', dragId, 'order:', order)
  sort(dragId, order);
}

function onMove(evt: any) {
  relatedId = evt.related?.dataset?.id;
  insertafter = evt.willInsertAfter;
  // console.log(`你正在拖动：${evt.dragged.dataset.id},替换了：${evt.related}`, 'insertafter', evt.willInsertAfter)
}

function destory() {
  sortTable && sortTable.destroy();
  sortTable = null;
}

onUnmounted(() => {
  destory();
});

function closeModal() {
  show.value = false;
}

defineExpose({
  showModal,
});

const inputHandler = debounce((word) => {
  keyword.value = word;
  query(1, 5);
}, 300);
</script>

<template>
  <div>
    <n-modal
      v-model:show="show"
      transform-origin="center"
      display-directive="if"
      @after-leave="afterLeave"
    >
      <n-card
        :style="cardStyle"
        :bordered="false"
        size="huge"
        role="dialog"
        aria-modal="true"
      >
        <div class="wrapper">
          <span class="wrapper-title">全部过滤条件</span>
          <div class="wrapper-bar">
            <div class="wrapper-info">
              <span
                :style="{ 'margin-left': '18px', 'font-size': '16px' }"
                class="wrapper-info-title"
                >基本信息</span
              >
            </div>
          </div>
          <div class="wrapper-form">
            <n-input
              :style="{ width: '360px', border: '1px solid #cad2dd' }"
              placeholder="请输入过滤条件名称搜索"
              @input="inputHandler"
            >
              <template #suffix>
                <SvgIcon size="14px" name="magnifying-1" color="#fff" />
              </template>
            </n-input>
            <n-button type="info" style="background: #507afd" @click="handleClick">
              创建
              <template #icon>
                <img
                  src="../../../../../assets/images/addIcon.png"
                  style="width: 16px; height: 16px"
                />
              </template>
            </n-button>
          </div>

          <div class="wrapper-table">
            <NDataTable
              ref="tableRef"
              :max-height="480"
              remote
              :row-props="rowProps as any"
              :columns="columns"
              :data="tableData"
              :loading="loading"
              :pagination="pagination"
              :row-key="rowKey"
              @update:page="handlePageChange"
              @update-page-size="handlePageSizeChange"
              @update:checked-row-keys="handleCheck"
              @update:sorter="sortData"
            />
          </div>
        </div>
        <template #footer>
          <div class="wrapper-footer">
            <n-button type="info" @click="closeModal"> 确认 </n-button>
            <n-button secondary style="margin-left: 15px" @click="closeModal">
              取消
            </n-button>
          </div>
        </template>
      </n-card>
    </n-modal>
  </div>
</template>

<style lang="less" scoped>
.wrapper {
  display: flex;
  flex-direction: column;
  padding: 20px;

  &-title {
    font-weight: bold;
    font-size: 20px;
  }

  &-bar {
    background-color: #f8f8f8;
    width: 100%;
    margin-top: 20px;
  }

  &-form {
    display: flex;
    justify-content: space-between;
    margin-top: 20px;

    .n-input {
      width: 300px;
      border: 1px solid gray;
    }
  }

  &-table {
    margin-top: 20px;
  }

  &-footer {
    display: flex;
    justify-content: flex-end;
  }

  &-info {
    font-weight: bold;
    position: relative;

    &:before {
      background-color: #1980ff;
      content: "";
      width: 5px;
      border-radius: 2px;
      top: 0;
      left: 3px;
      bottom: 0;
      position: absolute;
    }
    &-title {
      font-size: 16px;
      font-family: PingFang SC, PingFang SC-Medium;
      font-weight: Medium;
      text-align: left;
      color: #333333;
      line-height: 22px;
    }
  }
}
::v-deep(.n-data-table .n-data-table-th){
  font-weight: bold !important;
}
</style>
