<template>
  <div class="p-6">
    <div class="mb-6 flex flex-col gap-2 sm:flex-row sm:items-end sm:justify-between">
      <div>
        <p class="text-sm" :class="[mutedTextClass]">FileCodeBox Admin</p>
        <h2 class="text-2xl font-bold" :class="[primaryTextClass]">
          {{ t('admin.dashboard.title') }}
        </h2>
        <p class="mt-1 text-xs" :class="[mutedTextClass]">
          {{ t('admin.dashboard.lastUpdated', { time: lastUpdatedText }) }}
        </p>
      </div>
      <button
        type="button"
        :disabled="isLoading"
        @click="fetchDashboardData"
        class="inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-70"
        :class="[
          isDarkMode
            ? 'bg-gray-800 text-gray-200 hover:bg-gray-700'
            : 'bg-white text-gray-700 shadow-sm hover:bg-gray-50'
        ]"
      >
        <RefreshCwIcon class="mr-2 h-4 w-4" :class="{ 'animate-spin': isLoading }" />
        {{ isLoading ? t('admin.dashboard.refreshing') : t('admin.dashboard.refresh') }}
      </button>
    </div>

    <div
      v-if="errorMessage"
      class="mb-6 rounded-lg border px-4 py-3 text-sm"
      :class="[
        isDarkMode
          ? 'border-red-900/50 bg-red-950/30 text-red-200'
          : 'border-red-200 bg-red-50 text-red-700'
      ]"
    >
      {{ errorMessage }}
    </div>

    <div class="grid grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-4">
      <StatCard
        :title="t('admin.dashboard.totalFiles')"
        :value="dashboardData.totalFiles"
        :icon="FilesIcon"
        icon-color="indigo"
      >
        <template #description>
          {{ t('admin.dashboard.yesterdayShares', { count: dashboardData.yesterdayCount }) }}
        </template>
      </StatCard>

      <StatCard
        :title="t('admin.dashboard.storageSpace')"
        :value="dashboardData.storageUsedText"
        :icon="HardDriveIcon"
        icon-color="purple"
      >
        <template #description>
          {{ t('admin.dashboard.todayIncrease', { count: dashboardData.todaySizeText }) }}
        </template>
      </StatCard>

      <StatCard
        :title="t('admin.dashboard.todayShares')"
        :value="dashboardData.todayCount"
        :icon="UploadCloudIcon"
        icon-color="green"
      >
        <template #description>
          {{ t('admin.dashboard.yesterdayShares', { count: dashboardData.yesterdayCount }) }}
        </template>
      </StatCard>

      <StatCard
        :title="t('admin.dashboard.totalRetrievals')"
        :value="dashboardData.usedCount"
        :icon="DownloadCloudIcon"
        icon-color="blue"
      >
        <template #description>
          {{ t('admin.dashboard.serverUptime') }} {{ dashboardData.sysUptimeText }}
        </template>
      </StatCard>
    </div>

    <div v-if="dashboardData.hasExtendedStats" class="mt-6 grid grid-cols-1 gap-6 xl:grid-cols-3">
      <section class="xl:col-span-2 rounded-lg p-5 shadow-sm" :class="[panelClass]">
        <div class="mb-5 flex items-center justify-between">
          <div>
            <h3 class="text-lg font-semibold" :class="[primaryTextClass]">
              {{ t('admin.dashboard.fileHealth') }}
            </h3>
            <p class="text-sm" :class="[mutedTextClass]">
              {{ t('admin.dashboard.fileHealthDesc') }}
            </p>
          </div>
          <ActivityIcon
            class="h-5 w-5"
            :class="[isDarkMode ? 'text-indigo-300' : 'text-indigo-500']"
          />
        </div>

        <div class="grid grid-cols-1 gap-4 md:grid-cols-3">
          <MetricProgress
            :label="t('admin.dashboard.activeFileRatio')"
            :value="dashboardData.activeRatio"
            :detail="`${dashboardData.activeCount} / ${dashboardData.totalFiles}`"
            tone="green"
          />
          <MetricProgress
            :label="t('admin.dashboard.fileShareRatio')"
            :value="dashboardData.fileRatio"
            :detail="t('admin.dashboard.binaryFiles', { count: dashboardData.fileCount })"
            tone="indigo"
          />
          <MetricProgress
            :label="t('admin.dashboard.textShareRatio')"
            :value="dashboardData.textRatio"
            :detail="t('admin.dashboard.textShares', { count: dashboardData.textCount })"
            tone="purple"
          />
        </div>

        <div class="mt-6 grid grid-cols-1 gap-3 md:grid-cols-2 xl:grid-cols-5">
          <button
            v-for="action in healthActions"
            :key="action.key"
            type="button"
            class="group flex min-h-28 flex-col justify-between rounded-lg border p-4 text-left transition-colors"
            :class="getHealthActionClass(action.tone)"
            @click="openHealthQueue(action.health)"
          >
            <span class="flex items-start justify-between gap-3">
              <span>
                <span class="block text-2xl font-semibold">{{ action.count }}</span>
                <span class="mt-1 block text-sm font-medium">{{ action.label }}</span>
              </span>
              <component :is="getHealthActionIcon(action.tone)" class="h-5 w-5 shrink-0" />
            </span>
            <span class="mt-3 flex items-center justify-between gap-2 text-xs">
              <span class="line-clamp-2">{{ action.description }}</span>
              <ArrowRightIcon
                class="h-4 w-4 shrink-0 transition-transform group-hover:translate-x-0.5"
              />
            </span>
          </button>
        </div>

        <div class="mt-6 grid grid-cols-1 gap-4 md:grid-cols-2">
          <div class="rounded-lg border p-4" :class="[subtlePanelClass]">
            <p class="text-sm" :class="[mutedTextClass]">
              {{ t('admin.dashboard.expiredFiles') }}
            </p>
            <div class="mt-2 flex items-end justify-between">
              <strong class="text-3xl" :class="[primaryTextClass]">
                {{ dashboardData.expiredCount }}
              </strong>
              <span class="text-sm" :class="[mutedTextClass]">
                {{ t('admin.dashboard.needCleanup') }}
              </span>
            </div>
          </div>

          <div class="rounded-lg border p-4" :class="[subtlePanelClass]">
            <p class="text-sm" :class="[mutedTextClass]">
              {{ t('admin.dashboard.chunkedFiles') }}
            </p>
            <div class="mt-2 flex items-end justify-between">
              <strong class="text-3xl" :class="[primaryTextClass]">
                {{ dashboardData.chunkedCount }}
              </strong>
              <span class="text-sm" :class="[mutedTextClass]">
                {{ dashboardData.enableChunk ? t('common.enabled') : t('common.disabled') }}
              </span>
            </div>
          </div>
        </div>
      </section>

      <section class="rounded-lg p-5 shadow-sm" :class="[panelClass]">
        <div class="mb-5">
          <h3 class="text-lg font-semibold" :class="[primaryTextClass]">
            {{ t('admin.dashboard.storagePolicy') }}
          </h3>
          <p class="text-sm" :class="[mutedTextClass]">
            {{ t('admin.dashboard.storagePolicyDesc') }}
          </p>
        </div>

        <div class="space-y-4">
          <PolicyRow
            :label="t('admin.dashboard.storageBackend')"
            :value="dashboardData.storageBackend"
          />
          <PolicyRow
            :label="t('admin.dashboard.singleFileLimit')"
            :value="dashboardData.uploadSizeLimitText"
          />
          <PolicyRow
            :label="t('admin.dashboard.guestUpload')"
            :value="dashboardData.openUpload ? t('common.enabled') : t('common.disabled')"
          />
          <PolicyRow :label="t('admin.dashboard.maxSaveTime')" :value="maxSaveTimeText" />
        </div>

        <div class="mt-5">
          <div class="mb-2 flex items-center justify-between text-sm">
            <span :class="[mutedTextClass]">{{ t('admin.dashboard.todayCapacityReference') }}</span>
            <span :class="[primaryTextClass]">{{ dashboardData.todaySizeRatio }}%</span>
          </div>
          <div
            class="h-2 overflow-hidden rounded-full"
            :class="[isDarkMode ? 'bg-gray-700' : 'bg-gray-100']"
          >
            <div
              class="h-full rounded-full bg-indigo-500"
              :style="{ width: `${dashboardData.todaySizeRatio}%` }"
            ></div>
          </div>
        </div>
      </section>
    </div>

    <div v-if="dashboardData.hasExtendedStats" class="mt-6 grid grid-cols-1 gap-6 xl:grid-cols-4">
      <section class="rounded-lg p-5 shadow-sm" :class="[panelClass]">
        <h3 class="text-lg font-semibold" :class="[primaryTextClass]">
          {{ t('admin.dashboard.fileTypeDistribution') }}
        </h3>
        <div class="mt-4 space-y-3">
          <div
            v-if="dashboardData.topSuffixes.length === 0"
            class="text-sm"
            :class="[mutedTextClass]"
          >
            {{ t('common.noData') }}
          </div>
          <div v-for="item in dashboardData.topSuffixes" :key="item.suffix" class="space-y-1">
            <div class="flex items-center justify-between text-sm">
              <span :class="[primaryTextClass]">{{
                item.suffix || t('admin.dashboard.textType')
              }}</span>
              <span :class="[mutedTextClass]">{{ item.count }}</span>
            </div>
            <div
              class="h-2 overflow-hidden rounded-full"
              :class="[isDarkMode ? 'bg-gray-700' : 'bg-gray-100']"
            >
              <div
                class="h-full rounded-full bg-purple-500"
                :style="{ width: `${getSuffixRatio(item.count)}%` }"
              ></div>
            </div>
          </div>
        </div>
      </section>

      <section class="rounded-lg p-5 shadow-sm" :class="[panelClass]">
        <div class="mb-4 flex items-start justify-between gap-3">
          <div>
            <h3 class="text-lg font-semibold" :class="[primaryTextClass]">
              {{ t('admin.dashboard.recentActivities') }}
            </h3>
            <p class="text-sm" :class="[mutedTextClass]">
              {{ t('admin.dashboard.recentActivitiesDesc') }}
            </p>
          </div>
          <button
            type="button"
            class="inline-flex shrink-0 items-center gap-1.5 rounded-lg px-2.5 py-1.5 text-xs font-medium transition-colors"
            :class="[
              isDarkMode
                ? 'bg-gray-900 text-indigo-200 hover:bg-gray-700'
                : 'bg-indigo-50 text-indigo-700 hover:bg-indigo-100'
            ]"
            @click="handleOpenActivityTimeline"
          >
            <HistoryIcon class="h-4 w-4" />
            {{ t('admin.dashboard.viewAllActivities') }}
          </button>
        </div>

        <div
          v-if="dashboardData.recentActivities.length === 0"
          class="rounded-lg border px-4 py-6 text-center text-sm"
          :class="[subtlePanelClass, mutedTextClass]"
        >
          {{ t('admin.dashboard.noActivities') }}
        </div>
        <div v-else class="space-y-3">
          <div
            v-for="activity in dashboardData.recentActivities"
            :key="activity.id"
            class="rounded-lg border px-3 py-3"
            :class="[subtlePanelClass]"
          >
            <div class="flex items-start gap-3">
              <span
                class="mt-0.5 inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-lg"
                :class="getActivityIconClass(activity.action)"
              >
                <component :is="getActivityIcon(activity.action)" class="h-4 w-4" />
              </span>
              <div class="min-w-0 flex-1">
                <p class="text-sm font-medium" :class="[primaryTextClass]">
                  {{ getActivityTitle(activity.action) }}
                </p>
                <p class="mt-1 truncate text-xs" :class="[mutedTextClass]">
                  {{ getActivityDescription(activity) }}
                </p>
                <p class="mt-2 text-xs" :class="[mutedTextClass]">
                  {{ formatCreatedAt(activity.createdAtValue) }}
                </p>
              </div>
            </div>
          </div>
        </div>
      </section>

      <section class="xl:col-span-2 rounded-lg p-5 shadow-sm" :class="[panelClass]">
        <div class="mb-4 flex items-center justify-between">
          <div>
            <h3 class="text-lg font-semibold" :class="[primaryTextClass]">
              {{ t('admin.dashboard.recentFiles') }}
            </h3>
            <p class="text-sm" :class="[mutedTextClass]">
              {{ t('admin.dashboard.recentFilesDesc') }}
            </p>
          </div>
        </div>

        <div
          class="overflow-hidden rounded-lg border"
          :class="[isDarkMode ? 'border-gray-700' : 'border-gray-200']"
        >
          <table
            class="min-w-full divide-y"
            :class="[isDarkMode ? 'divide-gray-700' : 'divide-gray-200']"
          >
            <thead :class="[isDarkMode ? 'bg-gray-900/50' : 'bg-gray-50']">
              <tr>
                <th
                  class="px-4 py-3 text-left text-xs font-medium uppercase tracking-wider"
                  :class="[mutedTextClass]"
                >
                  {{ t('admin.dashboard.table.file') }}
                </th>
                <th
                  class="px-4 py-3 text-left text-xs font-medium uppercase tracking-wider"
                  :class="[mutedTextClass]"
                >
                  {{ t('admin.dashboard.table.size') }}
                </th>
                <th
                  class="px-4 py-3 text-left text-xs font-medium uppercase tracking-wider"
                  :class="[mutedTextClass]"
                >
                  {{ t('admin.dashboard.table.usage') }}
                </th>
                <th
                  class="px-4 py-3 text-left text-xs font-medium uppercase tracking-wider"
                  :class="[mutedTextClass]"
                >
                  {{ t('admin.dashboard.table.status') }}
                </th>
              </tr>
            </thead>
            <tbody class="divide-y" :class="[isDarkMode ? 'divide-gray-700' : 'divide-gray-100']">
              <tr v-if="dashboardData.recentFiles.length === 0">
                <td colspan="4" class="px-4 py-6 text-center text-sm" :class="[mutedTextClass]">
                  {{ t('common.noData') }}
                </td>
              </tr>
              <tr v-for="file in dashboardData.recentFiles" :key="file.id">
                <td class="px-4 py-3">
                  <div class="flex items-center gap-3">
                    <div
                      class="rounded-lg p-2"
                      :class="[isDarkMode ? 'bg-gray-700' : 'bg-gray-100']"
                    >
                      <FileTextIcon v-if="file.text" class="h-4 w-4" :class="[mutedTextClass]" />
                      <FileIcon v-else class="h-4 w-4" :class="[mutedTextClass]" />
                    </div>
                    <div class="min-w-0">
                      <p class="truncate text-sm font-medium" :class="[primaryTextClass]">
                        {{ file.name || file.code }}
                      </p>
                      <p class="text-xs" :class="[mutedTextClass]">
                        {{ file.code }} · {{ formatCreatedAt(file.createdAt) }}
                      </p>
                    </div>
                  </div>
                </td>
                <td class="px-4 py-3 text-sm" :class="[primaryTextClass]">
                  {{ formatFileSize(file.size) }}
                </td>
                <td class="px-4 py-3 text-sm" :class="[primaryTextClass]">
                  {{ file.usedCount }} {{ t('common.times') }}
                </td>
                <td class="px-4 py-3">
                  <span
                    class="inline-flex rounded-full px-2.5 py-1 text-xs font-medium"
                    :class="[
                      file.isExpired
                        ? isDarkMode
                          ? 'bg-red-900/40 text-red-300'
                          : 'bg-red-100 text-red-700'
                        : isDarkMode
                          ? 'bg-green-900/40 text-green-300'
                          : 'bg-green-100 text-green-700'
                    ]"
                  >
                    {{ file.isExpired ? t('common.expiredFile') : t('admin.dashboard.available') }}
                  </span>
                </td>
              </tr>
            </tbody>
          </table>
        </div>
      </section>
    </div>
  </div>

  <SideDrawer
    :visible="isActivityTimelineOpen"
    :title="t('admin.dashboard.activityTimelineTitle')"
    @close="closeActivityTimeline"
  >
    <div class="flex min-h-0 flex-1 flex-col">
      <div class="border-b p-5" :class="[isDarkMode ? 'border-gray-700' : 'border-gray-200']">
        <div class="grid grid-cols-2 gap-3">
          <div class="rounded-lg border p-3" :class="[subtlePanelClass]">
            <p class="text-xs" :class="[mutedTextClass]">
              {{ t('admin.dashboard.activityTimelineFiltered') }}
            </p>
            <strong class="mt-1 block text-2xl" :class="[primaryTextClass]">
              {{ activityTimelineTotal }}
            </strong>
          </div>
          <div class="rounded-lg border p-3" :class="[subtlePanelClass]">
            <p class="text-xs" :class="[mutedTextClass]">
              {{ t('admin.dashboard.activityTimelineStoredTotal') }}
            </p>
            <strong class="mt-1 block text-2xl" :class="[primaryTextClass]">
              {{ activityTimelineStoredTotal }}
            </strong>
          </div>
        </div>

        <form class="mt-4 space-y-3" @submit.prevent="handleApplyActivityFilters">
          <label class="block">
            <span class="mb-1 block text-xs font-medium" :class="[mutedTextClass]">
              {{ t('admin.dashboard.activityKeyword') }}
            </span>
            <span class="relative block">
              <SearchIcon
                class="pointer-events-none absolute left-3 top-2.5 h-4 w-4"
                :class="[mutedTextClass]"
              />
              <input
                v-model="activityFilters.keyword"
                type="search"
                class="w-full rounded-lg border py-2 pl-9 pr-3 text-sm outline-none transition-colors"
                :class="[
                  isDarkMode
                    ? 'border-gray-700 bg-gray-900 text-gray-100 placeholder:text-gray-500 focus:border-indigo-400'
                    : 'border-gray-200 bg-white text-gray-900 placeholder:text-gray-400 focus:border-indigo-400'
                ]"
                :placeholder="t('admin.dashboard.activityKeywordPlaceholder')"
              />
            </span>
          </label>

          <div class="grid grid-cols-1 gap-3 sm:grid-cols-2">
            <label class="block">
              <span class="mb-1 block text-xs font-medium" :class="[mutedTextClass]">
                {{ t('admin.dashboard.activityActionFilter') }}
              </span>
              <select
                v-model="activityFilters.action"
                class="w-full rounded-lg border px-3 py-2 text-sm outline-none transition-colors"
                :class="[
                  isDarkMode
                    ? 'border-gray-700 bg-gray-900 text-gray-100 focus:border-indigo-400'
                    : 'border-gray-200 bg-white text-gray-900 focus:border-indigo-400'
                ]"
              >
                <option value="">{{ t('admin.dashboard.activityAllActions') }}</option>
                <option
                  v-for="option in activityActionOptions"
                  :key="option.value"
                  :value="option.value"
                >
                  {{ getActivityTitle(option.value) }} ({{ option.count }})
                </option>
              </select>
            </label>

            <label class="block">
              <span class="mb-1 block text-xs font-medium" :class="[mutedTextClass]">
                {{ t('admin.dashboard.activityTargetTypeFilter') }}
              </span>
              <select
                v-model="activityFilters.targetType"
                class="w-full rounded-lg border px-3 py-2 text-sm outline-none transition-colors"
                :class="[
                  isDarkMode
                    ? 'border-gray-700 bg-gray-900 text-gray-100 focus:border-indigo-400'
                    : 'border-gray-200 bg-white text-gray-900 focus:border-indigo-400'
                ]"
              >
                <option value="">{{ t('admin.dashboard.activityAllTargets') }}</option>
                <option
                  v-for="option in activityTargetTypeOptions"
                  :key="option.value"
                  :value="option.value"
                >
                  {{ getActivityTargetTypeTitle(option.value) }} ({{ option.count }})
                </option>
              </select>
            </label>
          </div>

          <div class="flex flex-wrap items-center justify-between gap-2">
            <button
              type="button"
              class="inline-flex items-center gap-1.5 rounded-lg px-3 py-2 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-60"
              :class="[
                isDarkMode
                  ? 'bg-gray-800 text-gray-200 hover:bg-gray-700'
                  : 'bg-gray-100 text-gray-700 hover:bg-gray-200'
              ]"
              :disabled="!hasActivityFilters || isActivityTimelineLoading"
              @click="handleResetActivityFilters"
            >
              {{ t('admin.dashboard.activityResetFilters') }}
            </button>

            <div class="flex items-center gap-2">
              <button
                type="button"
                class="inline-flex items-center gap-1.5 rounded-lg px-3 py-2 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-60"
                :class="[
                  isDarkMode
                    ? 'bg-gray-800 text-gray-200 hover:bg-gray-700'
                    : 'bg-gray-100 text-gray-700 hover:bg-gray-200'
                ]"
                :disabled="isActivityTimelineLoading"
                @click="handleRefreshActivityTimeline"
              >
                <RefreshCwIcon
                  class="h-4 w-4"
                  :class="{ 'animate-spin': isActivityTimelineLoading }"
                />
                {{ t('admin.dashboard.activityRefresh') }}
              </button>
              <button
                type="submit"
                class="inline-flex items-center gap-1.5 rounded-lg bg-indigo-600 px-3 py-2 text-sm font-medium text-white transition-colors hover:bg-indigo-700 disabled:cursor-not-allowed disabled:opacity-60"
                :disabled="isActivityTimelineLoading"
              >
                <ListFilterIcon class="h-4 w-4" />
                {{ t('admin.dashboard.activityApplyFilters') }}
              </button>
            </div>
          </div>
        </form>
      </div>

      <div class="min-h-0 flex-1 overflow-y-auto p-5 custom-scrollbar">
        <div
          v-if="activityTimelineError"
          class="mb-4 rounded-lg border px-4 py-3 text-sm"
          :class="[
            isDarkMode
              ? 'border-red-900/50 bg-red-950/30 text-red-200'
              : 'border-red-200 bg-red-50 text-red-700'
          ]"
        >
          {{ activityTimelineError }}
        </div>

        <div
          v-if="isActivityTimelineLoading"
          class="flex items-center justify-center gap-2 rounded-lg border px-4 py-8 text-sm"
          :class="[subtlePanelClass, mutedTextClass]"
        >
          <RefreshCwIcon class="h-4 w-4 animate-spin" />
          {{ t('admin.dashboard.activityLoading') }}
        </div>

        <div
          v-else-if="activityTimeline.length === 0"
          class="rounded-lg border px-4 py-8 text-center text-sm"
          :class="[subtlePanelClass, mutedTextClass]"
        >
          {{
            hasActivityFilters
              ? t('admin.dashboard.activityNoFiltered')
              : t('admin.dashboard.noActivities')
          }}
        </div>

        <div v-else class="space-y-4">
          <div
            v-for="activity in activityTimeline"
            :key="activity.id"
            class="rounded-lg border p-4"
            :class="[subtlePanelClass]"
          >
            <div class="flex items-start gap-3">
              <span
                class="mt-0.5 inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-lg"
                :class="getActivityIconClass(activity.action)"
              >
                <component :is="getActivityIcon(activity.action)" class="h-4 w-4" />
              </span>
              <div class="min-w-0 flex-1">
                <div class="flex flex-wrap items-start justify-between gap-2">
                  <div class="min-w-0">
                    <p class="text-sm font-semibold" :class="[primaryTextClass]">
                      {{ getActivityTitle(activity.action) }}
                    </p>
                    <p class="mt-1 text-sm" :class="[mutedTextClass]">
                      {{ getActivityDescription(activity) }}
                    </p>
                  </div>
                  <span
                    class="inline-flex shrink-0 rounded-full px-2.5 py-1 text-xs font-medium"
                    :class="[isDarkMode ? 'bg-gray-800 text-gray-300' : 'bg-white text-gray-600']"
                  >
                    {{ getActivityTargetTypeTitle(activity.targetTypeValue) }}
                  </span>
                </div>
                <div
                  class="mt-3 flex flex-wrap items-center gap-2 text-xs"
                  :class="[mutedTextClass]"
                >
                  <span>{{ formatCreatedAt(activity.createdAtValue) }}</span>
                  <span v-if="activity.count > 1"
                    >· {{ activity.count }} {{ t('common.files') }}</span
                  >
                  <span v-if="activity.targetId ?? activity.target_id">
                    · ID {{ activity.targetId ?? activity.target_id }}
                  </span>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </SideDrawer>
</template>

<script setup lang="ts">
import { computed, defineComponent, h, onMounted } from 'vue'
import type { Component, PropType } from 'vue'
import { useRouter } from 'vue-router'
import {
  ActivityIcon,
  AlertTriangleIcon,
  ArrowRightIcon,
  CheckCircleIcon,
  ClockIcon,
  DownloadCloudIcon,
  FileIcon,
  FilesIcon,
  FileTextIcon,
  HardDriveIcon,
  HistoryIcon,
  ListFilterIcon,
  PencilIcon,
  RefreshCwIcon,
  SearchIcon,
  ShieldCheckIcon,
  SlidersHorizontalIcon,
  TrashIcon,
  UploadCloudIcon
} from 'lucide-vue-next'
import StatCard from '@/components/common/StatCard.vue'
import SideDrawer from '@/components/common/SideDrawer.vue'
import { useDashboardStats, useInjectedDarkMode } from '@/composables'
import { useI18n } from 'vue-i18n'
import { formatFileSize, formatTimestamp } from '@/utils/common'
import { ROUTES } from '@/constants'
import type { DashboardActivityViewItem, DashboardHealthAction } from '@/types'

const isDarkMode = useInjectedDarkMode()
const { t } = useI18n()
const router = useRouter()
const {
  activityActionOptions,
  activityFilters,
  activityTargetTypeOptions,
  activityTimeline,
  activityTimelineError,
  activityTimelineStoredTotal,
  activityTimelineTotal,
  applyActivityFilters,
  closeActivityTimeline,
  dashboardData,
  errorMessage,
  fetchActivityTimeline,
  fetchDashboardData,
  hasActivityFilters,
  isActivityTimelineLoading,
  isActivityTimelineOpen,
  isLoading,
  lastUpdatedText,
  openActivityTimeline,
  resetActivityFilters
} = useDashboardStats({
  activityLoadFailedMessage: t('admin.dashboard.activityLoadFailed'),
  loadFailedMessage: t('admin.dashboard.loadFailed')
})

const handleOpenActivityTimeline = () => {
  void openActivityTimeline()
}

const handleApplyActivityFilters = () => {
  void applyActivityFilters()
}

const handleResetActivityFilters = () => {
  void resetActivityFilters()
}

const handleRefreshActivityTimeline = () => {
  void fetchActivityTimeline()
}

const primaryTextClass = computed(() => (isDarkMode.value ? 'text-white' : 'text-gray-900'))
const mutedTextClass = computed(() => (isDarkMode.value ? 'text-gray-400' : 'text-gray-500'))
const panelClass = computed(() =>
  isDarkMode.value ? 'bg-gray-800/80 border border-gray-700' : 'bg-white border border-gray-100'
)
const subtlePanelClass = computed(() =>
  isDarkMode.value ? 'border-gray-700 bg-gray-900/30' : 'border-gray-100 bg-gray-50'
)
const maxSuffixCount = computed(() =>
  Math.max(...dashboardData.topSuffixes.map((item) => item.count), 1)
)
const maxSaveTimeText = computed(() => {
  if (!dashboardData.maxSaveSeconds) return t('admin.dashboard.noSaveLimit')
  const days = Math.floor(dashboardData.maxSaveSeconds / 86400)
  if (days >= 1) return `${days}${t('common.day')}`
  const hours = Math.floor(dashboardData.maxSaveSeconds / 3600)
  if (hours >= 1) return `${hours}${t('common.hour')}`
  return `${Math.floor(dashboardData.maxSaveSeconds / 60)}${t('common.minute')}`
})

const healthActions = computed<DashboardHealthAction[]>(() => [
  {
    key: 'attention',
    label: t('admin.dashboard.healthActions.attention.title'),
    description: t('admin.dashboard.healthActions.attention.description'),
    count: dashboardData.healthAttentionCount,
    health: 'attention',
    tone: dashboardData.healthAttentionCount > 0 ? 'danger' : 'success'
  },
  {
    key: 'storageIssue',
    label: t('admin.dashboard.healthActions.storageIssue.title'),
    description: t('admin.dashboard.healthActions.storageIssue.description'),
    count: dashboardData.storageIssueCount,
    health: 'storage_issue',
    tone: dashboardData.storageIssueCount > 0 ? 'danger' : 'success'
  },
  {
    key: 'expiringSoon',
    label: t('admin.dashboard.healthActions.expiringSoon.title'),
    description: t('admin.dashboard.healthActions.expiringSoon.description'),
    count: dashboardData.expiringSoonCount,
    health: 'expiring_soon',
    tone: dashboardData.expiringSoonCount > 0 ? 'warning' : 'success'
  },
  {
    key: 'neverRetrieved',
    label: t('admin.dashboard.healthActions.neverRetrieved.title'),
    description: t('admin.dashboard.healthActions.neverRetrieved.description'),
    count: dashboardData.neverRetrievedCount,
    health: 'never_retrieved',
    tone: dashboardData.neverRetrievedCount > 0 ? 'neutral' : 'success'
  },
  {
    key: 'permanent',
    label: t('admin.dashboard.healthActions.permanent.title'),
    description: t('admin.dashboard.healthActions.permanent.description'),
    count: dashboardData.permanentCount,
    health: 'permanent',
    tone: 'success'
  }
])

const getSuffixRatio = (count: number) => Math.round((count / maxSuffixCount.value) * 100)

const formatCreatedAt = (value: string | null) => {
  if (!value) return '-'
  return formatTimestamp(value, 'datetime')
}

type ActivityTone = 'danger' | 'warning' | 'success' | 'neutral'

const activityIconMap: Record<string, Component> = {
  'file.delete': TrashIcon,
  'files.batch_delete': TrashIcon,
  'file.update': PencilIcon,
  'files.batch_update': PencilIcon,
  'file.policy_action': ClockIcon,
  'files.batch_policy_action': ClockIcon,
  'file.metadata_update': FileTextIcon,
  'file.view_preset_create': SlidersHorizontalIcon,
  'file.view_preset_update': SlidersHorizontalIcon,
  'file.view_preset_delete': SlidersHorizontalIcon,
  'config.update': SlidersHorizontalIcon,
  'local_file.delete': TrashIcon,
  'local_file.share': UploadCloudIcon
}

const getActivityIcon = (action: string) => activityIconMap[action] || HistoryIcon

const getActivityTone = (action: string): ActivityTone => {
  if (action.includes('delete')) return 'danger'
  if (action.includes('policy') || action.includes('update')) return 'warning'
  if (action.includes('share') || action.includes('create')) return 'success'
  return 'neutral'
}

const getActivityIconClass = (action: string) => {
  const tone = getActivityTone(action)
  const darkClasses: Record<ActivityTone, string> = {
    danger: 'bg-red-500/10 text-red-300',
    warning: 'bg-amber-500/10 text-amber-300',
    success: 'bg-emerald-500/10 text-emerald-300',
    neutral: 'bg-gray-700 text-gray-300'
  }
  const lightClasses: Record<ActivityTone, string> = {
    danger: 'bg-red-50 text-red-700',
    warning: 'bg-amber-50 text-amber-700',
    success: 'bg-emerald-50 text-emerald-700',
    neutral: 'bg-gray-100 text-gray-700'
  }

  return isDarkMode.value ? darkClasses[tone] : lightClasses[tone]
}

const getActivityTitle = (action: string) => {
  const key = `admin.dashboard.activityActions.${action}`
  const title = t(key)
  return title === key ? action : title
}

const getActivityTargetTypeTitle = (targetType: string) => {
  const key = `admin.dashboard.activityTargetTypes.${targetType}`
  const title = t(key)
  return title === key ? targetType : title
}

const getActivityDescription = (activity: DashboardActivityViewItem) => {
  const targetName = activity.targetNameValue || t('admin.dashboard.activityUnknownTarget')
  if (activity.count > 1) {
    return t('admin.dashboard.activityBatchDescription', {
      target: targetName,
      count: activity.count
    })
  }

  return t('admin.dashboard.activityDescription', {
    target: targetName
  })
}

const healthActionIconMap: Record<DashboardHealthAction['tone'], Component> = {
  danger: AlertTriangleIcon,
  warning: AlertTriangleIcon,
  success: CheckCircleIcon,
  neutral: ShieldCheckIcon
}

const getHealthActionIcon = (tone: DashboardHealthAction['tone']) => healthActionIconMap[tone]

const getHealthActionClass = (tone: DashboardHealthAction['tone']) => {
  const darkClasses: Record<DashboardHealthAction['tone'], string> = {
    danger: 'border-red-500/20 bg-red-500/10 text-red-200 hover:border-red-400/40',
    warning: 'border-amber-500/20 bg-amber-500/10 text-amber-200 hover:border-amber-400/40',
    success: 'border-emerald-500/20 bg-emerald-500/10 text-emerald-200 hover:border-emerald-400/40',
    neutral: 'border-gray-700 bg-gray-900/30 text-gray-300 hover:border-gray-600'
  }
  const lightClasses: Record<DashboardHealthAction['tone'], string> = {
    danger: 'border-red-100 bg-red-50 text-red-700 hover:border-red-200',
    warning: 'border-amber-100 bg-amber-50 text-amber-700 hover:border-amber-200',
    success: 'border-emerald-100 bg-emerald-50 text-emerald-700 hover:border-emerald-200',
    neutral: 'border-gray-100 bg-gray-50 text-gray-700 hover:border-gray-200'
  }

  return isDarkMode.value ? darkClasses[tone] : lightClasses[tone]
}

const openHealthQueue = (health: DashboardHealthAction['health']) => {
  void router.push({
    path: ROUTES.FILE_MANAGE,
    query: { health }
  })
}

const MetricProgress = defineComponent({
  name: 'MetricProgress',
  props: {
    label: { type: String, required: true },
    value: { type: Number, required: true },
    detail: { type: String, required: true },
    tone: {
      type: String as PropType<'green' | 'indigo' | 'purple'>,
      required: true
    }
  },
  setup(props) {
    const toneClass = computed(() => {
      const classes = {
        green: 'bg-green-500',
        indigo: 'bg-indigo-500',
        purple: 'bg-purple-500'
      }
      return classes[props.tone]
    })

    return () =>
      h('div', { class: 'rounded-lg border p-4 border-gray-200/60 dark:border-gray-700' }, [
        h('div', { class: 'mb-2 flex items-center justify-between text-sm' }, [
          h('span', { class: 'text-gray-500 dark:text-gray-400' }, props.label),
          h('span', { class: 'font-medium text-gray-900 dark:text-white' }, `${props.value}%`)
        ]),
        h('div', { class: 'h-2 overflow-hidden rounded-full bg-gray-100 dark:bg-gray-700' }, [
          h('div', {
            class: ['h-full rounded-full', toneClass.value],
            style: { width: `${props.value}%` }
          })
        ]),
        h('p', { class: 'mt-2 text-sm text-gray-500 dark:text-gray-400' }, props.detail)
      ])
  }
})

const PolicyRow = defineComponent({
  name: 'PolicyRow',
  props: {
    label: { type: String, required: true },
    value: { type: String, required: true }
  },
  setup(props) {
    return () =>
      h(
        'div',
        {
          class:
            'flex items-center justify-between gap-4 border-b border-gray-200/60 pb-3 last:border-b-0 dark:border-gray-700'
        },
        [
          h('span', { class: 'text-sm text-gray-500 dark:text-gray-400' }, props.label),
          h('span', { class: 'text-sm font-medium text-gray-900 dark:text-white' }, props.value)
        ]
      )
  }
})

onMounted(() => {
  void fetchDashboardData()
})
</script>
