<script setup lang="ts">
import { computed, onMounted, ref } from 'vue';
import dayjs from 'dayjs';
import { fetchGetRecentNotices } from '@/service/api';
import { useAuthStore } from '@/store/modules/auth';
import { formatRelativeTime } from '@/utils/datetime';
import BusinessFormDialog from '@/components/custom/business-form-dialog.vue';
import { getGreeting } from '../homepage';

defineOptions({ name: 'WorkbenchBanner' });

const authStore = useAuthStore();
const displayName = computed(() => authStore.userInfo.nickname || authStore.userInfo.userName || '同学');
const greeting = computed(() => getGreeting());

const weekdayNames = ['', '周一', '周二', '周三', '周四', '周五', '周六', '周日'];
const dateContext = computed(() => {
  const now = dayjs();
  return {
    date: now.format('YYYY-MM-DD'),
    weekday: weekdayNames[now.isoWeekday()] ?? '',
    week: `第 ${now.isoWeek()} 周`
  };
});

// 「全部公告」抽屉无独立菜单/权限码，只能走登录即可的 recent 接口，取最新 50 条兜底
const NOTICE_FETCH_SIZE = 50;

const allNotices = ref<Api.Notice.Notice[]>([]);
const noticesLoading = ref(false);

async function loadNotices() {
  noticesLoading.value = true;
  const { data, error } = await fetchGetRecentNotices(NOTICE_FETCH_SIZE);
  noticesLoading.value = false;
  if (error || !data) return;
  allNotices.value = data;
}

onMounted(loadNotices);

const previewNotices = computed(() => allNotices.value.slice(0, 3));
const drawerOpen = ref(false);

const detailOpen = ref(false);
const detailNotice = ref<Api.Notice.Notice | null>(null);

function openNoticeDetail(row: Api.Notice.Notice) {
  detailNotice.value = row;
  detailOpen.value = true;
}

// 公告内容可能为富文本，列表行只取纯文本做单行预览
function toNoticeSnippet(html: string) {
  return html
    .replace(/<[^>]*>/g, ' ')
    .replace(/\s+/g, ' ')
    .trim();
}

const detailTimeLabel = computed(() =>
  detailNotice.value ? dayjs(detailNotice.value.createTime).format('YYYY-MM-DD HH:mm') : ''
);

function openDrawer() {
  drawerOpen.value = true;
}

function closeDrawer() {
  drawerOpen.value = false;
}
</script>

<template>
  <section class="workbench-banner">
    <div class="workbench-banner__identity">
      <h1 class="workbench-banner__title">{{ greeting }}，{{ displayName }}</h1>
      <p class="workbench-banner__meta">
        {{ dateContext.date }} {{ dateContext.weekday }}
        <span class="workbench-banner__meta-dot">·</span>
        {{ dateContext.week }}
      </p>
    </div>

    <div class="workbench-banner__notice">
      <header class="workbench-banner__notice-header">
        <span class="workbench-banner__notice-title">
          <SvgIcon icon="mdi:bullhorn-outline" class="workbench-banner__notice-icon" />
          公告
          <span class="workbench-banner__notice-count">{{ allNotices.length }}</span>
        </span>
        <button class="workbench-banner__notice-more" type="button" @click="openDrawer">
          更多
          <SvgIcon icon="mdi:arrow-right" />
        </button>
      </header>
      <ul v-if="previewNotices.length > 0" class="workbench-banner__notice-list">
        <li
          v-for="row in previewNotices"
          :key="row.id"
          class="workbench-banner__notice-row"
          @click="openNoticeDetail(row)"
        >
          <div class="workbench-banner__notice-row-main">
            <span class="workbench-banner__notice-row-title">{{ row.title }}</span>
            <span class="workbench-banner__notice-row-time">{{ formatRelativeTime(row.createTime) }}</span>
          </div>
          <div v-if="row.content" class="workbench-banner__notice-row-snippet">{{ toNoticeSnippet(row.content) }}</div>
        </li>
      </ul>
      <div v-else class="workbench-banner__notice-empty">
        {{ noticesLoading ? '加载中…' : '暂无公告' }}
      </div>
    </div>

    <ElDrawer v-model="drawerOpen" title="全部公告" size="480px">
      <ElScrollbar>
        <ul v-if="allNotices.length > 0" class="workbench-banner__drawer-list">
          <li
            v-for="row in allNotices"
            :key="row.id"
            class="workbench-banner__drawer-row"
            @click="openNoticeDetail(row)"
          >
            <div class="workbench-banner__drawer-row-title">{{ row.title }}</div>
            <div v-if="row.content" class="workbench-banner__drawer-row-snippet">
              {{ toNoticeSnippet(row.content) }}
            </div>
            <div class="workbench-banner__drawer-row-time">{{ formatRelativeTime(row.createTime) }}</div>
          </li>
        </ul>
        <div v-else class="workbench-banner__notice-empty">暂无公告</div>
      </ElScrollbar>
      <template #footer>
        <ElButton @click="closeDrawer">关闭</ElButton>
      </template>
    </ElDrawer>

    <BusinessFormDialog v-model="detailOpen" title="公告详情" width="560px">
      <template v-if="detailNotice">
        <h3 class="workbench-banner__detail-title">{{ detailNotice.title }}</h3>
        <p class="workbench-banner__detail-time">{{ detailTimeLabel }}</p>
        <BusinessRichTextView :value="detailNotice.content" />
      </template>
      <template #footer="{ close }">
        <ElButton @click="close">关闭</ElButton>
      </template>
    </BusinessFormDialog>
  </section>
</template>

<style scoped>
.workbench-banner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr);
  align-items: stretch;
  gap: 24px;
  padding: 22px 28px;
  border: 1px solid rgb(226 232 240 / 88%);
  border-radius: 20px;
  background-color: rgb(255 255 255 / 96%);
}

.workbench-banner__identity {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 8px;
  min-width: 0;
}

.workbench-banner__title {
  margin: 0;
  color: rgb(15 23 42 / 98%);
  font-size: 26px;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.01em;
}

.workbench-banner__meta {
  margin: 0;
  color: rgb(100 116 139 / 92%);
  font-size: 13px;
}

.workbench-banner__meta-dot {
  margin: 0 6px;
  color: rgb(203 213 225 / 96%);
}

.workbench-banner__notice {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
  padding-left: 24px;
  border-left: 1px solid rgb(226 232 240 / 88%);
}

.workbench-banner__notice-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.workbench-banner__notice-title {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: rgb(15 23 42 / 96%);
  font-size: 14px;
  font-weight: 600;
}

.workbench-banner__notice-icon {
  color: rgb(14 116 144 / 92%);
  font-size: 16px;
}

.workbench-banner__notice-count {
  display: inline-flex;
  align-items: center;
  padding: 1px 8px;
  border-radius: 999px;
  background-color: rgb(241 245 249 / 96%);
  color: rgb(71 85 105 / 96%);
  font-size: 11px;
  font-weight: 500;
}

.workbench-banner__notice-more {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 2px 6px;
  border: none;
  border-radius: 6px;
  background-color: transparent;
  color: rgb(14 116 144 / 96%);
  font-size: 13px;
  cursor: pointer;
  transition:
    background-color 160ms ease,
    color 160ms ease;
}

.workbench-banner__notice-more:hover {
  background-color: rgb(236 254 255 / 92%);
  color: rgb(8 90 110 / 96%);
}

.workbench-banner__notice-more:focus-visible {
  outline: 2px solid rgb(14 116 144 / 60%);
  outline-offset: 2px;
}

.workbench-banner__notice-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 0;
  padding: 0;
  list-style: none;
  max-height: 156px;
  /* 行项负 margin 出血会把 overflow-x 撑出横向滚动条，显式裁掉 */
  overflow-x: hidden;
  overflow-y: auto;
}

.workbench-banner__notice-list::-webkit-scrollbar {
  width: 6px;
}

.workbench-banner__notice-list::-webkit-scrollbar-thumb {
  background-color: rgb(203 213 225 / 70%);
  border-radius: 3px;
}

.workbench-banner__notice-row {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 6px;
  margin: 0 -6px;
  border-radius: 8px;
  border-bottom: 1px dashed rgb(226 232 240 / 70%);
  cursor: pointer;
  transition: background-color 120ms ease;
}

.workbench-banner__notice-row:hover {
  background-color: rgb(241 245 249 / 80%);
}

.workbench-banner__notice-row:last-child {
  border-bottom: none;
}

.workbench-banner__notice-row-main {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: baseline;
  gap: 12px;
}

.workbench-banner__notice-row-title {
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: rgb(15 23 42 / 96%);
  font-size: 14px;
  font-weight: 500;
}

.workbench-banner__notice-row-time {
  color: rgb(100 116 139 / 92%);
  font-size: 12px;
  white-space: nowrap;
}

.workbench-banner__notice-row-snippet {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: rgb(100 116 139 / 92%);
  font-size: 12px;
}

.workbench-banner__notice-empty {
  padding: 16px 0;
  color: rgb(100 116 139 / 92%);
  font-size: 13px;
}

.workbench-banner__drawer-list {
  margin: 0;
  padding: 0 4px 0 0;
  list-style: none;
  /* 同款负 margin 出血，裁掉横向溢出，避免传到 ElScrollbar */
  overflow: hidden;
}

.workbench-banner__drawer-row {
  padding: 12px 8px;
  margin: 0 -8px;
  border-radius: 8px;
  border-bottom: 1px solid rgb(226 232 240 / 80%);
  cursor: pointer;
  transition: background-color 120ms ease;
}

.workbench-banner__drawer-row:hover {
  background-color: rgb(241 245 249 / 80%);
}

.workbench-banner__drawer-row:last-child {
  border-bottom: none;
}

.workbench-banner__drawer-row-title {
  color: rgb(15 23 42 / 96%);
  font-size: 15px;
  font-weight: 500;
  line-height: 1.5;
}

.workbench-banner__drawer-row-snippet {
  margin-top: 4px;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: rgb(71 85 105 / 92%);
  font-size: 13px;
}

.workbench-banner__drawer-row-time {
  margin-top: 4px;
  color: rgb(100 116 139 / 92%);
  font-size: 12px;
}

.workbench-banner__detail-title {
  margin: 0;
  color: rgb(15 23 42 / 98%);
  font-size: 17px;
  font-weight: 600;
  line-height: 1.4;
}

.workbench-banner__detail-time {
  margin: 6px 0 14px;
  color: rgb(100 116 139 / 92%);
  font-size: 12px;
}

@media (width <= 1024px) {
  .workbench-banner {
    grid-template-columns: 1fr;
  }

  .workbench-banner__notice {
    padding-left: 0;
    padding-top: 16px;
    border-left: none;
    border-top: 1px solid rgb(226 232 240 / 88%);
  }
}

@media (width <= 768px) {
  .workbench-banner {
    padding: 18px 20px;
  }

  .workbench-banner__title {
    font-size: 22px;
  }
}
</style>
