<template>
  <AppPage :show-footer="true">
    <section class="workbench-overview">
      <div class="workbench-overview__title">
        <h1>概览</h1>
        <p>查看客户端连接和最近操作。</p>
      </div>
      <div class="workbench-overview__stats">
        <span>在线客户端 {{ onlineCount }}</span>
        <span>客户端总数 {{ connectionCount }}</span>
        <span>日志 {{ paginate.itemCount }}</span>
      </div>
      <div class="workbench-overview__user">
        <n-avatar round :size="40" :src="userStore.avatar" />
        <div>
          <strong>{{ userStore.nickname }}</strong>
          <p>{{ dailyPoetry.content || '莫向外求，但从心觅，行有不得，反求诸己。' }}</p>
        </div>
      </div>
    </section>

    <section class="workbench-grid">
      <n-card class="panel-card" :bordered="false">
        <template #header>
          <div class="panel-card__header">
            <h3>最近操作日志</h3>
          </div>
        </template>
        <n-data-table
          class="dashboard-table"
          remote
          :columns="tableColumns"
          :data="tableData.data"
          :pagination="paginate"
        />
      </n-card>

      <n-card class="panel-card" :bordered="false">
        <template #header>
          <div class="panel-card__header">
            <h3>客户端连接状态</h3>
          </div>
        </template>
        <div
          class="connections-panel"
          @click="closeDropdown"
          @contextmenu.prevent="openDropdown"
        >
          <n-data-table
            class="dashboard-table"
            remote
            :columns="connectionsColumns"
            :data="connectionsData.data"
          />
          <n-dropdown
            placement="bottom-start"
            trigger="manual"
            size="small"
            :x="xRef"
            :y="yRef"
            :options="rightMenuOpts"
            @select="rowSelect"
            @clickoutside="closeDropdown"
            :show="showDropdownRef"
          />
        </div>
      </n-card>
    </section>
  </AppPage>
</template>

<script setup>
import { useUserStore } from '@/store'
import api from '@/views/workbench/api'
import { debounce, renderIcon } from '@/utils'
import { NTag } from 'naive-ui'

const userStore = useUserStore()

const tableData = ref({
  data: []
})

const connectionsData = ref({
  data: []
})

const dailyPoetry = ref({
  author: '',
  content: ''
})

const onlineCount = computed(
  () => connectionsData.value.data.filter((item) => item.online === true).length
)
const connectionCount = computed(() => connectionsData.value.data.length)

// 表格表头
const tableColumns = [
  {
    title: '用户名称',
    key: 'username',
    align: 'center',
    titleAlign: 'center'
  },
  {
    title: '客户端IP',
    key: 'clientIP',
    align: 'center',
    titleAlign: 'center'
  },
  {
    title: '请求方法',
    key: 'method',
    align: 'center',
    titleAlign: 'center'
  },
  {
    title: '请求主机',
    key: 'host',
    align: 'center',
    titleAlign: 'center'
  },
  {
    title: '请求地址',
    key: 'uri',
    align: 'center',
    titleAlign: 'center'
  },
  {
    title: '状态码',
    key: 'statusCode',
    align: 'center',
    titleAlign: 'center'
  },
  {
    title: '请求时间',
    key: 'createdAt',
    align: 'center',
    titleAlign: 'center'
  },
]

// 链接信息列表
const connectionsColumns = [
  {
    title: '客户端名称',
    key: 'name',
    align: 'center',
    titleAlign: 'center'
  },
  {
    title: '联系邮箱',
    key: 'email',
    align: 'center',
    titleAlign: 'center'
  },
  {
    title: '客户端IP',
    key: 'ipAllocation',
    align: 'center',
    titleAlign: 'center'
  },
  {
    title: '端点',
    key: 'connectEndpoint',
    align: 'center',
    titleAlign: 'center'
  },
  {
    title: '是否在线',
    key: 'online',
    align: 'center',
    titleAlign: 'center',
    render: (row) => {
      switch (row.online) {
        case true:
          return h(NTag, {
            type: 'info',
          }, {
            default: () => '在线'
          })
        case false:
          return h(NTag, {
            type: 'warning',
          }, {
            default: () => '离线'
          })
      }
    }
  },
  {
    title: '接受流量',
    key: 'receiveBytes',
    align: 'center',
    titleAlign: 'center'
  },
  {
    title: '传输流量',
    key: 'transmitBytes',
    align: 'center',
    titleAlign: 'center'
  },
  {
    title: '最后握手时间',
    key: 'lastHandAt',
    align: 'center',
    titleAlign: 'center'
  }
]

const rightMenuOpts = [
  {
    label: () => h('span', { style: { color: 'green' } }, '刷新'),
    key: 'refresh',
    icon: renderIcon('tabler:refresh', { size: 14 })
  }
]

const showDropdownRef = ref(false)
const xRef = ref(0)
const yRef = ref(0)

function openDropdown(e) {
  showDropdownRef.value = false
  nextTick().then(() => {
    showDropdownRef.value = true
    xRef.value = e.clientX
    yRef.value = e.clientY
  })
}

function closeDropdown() {
  showDropdownRef.value = false
}

function onWindowKeydown(e) {
  if (e.key === 'Escape') {
    closeDropdown()
  }
}

function rowSelect(row) {
  switch (row) {
    case 'refresh':
      getClientConnections()
      closeDropdown()
  }
}

const paginate = reactive({
  page: 1,
  pageSize: 2,
  itemCount: 0,
  pageCount: 0,
  onChange: (page) => {
    paginate.page = page
    getLogsList()
  }
})

async function getLogsList() {
  try {
    const res = await api.logsList({
      current: paginate.page,
      size: paginate.pageSize,
    })
    if (res.data.code === 200) {
      tableData.value.data = res.data.data.records
      paginate.itemCount = res.data.data.total
      paginate.pageCount = res.data.data.totalPage
    }
  } catch (error) {
    return error
  }
}

const dailyPoe = debounce(() => {
  getDailyPoetry()
}, 800)

async function getDailyPoetry() {
  try {
    const res = await api.dailyPoetry()
    if (res.data.code === 200) {
      dailyPoetry.value.author = res.data.data.author
      dailyPoetry.value.content = res.data.data.content
    }
  } catch (error) {
    return error
  }
}

async function getClientConnections() {
  try {
    const res = await api.clientConnections()
    if (res.data.code === 200) {
      connectionsData.value.data = res.data.data
    }
  } catch (e) {
    return e
  }
}

const initFunc = debounce(() => {
  getClientConnections()
  dailyPoe()
}, 500)

onMounted(() => {
  window.addEventListener('keydown', onWindowKeydown)
  window.addEventListener('blur', closeDropdown)
})

onBeforeUnmount(() => {
  window.removeEventListener('keydown', onWindowKeydown)
  window.removeEventListener('blur', closeDropdown)
})

getLogsList()
initFunc()
</script>

<style scoped lang="scss">
.workbench-overview {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  padding: 4px 2px;
}

.workbench-overview__title h1,
.panel-card__header h3 {
  margin: 0;
  font-size: 18px;
  line-height: 1.4;
  color: #0f172a;
}

.workbench-overview__title p {
  margin: 4px 0 0;
  font-size: 13px;
  color: #64748b;
}

.workbench-overview__stats {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.workbench-overview__stats span {
  padding: 6px 10px;
  border: 1px solid rgba(148, 163, 184, 0.18);
  border-radius: 999px;
  font-size: 13px;
  color: #475569;
  background: rgba(255, 255, 255, 0.9);
}

.workbench-overview__user {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  max-width: 360px;
}

.workbench-overview__user strong {
  display: block;
  font-size: 14px;
  color: #0f172a;
}

.workbench-overview__user p {
  margin: 4px 0 0;
  font-size: 13px;
  line-height: 1.6;
  color: #64748b;
}

.workbench-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 16px;
}

.panel-card {
  border-radius: 14px;
  background: #ffffff;
}

.panel-card__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  color: #0f172a;
}

.dashboard-table:deep(.n-data-table-wrapper) {
  overflow: hidden;
  border-radius: 10px;
}

.connections-panel {
  position: relative;
}

@media (max-width: 960px) {
  .workbench-overview {
    flex-direction: column;
  }

  .workbench-overview__user {
    max-width: none;
  }
}
</style>
