<template>
  <div class="activity-page">
    <PageHeader
      title="Activity Log"
      subtitle="Your activity and milestones in the Guild"
    />

    <SidebarLayout :limit="5">
      <ClientOnly>
        <!-- Loading State -->
        <div v-if="loading && !entries.length" class="state-box">
          <div class="spinner"></div>
          <p class="state-text">Loading activity...</p>
        </div>

        <!-- Timeline -->
        <div v-else-if="entries.length" class="timeline-wrap">
          <div class="timeline">
            <div v-for="entry in entries" :key="entry._id" class="tl-item">
              <div class="tl-dot">
                <UIcon :name="getActivity(entry).icon" class="tl-icon" />
              </div>
              <div class="tl-time">{{ formatDate(entry.timestamp) }}</div>
              <div class="tl-text">
                <template v-if="getActivity(entry).link">
                  <span>{{ getActivity(entry).text.split(getActivity(entry).linkText)[0] }}</span>
                  <NuxtLink :to="getActivity(entry).link" class="tl-link">{{ getActivity(entry).linkText }}</NuxtLink>
                </template>
                <span v-else>{{ getActivity(entry).text }}</span>
                <span v-if="entry.performedBy" class="tl-admin-badge">admin</span>
              </div>

              <!-- Email body expandable -->
              <div v-if="entry.type === 'email_sent' && getActivity(entry).emailBody" class="tl-email">
                <button class="tl-email-toggle" @click="toggleEmail(entry._id)">
                  {{ expandedEmails[entry._id] ? 'Hide email' : 'View email' }}
                </button>
                <div v-if="expandedEmails[entry._id]" class="dashed-box tl-email-body">
                  <pre>{{ getActivity(entry).emailBody }}</pre>
                </div>
              </div>
            </div>
          </div>

          <!-- Load More -->
          <div v-if="hasMore" class="load-more">
            <button class="btn" :disabled="loadingMore" @click="loadMore">
              {{ loadingMore ? 'Loading...' : 'Load More' }}
            </button>
          </div>
        </div>

        <!-- Empty State -->
        <div v-else class="state-box">
          <div class="state-icon">
            <UIcon name="i-lucide-activity" />
          </div>
          <h2 class="state-heading">No activity yet</h2>
          <p class="state-text">Your activity will appear here as you use the Guild</p>
        </div>

        <template #fallback>
          <div class="state-box">
            <div class="spinner"></div>
            <p class="state-text">Loading activity...</p>
          </div>
        </template>
      </ClientOnly>
    </SidebarLayout>
  </div>
</template>

<script setup>
import { formatActivity } from '~/utils/activityText'

const entries = ref([])
const loading = ref(false)
const loadingMore = ref(false)
const hasMore = ref(false)
const nextCursor = ref(null)
const expandedEmails = ref({})

const getActivity = (entry) => formatActivity(entry)

const toggleEmail = (id) => {
  expandedEmails.value[id] = !expandedEmails.value[id]
}

const formatDate = (date) => {
  const now = new Date()
  const d = new Date(date)
  const diffInSeconds = Math.floor((now - d) / 1000)

  if (diffInSeconds < 60) return 'just now'
  if (diffInSeconds < 3600) return `${Math.floor(diffInSeconds / 60)} minutes ago`
  if (diffInSeconds < 86400) return `${Math.floor(diffInSeconds / 3600)} hours ago`
  if (diffInSeconds < 604800) return `${Math.floor(diffInSeconds / 86400)} days ago`

  return d.toLocaleDateString('en-US', {
    month: 'short',
    day: 'numeric',
    year: d.getFullYear() !== now.getFullYear() ? 'numeric' : undefined
  })
}

const loadEntries = async () => {
  loading.value = true
  try {
    const data = await $fetch('/api/members/me/activity', {
      params: { limit: 20 }
    })
    entries.value = data.entries
    hasMore.value = data.hasMore
    nextCursor.value = data.nextCursor
  } catch (err) {
    console.error('Failed to load activity:', err)
  } finally {
    loading.value = false
  }
}

const loadMore = async () => {
  if (!nextCursor.value) return
  loadingMore.value = true
  try {
    const data = await $fetch('/api/members/me/activity', {
      params: { limit: 20, before: nextCursor.value }
    })
    entries.value.push(...data.entries)
    hasMore.value = data.hasMore
    nextCursor.value = data.nextCursor
  } catch (err) {
    console.error('Failed to load more activity:', err)
  } finally {
    loadingMore.value = false
  }
}

onMounted(loadEntries)

useHead({ title: 'Activity Log - Ghost Guild' })
</script>

<style scoped>
.activity-page {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

/* ---- STATE BOXES ---- */
.state-box {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 64px 32px;
  text-align: center;
}

.state-icon {
  width: 48px;
  height: 48px;
  border: 1px dashed var(--border);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 16px;
  color: var(--text-faint);
  font-size: 20px;
}

.state-heading {
  font-family: 'Brygada 1918', serif;
  font-size: 18px;
  font-weight: 600;
  color: var(--text-bright);
  margin-bottom: 6px;
}

.state-text {
  font-size: 12px;
  color: var(--text-dim);
  margin-bottom: 20px;
  max-width: 320px;
}

.spinner {
  width: 20px;
  height: 20px;
  border: 2px dashed var(--candle);
  border-top-color: transparent;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
  margin-bottom: 12px;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

/* ---- TIMELINE ---- */
.timeline-wrap {
  padding: 24px 32px 48px;
}

.timeline {
  position: relative;
  padding-left: 32px;
}

.timeline::before {
  content: '';
  position: absolute;
  left: 11px;
  top: 0;
  bottom: 0;
  width: 1px;
  border-left: 1px dashed var(--border);
}

.tl-item {
  position: relative;
  padding: 0 0 24px;
}

.tl-item:last-child {
  padding-bottom: 0;
}

.tl-dot {
  position: absolute;
  left: -32px;
  top: 2px;
  width: 22px;
  height: 22px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg);
  border: 1px dashed var(--border);
  font-size: 12px;
  color: var(--text-dim);
}

.tl-icon {
  width: 12px;
  height: 12px;
}

.tl-time {
  font-size: 11px;
  color: var(--text-faint);
  margin-bottom: 2px;
}

.tl-text {
  font-size: 13px;
  color: var(--text);
  line-height: 1.5;
  display: flex;
  align-items: baseline;
  gap: 4px;
  flex-wrap: wrap;
}

.tl-link {
  color: var(--candle);
  text-decoration: none;
  font-weight: 500;
}

.tl-link:hover {
  text-decoration: underline;
}

.tl-admin-badge {
  font-size: 10px;
  color: var(--text-faint);
  border: 1px dashed var(--border);
  padding: 1px 5px;
  margin-left: 4px;
}

/* ---- EMAIL EXPANDABLE ---- */
.tl-email {
  margin-top: 4px;
}

.tl-email-toggle {
  font-family: 'Commit Mono', monospace;
  font-size: 11px;
  color: var(--text-faint);
  background: none;
  border: none;
  cursor: pointer;
  padding: 0;
  transition: color 0.15s;
}

.tl-email-toggle:hover {
  color: var(--candle);
}

.tl-email-body {
  margin-top: 6px;
  padding: 12px;
  font-size: 12px;
  color: var(--text-dim);
  line-height: 1.6;
  max-height: 300px;
  overflow-y: auto;
}

.tl-email-body pre {
  white-space: pre-wrap;
  word-break: break-word;
  font-family: 'Commit Mono', monospace;
  font-size: 12px;
  margin: 0;
}

/* ---- LOAD MORE ---- */
.load-more {
  display: flex;
  justify-content: center;
  padding-top: 8px;
}

/* ---- RESPONSIVE ---- */
@media (max-width: 768px) {
  .timeline-wrap {
    padding: 20px 20px 40px;
  }

  .state-box {
    padding: 48px 20px;
  }
}
</style>
