<script setup lang="ts">
import { computed, onMounted, ref, watch } from 'vue';
import { useRouter } from 'vue-router';

import { Page } from '@vben/common-ui';

import { Button, notification, Tag } from 'ant-design-vue';
import {
  Bell,
  CalendarClock,
  CheckCircle2,
  ChevronDown,
  ChevronLeft,
  ChevronRight,
  Eye,
  Filter,
  Megaphone,
  Search,
  X,
} from 'lucide-vue-next';

import { getNoticeListApi, readAllApi, readApi } from '#/views/notice/api';

const router = useRouter();

// 消息数据和分页状态
const messages = ref([]);
const loading = ref(false);
const currentPage = ref(1);
const pageSize = ref(5);
const total = ref(0);
const totalPages = ref(1);

// 筛选相关
const filterType = ref(-1); // -1表示全部
const searchQuery = ref('');
const showFilterDropdown = ref(false);

// 消息类型定义
const messageTypes = [
  { id: -1, name: '全部消息' },
  { id: 0, name: '系统公告', icon: Megaphone },
  { id: 1, name: '系统通知', icon: Bell },
  { id: 2, name: '周报提醒', icon: CalendarClock },
];

// 获取消息列表数据
const getNoticeList = async () => {
  loading.value = true;
  try {
    const res = await getNoticeListApi({
      page: currentPage.value,
      size: pageSize.value,
      type: filterType.value === -1 ? undefined : filterType.value,
      title: searchQuery.value || undefined,
    });

    messages.value = res.items.map((item) => ({
      ...item,
      // 将API返回的数据映射到组件需要的格式
      type_txt: getMessageTypeName(item.type),
      date: item.created_at,
      // status: 0表示未读，1表示已读
    }));

    total.value = res.total;
    totalPages.value = res.page_count;
  } catch (error) {
    console.error('获取消息列表失败:', error);
  } finally {
    loading.value = false;
  }
};

// 根据类型ID获取类型名称
const getMessageTypeName = (typeId) => {
  const type = messageTypes.find((t) => t.id === typeId);
  return type ? type.name : '未知类型';
};

// 监听筛选条件变化，重新获取数据
watch([filterType, searchQuery], () => {
  currentPage.value = 1;
  getNoticeList();
});

// 监听页码变化，重新获取数据
watch(currentPage, () => {
  getNoticeList();
});

// 组件挂载时获取数据
onMounted(() => {
  getNoticeList();
});

// 未读消息数量
const unreadCount = computed(() => {
  return messages.value.filter((msg) => msg.status === 0).length;
});

// 样式相关
const typeIcons = {
  0: Megaphone,
  1: Bell,
  2: CalendarClock,
};

const typeColors = {
  0: 'text-sky-500 dark:text-sky-400',
  1: 'text-amber-500 dark:text-amber-400',
  2: 'text-emerald-500 dark:text-emerald-400',
};

const typeBgColors = {
  0: 'bg-sky-50 dark:bg-sky-900/30',
  1: 'bg-amber-50 dark:bg-amber-900/30',
  2: 'bg-emerald-50 dark:bg-emerald-900/30',
};

const typeBorderColors = {
  0: 'border-sky-200 dark:border-sky-800',
  1: 'border-amber-200 dark:border-amber-800',
  2: 'border-emerald-200 dark:border-emerald-800',
};

// 处理消息点击
const handleItemClick = (item) => {
  router.push(`/notice/detail/${item.id}`);
};

// 标记消息为已读
const markAsRead = async (event, item) => {
  event.stopPropagation();
  try {
    await readApi(item.id);
    item.status = 1; // 临时更新UI状态
    // 成功后可以重新获取数据或者直接更新本地状态
    notification.success({
      message: '标记成功',
      duration: 2,
    });
    // getNoticeList();
  } catch (error) {
    console.error('标记已读失败:', error);
  }
};

// 标记所有消息为已读
const markAllAsRead = async () => {
  try {
    await readAllApi();
    messages.value.forEach((msg) => {
      msg.status = 1;
    });
    // 成功后可以重新获取数据或者直接更新本地状态
    notification.success({
      message: '标记成功',
      duration: 2,
    });
    // getNoticeList();
  } catch (error) {
    console.error('标记全部已读失败:', error);
  }
};

// 清除搜索
const clearSearch = () => {
  searchQuery.value = '';
};

// 切换筛选下拉菜单
const toggleFilterDropdown = () => {
  showFilterDropdown.value = !showFilterDropdown.value;
};

// 选择筛选类型
const selectFilterType = (type) => {
  filterType.value = type;
  showFilterDropdown.value = false;
};

// 分页导航
const goToPage = (page) => {
  if (page >= 1 && page <= totalPages.value) {
    currentPage.value = page;
  }
};

// 获取当前选中的筛选类型名称
const currentFilterName = computed(() => {
  const type = messageTypes.find((t) => t.id === filterType.value);
  return type ? type.name : '全部消息';
});

// 展开消息详情
const expandedMessage = ref(null);
const toggleExpand = (event, id) => {
  event.stopPropagation();
  expandedMessage.value = expandedMessage.value === id ? null : id;
};
</script>

<template>
  <Page title="消息中心" description="关于执行的操作通知、公告等等信息都会在这里">
    <template #extra>
      <div class="flex items-center gap-2">
        <span class="text-gray-500 dark:text-gray-400">共 {{ total }} 条消息</span>
        <span
          v-if="unreadCount > 0"
          class="rounded-full bg-red-500 px-2 py-0.5 text-xs font-medium text-white dark:bg-red-600"
        >
          {{ unreadCount }} 未读
        </span>
      </div>
    </template>

    <div class="mx-auto max-w-4xl">
      <!-- 筛选和搜索工具栏 -->
      <div
        class="mb-4 flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between"
      >
        <!-- 筛选下拉菜单 -->
        <div class="relative">
          <button
            class="flex items-center gap-2 rounded-lg border border-gray-200 bg-white px-4 py-2 text-sm font-medium text-gray-700 shadow-sm transition-colors hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-sky-500 focus:ring-offset-2 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700 dark:focus:ring-sky-400 dark:focus:ring-offset-gray-900"
            @click="toggleFilterDropdown"
          >
            <Filter class="h-4 w-4" />
            {{ currentFilterName }}
            <ChevronDown class="h-4 w-4" />
          </button>

          <div
            v-if="showFilterDropdown"
            class="absolute left-0 top-full z-10 mt-1 w-56 origin-top-left rounded-md bg-white shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none dark:bg-gray-800 dark:ring-white dark:ring-opacity-10"
          >
            <div class="py-1">
              <button
                v-for="type in messageTypes"
                :key="type.id"
                :class="
                  filterType === type.id
                    ? 'bg-gray-50 font-medium text-sky-600 dark:bg-gray-700 dark:text-sky-400'
                    : 'text-gray-700 dark:text-gray-200'
                "
                class="flex w-full items-center gap-2 px-4 py-2 text-left text-sm transition-colors hover:bg-gray-100 dark:hover:bg-gray-700"
                @click="selectFilterType(type.id)"
              >
                <component
                  :is="type.icon"
                  v-if="type.id !== -1 && type.icon"
                  :class="type.id !== -1 ? typeColors[type.id] : ''"
                  class="h-4 w-4"
                />
                {{ type.name }}
              </button>
            </div>
          </div>
        </div>

        <!-- 搜索框 -->
        <div class="relative flex-1 sm:max-w-xs">
          <div
            class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3"
          >
            <Search class="h-4 w-4 text-gray-400 dark:text-gray-500" />
          </div>
          <input
            v-model="searchQuery"
            class="block w-full rounded-lg border border-gray-200 bg-white py-2 pl-10 pr-10 text-sm text-gray-700 transition-colors focus:border-sky-500 focus:outline-none focus:ring-1 focus:ring-sky-500 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-200 dark:focus:border-sky-400 dark:focus:ring-sky-400"
            placeholder="搜索消息..."
            type="text"
          />
          <button
            v-if="searchQuery"
            class="absolute inset-y-0 right-0 flex items-center pr-3"
            @click="clearSearch"
          >
            <X
              class="h-4 w-4 text-gray-400 transition-colors hover:text-gray-600 dark:text-gray-500 dark:hover:text-gray-300"
            />
          </button>
        </div>

        <!-- 标记全部已读按钮 -->
        <button
          v-if="unreadCount > 0"
          class="flex items-center gap-1 rounded-lg bg-white px-3 py-2 text-sm font-medium text-gray-700 shadow-sm ring-1 ring-gray-200 transition-colors hover:bg-gray-50 dark:bg-gray-800 dark:text-gray-200 dark:ring-gray-700 dark:hover:bg-gray-700"
          @click="markAllAsRead"
        >
          <CheckCircle2 class="h-4 w-4 text-gray-500 dark:text-gray-400" />
          标记全部已读
        </button>
        <Button type="link" @click="getNoticeList">刷新</Button>
      </div>

      <!-- 消息列表 -->
      <div
        class="overflow-hidden rounded-xl border border-gray-200 bg-white shadow-sm dark:border-gray-700 dark:bg-gray-800"
      >
        <!-- 加载状态 -->
        <div v-if="loading" class="flex justify-center py-12">
          <div
            class="h-8 w-8 animate-spin rounded-full border-4 border-gray-200 border-t-sky-500 dark:border-gray-700 dark:border-t-sky-400"
          ></div>
        </div>

        <!-- 空状态 -->
        <div
          v-else-if="messages.length === 0"
          class="flex flex-col items-center justify-center py-16"
        >
          <Bell class="mb-4 h-16 w-16 text-gray-200 dark:text-gray-700" />
          <p class="text-gray-500 dark:text-gray-400">暂无消息</p>
          <p
            v-if="searchQuery || filterType !== -1"
            class="mt-2 text-sm text-gray-400 dark:text-gray-500"
          >
            尝试调整筛选条件
          </p>
        </div>

        <!-- 消息列表 -->
        <ul v-else class="divide-y divide-gray-100 dark:divide-gray-700">
          <li
            v-for="item in messages"
            :key="item.id"
            :class="[
              item.status === 0
                ? 'bg-gray-50 dark:bg-gray-900'
                : 'bg-gray-50 dark:bg-gray-800',
            ]"
            class="group relative cursor-pointer transition-all duration-200"
            @click="handleItemClick(item)"
          >
            <div class="flex items-start gap-4 p-4 sm:p-5">
              <!-- 图标 -->
              <div
                :class="[
                  item.status === 1
                    ? 'bg-gray-100 dark:bg-gray-700'
                    : typeBgColors[item.type],
                ]"
                class="flex h-10 w-10 shrink-0 items-center justify-center rounded-full transition-all duration-200"
                style="margin: auto 0;"
              >
                <component
                  :is="typeIcons[item.type]"
                  :class="[
                    item.status === 1
                      ? 'text-gray-400 group-hover:text-gray-600 dark:text-gray-500 dark:group-hover:text-gray-300'
                      : typeColors[item.type],
                  ]"
                  class="h-5 w-5 transition-all duration-200"
                />
              </div>

              <!-- 内容 -->
              <div class="min-w-0 flex-1">
                <div class="flex items-start justify-between gap-2">
                  <h3
                    :class="[
                      item.status === 0
                        ? 'font-semibold text-gray-900 dark:text-white'
                        : 'text-gray-700 group-hover:text-gray-900 dark:text-gray-300 dark:group-hover:text-white',
                    ]"
                    class="text-sm font-medium transition-all duration-200 sm:text-base"
                  >
                    {{ item.title }}
                  </h3>
                  <span
                    class="shrink-0 whitespace-nowrap text-xs text-gray-400 dark:text-gray-500"
                    >{{ item.date }}</span>
                </div>

                <div class="mt-1 flex flex-wrap items-center gap-2">
                  <span
                    :class="[
                      item.status === 1
                        ? 'border-gray-200 text-gray-500 dark:border-gray-700 dark:text-gray-400'
                        : `${typeColors[item.type]} ${typeBorderColors[item.type]}`,
                    ]"
                    class="inline-flex items-center rounded-full border px-2 py-0.5 text-xs font-medium transition-all duration-200"
                  >
                    {{ item.type_txt }}
                  </span>

                  <!-- 详情文本，只显示第一行，可展开 -->
                  <div class="mt-1 w-full">
                    <p
                      :class="[
                        item.status === 1
                          ? 'text-gray-500 dark:text-gray-400'
                          : 'text-gray-700 dark:text-gray-300',
                        expandedMessage === item.id ? '' : 'line-clamp-1',
                      ]"
                      class="text-xs transition-all duration-200"
                    >
                      {{ item.detail }}
                    </p>

                    <!-- 展开/收起按钮 -->
                    <button
                      v-if="item.detail && item.detail.length > 70"
                      class="mt-1 flex items-center gap-1 text-xs text-sky-500 transition-colors hover:text-sky-600 dark:text-sky-400 dark:hover:text-sky-300"
                      @click="toggleExpand($event, item.id)"
                    >
                      <Eye class="h-3 w-3" />
                      {{ expandedMessage === item.id ? '收起' : '展开' }}
                    </button>
                  </div>

                  <span
                    v-if="item.is_my === 1"
                    style="position: absolute; bottom: 10px; right: 10px"
                  >
                    我发布的 （{{ item.is_all_read === 1 ? '全部已读' : `有 ${item.unread_count} 人未读` }}）
                  </span>
                </div>
              </div>

              <!-- 操作按钮 -->
              <div class="flex shrink-0 items-center gap-2">
                <button
                  v-if="item.status === 0"
                  class="rounded-full p-1.5 text-gray-400 transition-all duration-200 hover:bg-gray-100 hover:text-gray-600 dark:text-gray-500 dark:hover:bg-gray-700 dark:hover:text-gray-300"
                  title="标记为已读"
                  @click="markAsRead($event, item)"
                >
                  <CheckCircle2 class="h-5 w-5" />
                </button>
                <ChevronRight
                  class="h-5 w-5 text-gray-300 transition-all duration-200 group-hover:text-gray-400 dark:text-gray-600 dark:group-hover:text-gray-500"
                />
              </div>
            </div>

            <!-- 未读指示器 -->
            <div
              v-if="item.status === 0"
              :class="[typeColors[item.type]]"
              class="absolute bottom-0 left-0 top-0 w-1"
            ></div>
          </li>
        </ul>

        <!-- 分页控件 -->
        <div
          v-if="totalPages > 1"
          class="dark:bg-gray-750 flex items-center justify-between border-t border-gray-200 bg-gray-50 px-4 py-3 sm:px-6 dark:border-gray-700"
        >
          <div class="flex flex-1 justify-between sm:hidden">
            <button
              :class="[
                currentPage === 1
                  ? 'text-gray-300 dark:text-gray-600'
                  : 'text-gray-700 hover:bg-gray-50 dark:text-gray-300 dark:hover:bg-gray-700',
              ]"
              :disabled="currentPage === 1"
              class="relative inline-flex items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium transition-colors dark:border-gray-600 dark:bg-gray-800"
              @click="goToPage(currentPage - 1)"
            >
              上一页
            </button>
            <button
              :class="[
                currentPage === totalPages
                  ? 'text-gray-300 dark:text-gray-600'
                  : 'text-gray-700 hover:bg-gray-50 dark:text-gray-300 dark:hover:bg-gray-700',
              ]"
              :disabled="currentPage === totalPages"
              class="relative ml-3 inline-flex items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium transition-colors dark:border-gray-600 dark:bg-gray-800"
              @click="goToPage(currentPage + 1)"
            >
              下一页
            </button>
          </div>
          <div
            class="hidden sm:flex sm:flex-1 sm:items-center sm:justify-between"
          >
            <div>
              <p class="text-sm text-gray-700 dark:text-gray-300">
                显示第
                <span class="font-medium">{{
                  (currentPage - 1) * pageSize + 1
                }}</span>
                至
                <span class="font-medium">{{
                  Math.min(currentPage * pageSize, total)
                }}</span>
                条， 共
                <span class="font-medium">{{ total }}</span>
                条
              </p>
            </div>
            <div>
              <nav
                aria-label="Pagination"
                class="isolate inline-flex -space-x-px rounded-md shadow-sm"
              >
                <button
                  :class="
                    currentPage === 1
                      ? 'cursor-not-allowed'
                      : 'hover:text-gray-500 dark:hover:text-gray-300'
                  "
                  :disabled="currentPage === 1"
                  class="relative inline-flex items-center rounded-l-md px-2 py-2 text-gray-400 ring-1 ring-inset ring-gray-300 transition-colors hover:bg-gray-50 focus:z-20 focus:outline-offset-0 dark:text-gray-500 dark:ring-gray-600 dark:hover:bg-gray-700"
                  @click="goToPage(currentPage - 1)"
                >
                  <span class="sr-only">上一页</span>
                  <ChevronLeft class="h-5 w-5" />
                </button>

                <!-- 页码按钮 -->
                <template v-for="page in totalPages" :key="page">
                  <button
                    v-if="
                      page === currentPage ||
                      page === 1 ||
                      page === totalPages ||
                      (page >= currentPage - 1 && page <= currentPage + 1)
                    "
                    :class="[
                      page === currentPage
                        ? 'z-10 bg-sky-500 text-white focus:z-20 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-sky-500 dark:bg-sky-600 dark:focus-visible:outline-sky-400'
                        : 'text-gray-900 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-20 focus:outline-offset-0 dark:text-gray-200 dark:ring-gray-600 dark:hover:bg-gray-700',
                    ]"
                    class="relative inline-flex items-center px-4 py-2 text-sm font-semibold transition-colors"
                    @click="goToPage(page)"
                  >
                    {{ page }}
                  </button>

                  <!-- 省略号 -->
                  <span
                    v-else-if="
                      (page === 2 && currentPage > 3) ||
                      (page === totalPages - 1 && currentPage < totalPages - 2)
                    "
                    class="relative inline-flex items-center px-4 py-2 text-sm font-semibold text-gray-700 ring-1 ring-inset ring-gray-300 dark:text-gray-300 dark:ring-gray-600"
                  >
                    ...
                  </span>
                </template>

                <button
                  :class="
                    currentPage === totalPages
                      ? 'cursor-not-allowed'
                      : 'hover:text-gray-500 dark:hover:text-gray-300'
                  "
                  :disabled="currentPage === totalPages"
                  class="relative inline-flex items-center rounded-r-md px-2 py-2 text-gray-400 ring-1 ring-inset ring-gray-300 transition-colors hover:bg-gray-50 focus:z-20 focus:outline-offset-0 dark:text-gray-500 dark:ring-gray-600 dark:hover:bg-gray-700"
                  @click="goToPage(currentPage + 1)"
                >
                  <span class="sr-only">下一页</span>
                  <ChevronRight class="h-5 w-5" />
                </button>
              </nav>
            </div>
          </div>
        </div>
      </div>
    </div>
  </Page>
</template>

<style scoped>
.line-clamp-1 {
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* 平滑过渡效果 */
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.3s ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}

/* 微妙的悬停动画 */
@keyframes pulse {
  0% {
    box-shadow: 0 0 0 0 rgba(var(--color-primary-rgb), 0.2);
  }
  70% {
    box-shadow: 0 0 0 6px rgba(var(--color-primary-rgb), 0);
  }
  100% {
    box-shadow: 0 0 0 0 rgba(var(--color-primary-rgb), 0);
  }
}

.group:hover .pulse-on-hover {
  animation: pulse 1.5s infinite;
}

/* 暗黑模式下的自定义灰色 */
.dark .bg-gray-750 {
  background-color: #1a202c; /* 介于gray-800和gray-900之间 */
}

.dark .bg-gray-650 {
  background-color: #2d3748; /* 介于gray-600和gray-700之间 */
}
</style>
