<template>
    <div class="activity-feed">
        <!-- Feed Header -->
        <div class="feed-header">
            <div class="header-content">
                <h2 class="feed-title">Recent Activity</h2>
                <div class="header-stats">
                    <span v-if="!store.isLoading" class="activity-count">
                        {{ totalActivitiesText }}
                    </span>
                </div>
            </div>
            <div class="header-actions">
                <button v-if="store.activities.length > 0" class="view-all-btn" @click="handleViewAll"
                    aria-label="View all activities">
                    <span class="material-icons">open_in_new</span>
                </button>
            </div>
        </div>

        <!-- Feed Content -->
        <div class="feed-content">
            <!-- Loading State -->
            <div v-if="store.isLoading && store.activities.length === 0" class="feed-loading">
                <div class="loading-content">
                    <div class="loading-spinner">
                        <svg class="animate-spin h-6 w-6 text-primary-500" fill="none" viewBox="0 0 24 24">
                            <circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4" class="opacity-25">
                            </circle>
                            <path fill="currentColor"
                                d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
                                class="opacity-75"></path>
                        </svg>
                    </div>
                    <p class="loading-text">Loading recent activity...</p>
                </div>
            </div>

            <!-- Error State -->
            <div v-else-if="store.error" class="feed-error">
                <div class="error-content">
                    <span class="material-icons error-icon">error_outline</span>
                    <p class="error-message">{{ store.error }}</p>
                    <button class="retry-btn" @click="handleRetry">
                        Try Again
                    </button>
                </div>
            </div>

            <!-- Activity Groups -->
            <div v-else-if="activityGroups.length > 0" class="activity-groups">
                <div v-for="group in activityGroups" :key="group.key" class="activity-group"
                    :class="{ 'new-group': group.isNew }">
                    <!-- Group Header -->
                    <div class="group-header">
                        <time class="group-time">{{ group.timeLabel }}</time>
                        <div class="group-stats">
                            <span class="group-count">{{ group.activities.length }} {{ group.activities.length === 1 ?
                                'update' : 'updates' }}</span>
                        </div>
                    </div>

                    <!-- Group Activities -->
                    <div class="group-activities">
                        <ActivityItem v-for="activity in group.activities" :key="activity.id" :activity="activity"
                            :is-new="isNewActivity(activity)" @click="handleActivityClick(activity)" />
                    </div>
                </div>

                <!-- Load More Sentinel -->
                <div ref="loadMoreSentinel" class="load-more-sentinel" :class="{ 'loading': store.isLoading }">
                    <div v-if="store.isLoading" class="load-more-spinner">
                        <svg class="animate-spin h-4 w-4 text-neutral-400" fill="none" viewBox="0 0 24 24">
                            <circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4" class="opacity-25">
                            </circle>
                            <path fill="currentColor"
                                d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
                                class="opacity-75"></path>
                        </svg>
                        <span class="load-more-text">Loading more...</span>
                    </div>
                </div>
            </div>

            <!-- Empty State -->
            <div v-else class="feed-empty">
                <div class="empty-content">
                    <div class="empty-illustration">
                        <span class="material-icons empty-icon">timeline</span>
                    </div>
                    <h3 class="empty-title">No activity yet</h3>
                    <p class="empty-description">
                        Activity from your household will appear here as members complete chores, add expenses, and
                        update lists.
                    </p>
                    <div class="empty-actions">
                        <button class="empty-action-btn primary" @click="handleCreateSomething">
                            <span class="material-icons">add</span>
                            Get Started
                        </button>
                    </div>
                </div>
            </div>
        </div>

        <!-- Social Proof Footer -->
        <div v-if="socialProofMessage" class="social-proof">
            <div class="social-proof-content">
                <span class="material-icons social-proof-icon">people</span>
                <p class="social-proof-text">{{ socialProofMessage }}</p>
            </div>
        </div>
    </div>
</template>

<script setup lang="ts">
import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
import { useIntersectionObserver } from '@vueuse/core'
import { formatDistanceToNow, isToday, isYesterday, format, startOfDay, isSameDay } from 'date-fns'
import { useActivityStore } from '@/stores/activityStore'
import { useGroupStore } from '@/stores/groupStore'
import { useAuthStore } from '@/stores/auth'
import { useRouter } from 'vue-router'
import type { Activity } from '@/types/activity'
import ActivityItem from './ActivityItem.vue'

// Props
interface Props {
    maxHeight?: string
    showSocialProof?: boolean
    limitVisible?: number
}

const props = withDefaults(defineProps<Props>(), {
    maxHeight: '400px',
    showSocialProof: true,
    limitVisible: 20,
})

// Emits
const emit = defineEmits<{
    'activity-click': [activity: Activity]
    'create-action': []
}>()

// Store and router
const store = useActivityStore()
const groupStore = useGroupStore()
const authStore = useAuthStore()
const router = useRouter()

// Refs
const loadMoreSentinel = ref<HTMLDivElement | null>(null)
const recentActivityIds = ref<Set<string>>(new Set())

// Activity grouping logic
interface ActivityGroup {
    key: string
    timeLabel: string
    activities: Activity[]
    isNew?: boolean
}

const activityGroups = computed<ActivityGroup[]>(() => {
    const activities = store.activities.slice(0, props.limitVisible)
    if (!activities.length) return []

    const groups: ActivityGroup[] = []
    const groupMap = new Map<string, Activity[]>()

    // Group activities by day
    activities.forEach(activity => {
        const activityDate = new Date(activity.timestamp)
        let groupKey: string
        let timeLabel: string

        if (isToday(activityDate)) {
            groupKey = 'today'
            timeLabel = 'Today'
        } else if (isYesterday(activityDate)) {
            groupKey = 'yesterday'
            timeLabel = 'Yesterday'
        } else {
            groupKey = format(activityDate, 'yyyy-MM-dd')
            timeLabel = format(activityDate, 'EEEE, MMM d')
        }

        if (!groupMap.has(groupKey)) {
            groupMap.set(groupKey, [])
        }
        groupMap.get(groupKey)!.push(activity)
    })

    // Convert to groups array and sort
    const sortedKeys = Array.from(groupMap.keys()).sort((a, b) => {
        if (a === 'today') return -1
        if (b === 'today') return 1
        if (a === 'yesterday') return -1
        if (b === 'yesterday') return 1
        return b.localeCompare(a) // Recent dates first
    })

    sortedKeys.forEach(key => {
        const groupActivities = groupMap.get(key)!
        groups.push({
            key,
            timeLabel: key === 'today' ? 'Today' :
                key === 'yesterday' ? 'Yesterday' :
                    format(new Date(groupActivities[0].timestamp), 'EEEE, MMM d'),
            activities: groupActivities.sort((a, b) =>
                new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()
            ),
            isNew: key === 'today' && hasNewActivities(groupActivities)
        })
    })

    return groups
})

// Helper functions
const hasNewActivities = (activities: Activity[]): boolean => {
    return activities.some(activity => isNewActivity(activity))
}

const isNewActivity = (activity: Activity): boolean => {
    const activityTime = new Date(activity.timestamp)
    const fiveMinutesAgo = new Date(Date.now() - 5 * 60 * 1000)
    return activityTime > fiveMinutesAgo
}

const totalActivitiesText = computed(() => {
    const count = store.activities.length
    if (count === 0) return ''
    if (count === 1) return '1 recent update'
    return `${count} recent updates`
})

const socialProofMessage = computed(() => {
    if (!props.showSocialProof || !store.activities.length) return ''

    const recentCompletions = store.activities
        .filter(activity => activity.event_type.includes('completed'))
        .slice(0, 3)

    if (recentCompletions.length === 0) {
        return 'Your household is getting organized! 🏠'
    }

    if (recentCompletions.length === 1) {
        return `${recentCompletions[0].user.name || 'Someone'} is staying productive! 💪`
    }

    return `${recentCompletions.length} completed tasks this week. Keep it up! 🎉`
})

// Event handlers
const handleActivityClick = (activity: Activity) => {
    emit('activity-click', activity)

    // Auto-navigate based on activity type
    if (activity.event_type.includes('chore')) {
        router.push('/chores')
    } else if (activity.event_type.includes('expense')) {
        router.push('/expenses')
    } else if (activity.event_type.includes('item')) {
        router.push('/lists')
    }
}

const handleViewAll = () => {
    router.push('/activity')
}

const handleRetry = () => {
    if (groupStore.currentGroupId) {
        store.fetchActivities(groupStore.currentGroupId)
    }
}

const handleCreateSomething = () => {
    emit('create-action')
}

// Lifecycle
onMounted(() => {
    if (groupStore.currentGroupId) {
        store.fetchActivities(groupStore.currentGroupId)
        store.connectWebSocket(groupStore.currentGroupId, authStore.accessToken)
    }
})

watch(() => groupStore.currentGroupId, (newGroupId, oldGroupId) => {
    if (oldGroupId && oldGroupId !== newGroupId) {
        store.disconnectWebSocket()
    }
    if (newGroupId) {
        store.fetchActivities(newGroupId)
        store.connectWebSocket(newGroupId, authStore.accessToken)
    }
})

onUnmounted(() => {
    store.disconnectWebSocket()
})

// Intersection observer for infinite scroll
useIntersectionObserver(
    loadMoreSentinel,
    ([{ isIntersecting }]) => {
        if (isIntersecting && groupStore.currentGroupId && store.hasMore && !store.isLoading) {
            store.fetchActivities(groupStore.currentGroupId)
        }
    },
)

// Track new activities for animations
watch(() => store.activities, (newActivities, oldActivities) => {
    if (oldActivities && newActivities.length > oldActivities.length) {
        // New activities were added
        const newIds = newActivities
            .slice(0, newActivities.length - oldActivities.length)
            .map(activity => activity.id)

        newIds.forEach(id => recentActivityIds.value.add(id))

        // Remove from recent set after animation
        setTimeout(() => {
            newIds.forEach(id => recentActivityIds.value.delete(id))
        }, 3000)
    }
}, { flush: 'post' })
</script>

<style scoped>
.activity-feed {
    @apply bg-white rounded-xl border border-neutral-200 shadow-soft overflow-hidden;
    transition: all 300ms ease-page;
}

.feed-header {
    @apply flex items-center justify-between p-4 border-b border-neutral-100 bg-neutral-50/50;
}

.header-content {
    @apply flex items-center gap-3;
}

.feed-title {
    @apply text-lg font-semibold text-neutral-900;
}

.activity-count {
    @apply text-sm text-neutral-500 font-medium;
}

.header-actions {
    @apply flex items-center gap-2;
}

.view-all-btn {
    @apply p-2 rounded-lg text-neutral-400 hover:text-primary-600 hover:bg-primary-50 transition-all duration-micro;
}

.feed-content {
    @apply relative;
    max-height: v-bind(maxHeight);
    overflow-y: auto;
}

/* Loading State */
.feed-loading {
    @apply p-8;
}

.loading-content {
    @apply flex flex-col items-center gap-3;
}

.loading-spinner {
    @apply animate-pulse;
}

.loading-text {
    @apply text-sm text-neutral-500 font-medium;
}

/* Error State */
.feed-error {
    @apply p-6;
}

.error-content {
    @apply flex flex-col items-center gap-3 text-center;
}

.error-icon {
    @apply text-2xl text-error-500;
}

.error-message {
    @apply text-sm text-error-600 font-medium;
}

.retry-btn {
    @apply px-4 py-2 bg-error-50 text-error-700 rounded-lg border border-error-200 hover:bg-error-100 transition-colors duration-micro;
}

/* Activity Groups */
.activity-groups {
    @apply divide-y divide-neutral-100;
}

.activity-group {
    @apply relative;
    animation: fade-in 300ms ease-out;
}

.activity-group.new-group {
    animation: scale-in 150ms ease-out;
}

.group-header {
    @apply flex items-center justify-between px-4 py-3 bg-neutral-50/30;
}

.group-time {
    @apply text-sm font-semibold text-neutral-700;
}

.group-count {
    @apply text-xs text-neutral-500 font-medium;
}

.group-activities {
    @apply divide-y divide-neutral-50;
}

/* Load More */
.load-more-sentinel {
    @apply flex items-center justify-center p-4 transition-opacity duration-micro;
}

.load-more-sentinel:not(.loading) {
    @apply opacity-0;
}

.load-more-spinner {
    @apply flex items-center gap-2;
}

.load-more-text {
    @apply text-sm text-neutral-500;
}

/* Empty State */
.feed-empty {
    @apply p-8;
}

.empty-content {
    @apply flex flex-col items-center text-center gap-4;
}

.empty-illustration {
    @apply w-16 h-16 rounded-full bg-neutral-100 flex items-center justify-center;
}

.empty-icon {
    @apply text-2xl text-neutral-400;
}

.empty-title {
    @apply text-lg font-semibold text-neutral-700;
}

.empty-description {
    @apply text-sm text-neutral-500 max-w-xs leading-relaxed;
}

.empty-actions {
    @apply flex gap-3 mt-2;
}

.empty-action-btn {
    @apply flex items-center gap-2 px-4 py-2 rounded-lg font-medium transition-all duration-micro;
}

.empty-action-btn.primary {
    @apply bg-primary-500 text-white hover:bg-primary-600 shadow-soft;
}

/* Social Proof */
.social-proof {
    @apply border-t border-neutral-100 bg-gradient-to-r from-success-50 to-primary-50 p-4;
}

.social-proof-content {
    @apply flex items-center gap-3;
}

.social-proof-icon {
    @apply text-success-500 text-lg;
}

.social-proof-text {
    @apply text-sm text-success-700 font-medium;
}

/* Animations */
@keyframes fade-in {
    0% {
        opacity: 0;
        transform: translateY(10px);
    }

    100% {
        opacity: 1;
        transform: translateY(0);
    }
}

@keyframes scale-in {
    0% {
        opacity: 0;
        transform: scale(0.95);
    }

    100% {
        opacity: 1;
        transform: scale(1);
    }
}

/* Scrollbar styling */
.feed-content::-webkit-scrollbar {
    width: 4px;
}

.feed-content::-webkit-scrollbar-track {
    @apply bg-neutral-100;
}

.feed-content::-webkit-scrollbar-thumb {
    @apply bg-neutral-300 rounded-full;
}

.feed-content::-webkit-scrollbar-thumb:hover {
    @apply bg-neutral-400;
}
</style>