<script lang="ts" setup>
import { 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 Action from '../Action.vue'
import { deleteCondition, getConditionList, sort } from '@/api/home/filter'

defineOptions({ name: 'FilterModal' })

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

const show = ref(false)

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

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

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',
  },
  {
    title: '更新者',
    key: 'updateby',
  },
  {
    title: '更新时间',
    key: 'updatetime',
  },
]

const loading = ref(true)
const pagination = reactive({
  page: 1,
  pageCount: 1,
  pageSize: 10,
})
const tableData = ref<Array<RowData>>([])

async function query(page: number, pageSize: number) {
  const result = await getConditionList({ pageNo: page, pageSize })
  const { data, pageCount } = result
  tableData.value = data
  pagination.page = page
  pagination.pageCount = pageCount
  loading.value = false
}

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

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) {
  switch (key) {
    case 1:
      editSelection()
      break
    case 2:
      deleteSelection()
      break
    default:
      break
  }
}

function editSelection() {
  // eslint-disable-next-line dot-notation
  const $message = window['$message']

  if (selectionIds.value.length === 0 || selectionIds.value.length > 1) {
    $message.error('请选中一条过滤')
    return
  }

  const selectedId = selectionIds.value[0]
  const selectedFilter = tableData.value.find((item: any) => {
    return item.id === selectedId
  })

  emit('editFilter', selectedFilter)
  closeModal()
}

function deleteSelection() {
  // eslint-disable-next-line dot-notation
  const $message = window['$message']

  if (selectionIds.value.length === 0) {
    $message.error('至少选中一条过滤')
    return
  }

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

async function handlePageChange(currentPage) {
  if (loading.value)
    return

  const { pageSize } = pagination
  await query(currentPage, pageSize)
}

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,
})
</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' }">基本信息</span>
            </div>
          </div>
          <div class="wrapper-form">
            <n-input :style="{ width: '360px', border: '1px solid #cad2dd' }" placeholder="请输入过滤条件名称搜索">
              <template #suffix>
                <SvgIcon size="14px" name="magnifying-1" />
              </template>
            </n-input>
            <n-button type="info" @click="handleClick">
              创建
              <template #icon>
                <SvgIcon size="14px" name="magnifying-1" />
              </template>
            </n-button>
          </div>
          <div class="wrapper-table">
            <NDataTable
              ref="tableRef" remote :row-props="rowProps as any" :columns="columns" :data="tableData" :loading="loading"
              :pagination="pagination" :row-key="rowKey" @update:page="handlePageChange"
              @update:checked-row-keys="handleCheck"
            />
          </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;

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

  &-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;
      bottom: 0;
      position: absolute;
    }
  }
}
</style>
