<template>
  <!-- Smart Page Header -->
  <header class="page-header mb-8">
    <div class="header-content">
      <div class="header-main">
        <h1 class="page-title">{{ pageTitle }}</h1>
        <p v-if="currentGroupId" class="page-subtitle">
          {{ t('listsPage.groupContext', 'Shared with your group') }}
        </p>
        <p v-else class="page-subtitle">
          {{ t('listsPage.personalContext', 'Your personal lists') }}
        </p>
      </div>

      <!-- Quick Stats -->
      <div class="quick-stats">
        <div class="stat-item">
          <span class="stat-number">{{ filteredLists.length }}</span>
          <span class="stat-label">{{ t('listsPage.stats.lists', 'Lists') }}</span>
        </div>
        <div v-if="totalItems > 0" class="stat-item">
          <span class="stat-number">{{ totalItems }}</span>
          <span class="stat-label">{{ t('listsPage.stats.items', 'Items') }}</span>
        </div>
      </div>
    </div>
  </header>

  <!-- Error State with Retry -->
  <Alert v-if="error" type="error" class="error-alert">
    <div class="error-content">
      <h3>{{ t('listsPage.error.title', 'Failed to load lists') }}</h3>
      <p>{{ error }}</p>
      <Button color="error" size="sm" @click="fetchListsAndGroups" class="retry-button">
        <span class="material-icons">refresh</span>
        {{ t('listsPage.retryButton', 'Retry') }}
      </Button>
    </div>
  </Alert>

  <!-- Enhanced Empty State -->
  <div v-else-if="filteredLists.length === 0 && !loading" class="empty-state">
    <div class="empty-illustration">
      <div class="empty-icon-container">
        <span class="material-icons">playlist_add</span>
      </div>
    </div>

    <div class="empty-content">
      <h3 class="empty-title">{{ t(noListsMessageKey, 'No lists yet') }}</h3>
      <p class="empty-description">
        <span v-if="!currentGroupId">{{ t('listsPage.emptyState.personalGlobalInfo', 'Create your first list!')
          }}</span>
        <span v-else>{{ t('listsPage.emptyState.groupSpecificInfo', 'Start collaborating with your group!') }}</span>
      </p>

      <!-- Quick Start Actions -->
      <div class="empty-actions">
        <Button @click="showCreateModal = true" class="primary-action">
          <span class="material-icons">add</span>
          {{ t('listsPage.createNewListButton', 'Create Your First List') }}
        </Button>

        <div class="suggested-templates">
          <p class="templates-label">{{ t('listsPage.quickStart', 'Quick start:') }}</p>
          <div class="template-buttons">
            <button v-for="template in quickTemplates" :key="template.id" class="template-button"
              @click="createFromTemplate(template)">
              <span class="material-icons">{{ template.icon }}</span>
              {{ template.name }}
            </button>
          </div>
        </div>
      </div>
    </div>
  </div>

  <!-- Enhanced Loading State -->
  <div v-else-if="loading && filteredLists.length === 0" class="loading-container">
    <div class="loading-grid">
      <div v-for="i in 6" :key="i" class="loading-list-card">
        <div class="loading-header">
          <div class="skeleton-line title"></div>
          <div class="skeleton-line subtitle"></div>
        </div>
        <div class="loading-items">
          <div v-for="j in 3" :key="j" class="skeleton-line item"></div>
        </div>
      </div>
    </div>
  </div>

  <!-- Enhanced Lists Grid -->
  <div v-else class="lists-container">
    <!-- Smart Filters -->
    <div v-if="filteredLists.length > 3" class="filters-section">
      <div class="filter-pills">
        <button v-for="filter in availableFilters" :key="filter.id" class="filter-pill"
          :class="{ active: activeFilter === filter.id }" @click="setActiveFilter(filter.id)">
          <span class="material-icons">{{ filter.icon }}</span>
          {{ filter.label }}
          <span v-if="filter.count > 0" class="filter-count">{{ filter.count }}</span>
        </button>
      </div>
    </div>

    <!-- Lists Grid with Improved UX -->
    <div class="lists-grid">
      <!-- Active Lists -->
      <div v-for="list in visibleLists" :key="list.id" class="list-card" :class="{
        'touch-active': touchActiveListId === list.id,
        'archived': list.archived_at,
        'has-activity': hasRecentActivity(list),
        'collaborative': list.group_id
      }" @click="navigateToList(list.id)" @touchstart.passive="handleTouchStart(list.id)"
        @touchend.passive="handleTouchEnd" @touchcancel.passive="handleTouchEnd" :data-list-id="list.id"
        :ref="el => setListCardRef(el, list.id)">
        <!-- List Header with Enhanced Visual Hierarchy -->
        <header class="list-header">
          <div class="list-title-section">
            <h3 class="list-title">{{ list.name }}</h3>
            <div class="list-metadata">
              <span v-if="list.group_id" class="metadata-badge group">
                <span class="material-icons">group</span>
                {{ t('listsPage.shared', 'Shared') }}
              </span>
              <span v-if="hasRecentActivity(list)" class="metadata-badge recent">
                <span class="material-icons">schedule</span>
                {{ t('listsPage.recentActivity', 'Active') }}
              </span>
            </div>
          </div>

          <!-- Enhanced Actions Menu -->
          <div class="list-actions">
            <button class="action-trigger" @click.stop="toggleActionsMenu(list.id)"
              :aria-expanded="actionsMenuVisibleFor === list.id"
              :aria-label="t('listsPage.moreActions', 'More actions')">
              <span class="material-icons">more_vert</span>
            </button>

            <Transition name="dropdown-scale">
              <div v-if="actionsMenuVisibleFor === list.id" class="actions-dropdown">
                <button v-if="!list.archived_at" class="dropdown-action" @click.stop="archiveOrUnarchive(list)">
                  <span class="material-icons">archive</span>
                  {{ t('listsPage.archive', 'Archive') }}
                </button>

                <button v-if="list.archived_at" class="dropdown-action" @click.stop="archiveOrUnarchive(list)">
                  <span class="material-icons">unarchive</span>
                  {{ t('listsPage.unarchive', 'Unarchive') }}
                </button>

                <button class="dropdown-action" @click.stop="editList(list)">
                  <span class="material-icons">edit</span>
                  {{ t('listsPage.edit', 'Edit') }}
                </button>

                <button class="dropdown-action" @click.stop="duplicateList(list)">
                  <span class="material-icons">content_copy</span>
                  {{ t('listsPage.duplicate', 'Duplicate') }}
                </button>
              </div>
            </Transition>
          </div>
        </header>

        <!-- List Description -->
        <p v-if="list.description" class="list-description">
          {{ list.description }}
        </p>
        <p v-else class="list-description placeholder">
          {{ t('listsPage.noDescription', 'No description') }}
        </p>

        <!-- Enhanced Items Preview -->
        <div class="list-items-preview">
          <!-- Completed Items Summary -->
          <div v-if="getCompletedCount(list.items) > 0" class="completion-summary">
            <div class="completion-bar">
              <div class="completion-fill" :style="{ width: `${getCompletionPercentage(list.items)}%` }"></div>
            </div>
            <span class="completion-text">
              {{ getCompletedCount(list.items) }}/{{ list.items.length }}
              {{ t('listsPage.completed', 'completed') }}
            </span>
          </div>

          <!-- Items List -->
          <ul class="items-preview-list">
            <li v-for="item in getPreviewItems(list.items)" :key="item.id || item.tempId" class="preview-item" :class="{
              'completed': item.is_complete,
              'updating': item.updating
            }">
              <label class="item-checkbox-label" @click.stop>
                <input type="checkbox" :checked="item.is_complete" @change="toggleItem(list, item)"
                  :disabled="item.id === undefined && item.tempId !== undefined" class="item-checkbox" />
                <span class="item-text" :class="{ 'completed': item.is_complete }">
                  {{ item.name }}
                </span>
              </label>
            </li>

            <!-- Show more indicator -->
            <li v-if="list.items.length > 3" class="more-items-indicator">
              <span class="more-text">
                +{{ list.items.length - 3 }} {{ t('listsPage.moreItems', 'more items') }}
              </span>
            </li>
          </ul>

          <!-- Quick Add (only for non-archived lists) -->
          <div v-if="!list.archived_at" class="quick-add-container">
            <div class="quick-add-input">
              <input type="text" :placeholder="t('listsPage.addItemPlaceholder', 'Add item...')"
                :ref="el => setNewItemInputRef(el as HTMLInputElement | null, list.id)" :data-list-id="list.id"
                @keyup.enter="addNewItem(list, $event)" @blur="handleNewItemBlur(list, $event)" @click.stop
                class="add-input" />
              <span class="material-icons add-icon">add</span>
            </div>
          </div>
        </div>
      </div>

      <!-- Create New List Card -->
      <div class="create-list-card" @click="showCreateModal = true" ref="createListCardRef">
        <div class="create-content">
          <div class="create-icon">
            <span class="material-icons">add</span>
          </div>
          <h3 class="create-title">{{ t('listsPage.createCard.title', 'Create New List') }}</h3>
          <p class="create-subtitle">{{ t('listsPage.createCard.subtitle', 'Start organizing your tasks') }}</p>
        </div>
      </div>
    </div>
  </div>

  <!-- Enhanced Create List Modal -->
  <CreateListModal v-model="showCreateModal" :groups="availableGroupsForModal" @created="onListCreated" />
</template>

<script setup lang="ts">
import { ref, onMounted, computed, watch, onUnmounted, nextTick } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRoute, useRouter } from 'vue-router';
import { apiClient, API_ENDPOINTS } from '@/services/api';
import CreateListModal from '@/components/CreateListModal.vue';
import { useStorage, onClickOutside } from '@vueuse/core';
import { Alert, Button } from '@/components/ui'
import { useSocket } from '@/composables/useSocket'
import { useItemHelpers } from '@/composables/useItemHelpers'

const { t } = useI18n();
const { getCompletedCount, getCompletionPercentage, getPreviewItems } = useItemHelpers();

interface ListStatus {
  id: number;
  updated_at: string;
  item_count: number;
  latest_item_updated_at: string | null;
}

interface List {
  id: number;
  name: string;
  description?: string;
  is_complete: boolean;
  updated_at: string;
  created_by_id: number;
  group_id?: number | null;
  created_at: string;
  version: number;
  items: Item[];
  archived_at?: string | null;
}

interface Group {
  id: number;
  name: string;
}

interface Item {
  id: number | string;
  tempId?: string;
  name: string;
  quantity?: string | null;
  is_complete: boolean;
  price?: number | null;
  version: number;
  updating?: boolean;
  created_at?: string;
  updated_at: string;
}

const props = defineProps<{
  groupId?: number | string;
}>();

const route = useRoute();
const router = useRouter();

// Enhanced reactive state
const loading = ref(true);
const error = ref<string | null>(null);
const lists = ref<(List & { items: Item[] })[]>([]);
const archivedLists = ref<List[]>([]);
const haveFetchedArchived = ref(false);
const allFetchedGroups = ref<Group[]>([]);
const currentViewedGroup = ref<Group | null>(null);
const showCreateModal = ref(false);
const newItemInputRefs = ref<Map<number, HTMLInputElement>>(new Map());
const actionsMenuVisibleFor = ref<number | null>(null);
const listCardRefs = ref<Map<number, HTMLElement>>(new Map());
const touchActiveListId = ref<number | null>(null);
const activeFilter = ref('all');
let pollingInterval: ReturnType<typeof setInterval> | null = null;

// Quick templates for empty state
const quickTemplates = computed(() => [
  {
    id: 'grocery',
    name: t('listsPage.templates.grocery', 'Grocery List'),
    icon: 'shopping_cart',
    items: ['Milk', 'Bread', 'Eggs']
  },
  {
    id: 'todo',
    name: t('listsPage.templates.todo', 'To-Do'),
    icon: 'task_alt',
    items: ['Important task', 'Call someone', 'Schedule appointment']
  },
  {
    id: 'packing',
    name: t('listsPage.templates.packing', 'Packing'),
    icon: 'luggage',
    items: ['Clothes', 'Toiletries', 'Documents']
  }
]);

// Filtered lists (move this up for dependency order)
const filteredLists = computed<(List & { items: Item[] })[]>(() => {
  if (showArchived.value) {
    const combined = [...lists.value, ...archivedLists.value];
    const uniqueLists = Array.from(new Map(combined.map(l => [l.id, l])).values());
    return uniqueLists.sort((a, b) => new Date(b.updated_at).getTime() - new Date(a.updated_at).getTime());
  }
  return lists.value.filter((list) => !list.archived_at);
});

// Enhanced computed properties
const totalItems = computed(() =>
  filteredLists.value.reduce((sum: number, list: List & { items: Item[] }) => sum + list.items.length, 0)
);

const visibleLists = computed(() => {
  let filtered = filteredLists.value;

  switch (activeFilter.value) {
    case 'active':
      filtered = filtered.filter((l: List) => !l.archived_at && hasIncompleteItems(l));
      break;
    case 'completed':
      filtered = filtered.filter((l: List) => !l.archived_at && isListCompleted(l));
      break;
    case 'shared':
      filtered = filtered.filter((l: List) => l.group_id);
      break;
    default:
      break;
  }

  return filtered;
});

const availableFilters = computed(() => [
  {
    id: 'all',
    label: t('listsPage.filters.all', 'All'),
    icon: 'list',
    count: filteredLists.value.length
  },
  {
    id: 'active',
    label: t('listsPage.filters.active', 'Active'),
    icon: 'radio_button_checked',
    count: filteredLists.value.filter((l: List) => !l.archived_at && hasIncompleteItems(l)).length
  },
  {
    id: 'completed',
    label: t('listsPage.filters.completed', 'Completed'),
    icon: 'check_circle',
    count: filteredLists.value.filter((l: List) => !l.archived_at && isListCompleted(l)).length
  },
  {
    id: 'shared',
    label: t('listsPage.filters.shared', 'Shared'),
    icon: 'group',
    count: filteredLists.value.filter((l: List) => l.group_id).length
  }
]);

// Enhanced utility functions
const hasRecentActivity = (list: List) => {
  const oneDayAgo = new Date(Date.now() - 24 * 60 * 60 * 1000);
  return new Date(list.updated_at) > oneDayAgo;
};

const hasIncompleteItems = (list: List) => {
  return list.items.some(item => !item.is_complete);
};

const isListCompleted = (list: List) => {
  return list.items.length > 0 && list.items.every(item => item.is_complete);
};

const setActiveFilter = (filterId: string) => {
  activeFilter.value = filterId;
};

const createFromTemplate = async (template: any) => {
  // Implementation for creating list from template
  showCreateModal.value = true;
  // Pass template data to modal
};

// Enhanced ref setters
const setNewItemInputRef = (el: HTMLInputElement | null, listId: number) => {
  if (el) {
    newItemInputRefs.value.set(listId, el);
  } else {
    newItemInputRefs.value.delete(listId);
  }
};

const currentGroupId = computed<number | null>(() => {
  const idFromProp = props.groupId;
  const idFromRoute = route.params.groupId;
  if (idFromProp) {
    return typeof idFromProp === 'string' ? parseInt(idFromProp, 10) : idFromProp;
  }
  if (idFromRoute) {
    return parseInt(idFromRoute as string, 10);
  }
  return null;
});

const pageTitle = computed(() => {
  if (currentGroupId.value) {
    return currentViewedGroup.value
      ? t('listsPage.pageTitle.forGroup', { groupName: currentViewedGroup.value.name })
      : t('listsPage.pageTitle.forGroupId', { groupId: currentGroupId.value });
  }
  return t('listsPage.pageTitle.myLists');
});

const noListsMessageKey = computed(() => {
  if (currentGroupId.value) {
    return 'listsPage.emptyState.noListsForGroup';
  }
  return 'listsPage.emptyState.noListsYet';
});

const fetchAllAccessibleGroups = async () => {
  try {
    const response = await apiClient.get(API_ENDPOINTS.GROUPS.BASE);
    allFetchedGroups.value = (response.data as Group[]);
  } catch (err) {
    console.error('Failed to fetch groups for modal:', err);
  }
};

const cachedLists = useStorage<(List & { items: Item[] })[]>('cached-lists', []);
const cachedTimestamp = useStorage<number>('cached-lists-timestamp', 0);
const CACHE_DURATION = 5 * 60 * 1000;

const loadCachedData = () => {
  const now = Date.now();
  if (cachedLists.value.length > 0 && (now - cachedTimestamp.value) < CACHE_DURATION) {
    lists.value = JSON.parse(JSON.stringify(cachedLists.value));
    loading.value = false;
  }
};

const fetchLists = async () => {
  error.value = null;

  // Only show loading if we don't have any cached data to display
  if (lists.value.length === 0) {
    loading.value = true;
  }

  try {
    const endpoint = currentGroupId.value
      ? API_ENDPOINTS.GROUPS.LISTS(String(currentGroupId.value))
      : API_ENDPOINTS.LISTS.BASE;
    const response = await apiClient.get(endpoint);
    lists.value = (response.data as (List & { items: Item[] })[]).map(list => ({
      ...list,
      items: list.items || []
    }));
    cachedLists.value = JSON.parse(JSON.stringify(lists.value));
    cachedTimestamp.value = Date.now();
  } catch (err: unknown) {
    error.value = err instanceof Error ? err.message : t('listsPage.errors.fetchFailed');
    console.error(error.value, err);
    // If we have cached data and there's an error, don't clear the lists
    if (cachedLists.value.length === 0) lists.value = [];
  } finally {
    loading.value = false;
  }
};

const fetchArchivedLists = async () => {
  if (haveFetchedArchived.value) return;
  try {
    const endpoint = API_ENDPOINTS.LISTS.ARCHIVED;
    const response = await apiClient.get(endpoint);
    archivedLists.value = response.data as List[];
    haveFetchedArchived.value = true;
  } catch (err) {
    console.error('Failed to fetch archived lists:', err);
  }
};

const fetchListsAndGroups = async () => {
  // Only show loading if we don't have cached data
  if (lists.value.length === 0) {
    loading.value = true;
  }

  try {
    await Promise.all([
      fetchLists(),
      fetchAllAccessibleGroups()
    ]);
  } catch (err) {
    console.error('Error in fetchListsAndGroups:', err);
  } finally {
    loading.value = false;
  }
};

const availableGroupsForModal = computed(() => {
  return allFetchedGroups.value.map(group => ({
    label: group.name,
    value: group.id,
  }));
});

const getGroupName = (groupId?: number | null): string | undefined => {
  if (!groupId) return undefined;
  return allFetchedGroups.value.find(g => g.id === groupId)?.name;
}

const onListCreated = (newList: List & { items: Item[] }) => {
  lists.value.push({
    ...newList,
    items: newList.items || []
  });
  cachedLists.value = JSON.parse(JSON.stringify(lists.value));
  cachedTimestamp.value = Date.now();
};

const toggleItem = async (list: List, item: Item | any) => {
  if (typeof item.id === 'string' && item.id.startsWith('temp-')) {
    return;
  }
  const originalIsComplete = item.is_complete;
  item.is_complete = !item.is_complete;
  item.updating = true;

  try {
    await apiClient.put(
      API_ENDPOINTS.LISTS.ITEM(String(list.id), String(item.id)),
      {
        is_complete: item.is_complete,
        version: item.version,
        name: item.name,
        quantity: item.quantity,
        price: item.price
      }
    );
    item.version++;
  } catch (err) {
    item.is_complete = originalIsComplete;
    console.error('Failed to update item:', err);
    const itemElement = document.querySelector(`.neo-list-item[data-item-id="${item.id}"]`);
    if (itemElement) {
      itemElement.classList.add('error-flash');
      setTimeout(() => itemElement.classList.remove('error-flash'), 800);
    }
  } finally {
    item.updating = false;
  }
};

const addNewItem = async (list: List, event: Event) => {
  const inputElement = event.target as HTMLInputElement;
  const itemName = inputElement.value.trim();

  if (!itemName) {
    if (event.type === 'blur') inputElement.value = '';
    return;
  }

  const localTempId = `temp-${Date.now()}`;
  const newItem: Item = {
    id: localTempId,
    tempId: localTempId,
    name: itemName,
    is_complete: false,
    version: 0,
    updating: true,
    created_at: new Date().toISOString(),
    updated_at: new Date().toISOString(),
  };

  list.items.push(newItem);
  const originalInputValue = inputElement.value;
  inputElement.value = '';
  inputElement.disabled = true;

  await nextTick();

  const newItemLiElement = document.querySelector(`.neo-list-item[data-item-temp-id="${localTempId}"]`);
  if (newItemLiElement) {
    newItemLiElement.classList.add('item-appear');
  }

  try {
    const response = await apiClient.post(API_ENDPOINTS.LISTS.ITEMS(String(list.id)), {
      name: itemName,
      is_complete: false,
    });
    const addedItemFromServer = response.data as Item;

    const itemIndex = list.items.findIndex(i => i.tempId === localTempId);
    if (itemIndex !== -1) {
      list.items.splice(itemIndex, 1, {
        ...newItem,
        ...addedItemFromServer,
        updating: false,
        tempId: undefined
      });
    }
    if (event.type === 'keyup' && (event as KeyboardEvent).key === 'Enter') {
      inputElement.disabled = false;
      inputElement.focus();
    } else {
      inputElement.disabled = false;
    }
  } catch (err) {
    console.error('Failed to add new item:', err);
    list.items = list.items.filter(i => i.tempId !== localTempId);
    inputElement.value = originalInputValue;
    inputElement.disabled = false;
    inputElement.style.transition = 'border-color 0.5s ease';
    inputElement.style.borderColor = 'red';
    setTimeout(() => {
      inputElement.style.borderColor = '#ccc';
    }, 500);
  }
};

const handleNewItemBlur = (list: List, event: Event) => {
  const inputElement = event.target as HTMLInputElement;
  if (inputElement.value.trim()) {
    addNewItem(list, event);
  }
};

const navigateToList = (listId: number) => {
  const selectedList = lists.value.find(l => l.id === listId);
  if (selectedList) {
    const listShell = {
      id: selectedList.id,
      name: selectedList.name,
      description: selectedList.description,
      group_id: selectedList.group_id,
    };
    sessionStorage.setItem('listDetailShell', JSON.stringify(listShell));
  }
  router.push({ name: 'ListDetail', params: { id: listId } });
};

const prefetchListDetails = async (listId: number) => {
  try {
    const response = await apiClient.get(API_ENDPOINTS.LISTS.BY_ID(String(listId)));
    const fullListData = response.data;
    sessionStorage.setItem(`listDetailFull_${listId}`, JSON.stringify(fullListData));
  } catch (err) {
    console.warn('Pre-fetch failed:', err);
  }
};

let intersectionObserver: IntersectionObserver | null = null;
const setupIntersectionObserver = () => {
  if (intersectionObserver) intersectionObserver.disconnect();

  intersectionObserver = new IntersectionObserver((entries) => {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        const listId = entry.target.getAttribute('data-list-id');
        if (listId) {
          const cachedFullData = sessionStorage.getItem(`listDetailFull_${listId}`);
          if (!cachedFullData) {
            prefetchListDetails(Number(listId));
          }
        }
      }
    });
  }, {
    rootMargin: '100px 0px',
    threshold: 0.01
  });

  nextTick(() => {
    document.querySelectorAll('.neo-list-card[data-list-id]').forEach(card => {
      intersectionObserver!.observe(card);
    });
  });
};

const handleTouchStart = (listId: number) => { touchActiveListId.value = listId; };
const handleTouchEnd = () => { touchActiveListId.value = null; };

const refetchList = async (listId: number) => {
  try {
    const response = await apiClient.get(API_ENDPOINTS.LISTS.BY_ID(String(listId)));
    const updatedList = response.data as List;
    const listIndex = lists.value.findIndex(l => l.id === listId);

    if (listIndex !== -1) {
      lists.value[listIndex] = { ...updatedList, items: updatedList.items || [] };
      cachedLists.value = JSON.parse(JSON.stringify(lists.value));
      cachedTimestamp.value = Date.now();
    } else {
    }
  } catch (err) {
    console.error(`Failed to refetch list ${listId}:`, err);
  }
};

const checkForUpdates = async () => {
  if (lists.value.length === 0) {
    return;
  }

  const listIds = lists.value.map(l => l.id);
  if (listIds.length === 0) return;

  try {
    const response = await apiClient.get(API_ENDPOINTS.LISTS.STATUSES, {
      params: { ids: listIds }
    });
    const statuses = response.data as ListStatus[];

    for (const status of statuses) {
      const localList = lists.value.find(l => l.id === status.id);
      if (localList) {
        const localUpdatedAt = new Date(localList.updated_at).getTime();
        const remoteUpdatedAt = new Date(status.updated_at).getTime();
        const localItemCount = localList.items.length;
        const remoteItemCount = status.item_count;

        const localLatestItemUpdate = localList.items.reduce((latest, item) => {
          const itemDate = new Date(item.updated_at).getTime();
          return itemDate > latest ? itemDate : latest;
        }, 0);

        const remoteLatestItemUpdate = status.latest_item_updated_at
          ? new Date(status.latest_item_updated_at).getTime()
          : 0;

        if (
          remoteUpdatedAt > localUpdatedAt ||
          localItemCount !== remoteItemCount ||
          (remoteLatestItemUpdate > localLatestItemUpdate)
        ) {
          await refetchList(status.id);
        }
      }
    }
  } catch (err) {
    console.warn('Polling for list updates failed:', err);
  }
};

const startPolling = () => {
  stopPolling();
  pollingInterval = setInterval(checkForUpdates, 15000);
};

const stopPolling = () => {
  if (pollingInterval) {
    clearInterval(pollingInterval);
    pollingInterval = null;
  }
};

const showArchived = ref(false);

watch(showArchived, (isShowing) => {
  if (isShowing) {
    fetchArchivedLists();
  }
});

const setListCardRef = (el: any, listId: number) => {
  if (el) {
    listCardRefs.value.set(listId, el);
  } else if (listCardRefs.value.has(listId)) {
    listCardRefs.value.delete(listId);
  }
};

const toggleActionsMenu = (listId: number) => {
  actionsMenuVisibleFor.value = actionsMenuVisibleFor.value === listId ? null : listId;
};

const closeActionsMenu = () => {
  actionsMenuVisibleFor.value = null;
};

const currentCardRef = computed(() => {
  if (actionsMenuVisibleFor.value) {
    return listCardRefs.value.get(actionsMenuVisibleFor.value)
  }
  return undefined
});

onClickOutside(currentCardRef, () => {
  closeActionsMenu();
});

const archiveOrUnarchive = (list: List) => {
  if (list.archived_at) {
    unarchiveList(list);
  } else {
    archiveList(list);
  }
  closeActionsMenu();
};

const archiveList = async (list: List) => {
  const originalArchiveState = list.archived_at;

  // Optimistic update
  list.archived_at = new Date().toISOString();

  try {
    await apiClient.delete(API_ENDPOINTS.LISTS.BY_ID(String(list.id)), {
      params: { expected_version: list.version }
    });

    // Move from active to archived lists
    const index = lists.value.findIndex(l => l.id === list.id);
    if (index > -1) {
      const [archivedItem] = lists.value.splice(index, 1);
      archivedLists.value.push(archivedItem);
    }

    // Update cache
    cachedLists.value = JSON.parse(JSON.stringify(lists.value));
    cachedTimestamp.value = Date.now();

    console.log(`Successfully archived list ${list.id}`);
  } catch (err: any) {
    // Rollback optimistic update
    list.archived_at = originalArchiveState;

    if (err.response?.status === 409) {
      error.value = `List "${list.name}" was modified by someone else. Please refresh and try again.`;
    } else {
      error.value = err.response?.data?.detail || `Failed to archive list "${list.name}"`;
    }
    console.error('Failed to archive list:', err);
  }
};

const unarchiveList = async (list: List) => {
  const originalArchiveState = list.archived_at;

  // Optimistic update
  list.archived_at = undefined;

  try {
    const response = await apiClient.post(API_ENDPOINTS.LISTS.UNARCHIVE(String(list.id)));

    // Move from archived to active lists
    const index = archivedLists.value.findIndex(l => l.id === list.id);
    if (index > -1) {
      const [unarchivedItem] = archivedLists.value.splice(index, 1);
      unarchivedItem.archived_at = undefined;
      unarchivedItem.version = response.data.version; // Update version from server
      lists.value.push(unarchivedItem);
    }

    // Update cache
    cachedLists.value = JSON.parse(JSON.stringify(lists.value));
    cachedTimestamp.value = Date.now();

    console.log(`Successfully unarchived list ${list.id}`);
  } catch (err: any) {
    // Rollback optimistic update
    list.archived_at = originalArchiveState;

    if (err.response?.status === 409) {
      error.value = `List "${list.name}" was modified by someone else. Please refresh and try again.`;
    } else {
      error.value = err.response?.data?.detail || `Failed to unarchive list "${list.name}"`;
    }
    console.error('Failed to unarchive list:', err);
  }
};

const deleteList = async (list: List) => {
  // Note: Backend only supports archiving, not permanent deletion
  // This function archives the list if not already archived
  if (list.archived_at) {
    // Already archived - show info message
    error.value = `List "${list.name}" is already archived. Use unarchive if you want to restore it.`;
    closeActionsMenu();
    return;
  }

  if (confirm(`Are you sure you want to archive the list "${list.name}"? You can unarchive it later if needed.`)) {
    await archiveList(list);
  }
  closeActionsMenu();
};

const editList = async (list: List) => {
  // TODO: Implement list editing functionality
  console.log(`TODO: Implement edit functionality for list ${list.id}`);
  closeActionsMenu();
};

const duplicateList = async (list: List) => {
  // TODO: Implement list duplication functionality  
  console.log(`TODO: Implement duplicate functionality for list ${list.id}`);
  closeActionsMenu();
};

// --- WebSocket Integration ---
const { connect: connectSocket, on: onSocket, off: offSocket, isConnected } = useSocket();

// Real-time event handlers
const handleListCreated = (payload: any) => {
  const listId = payload?.list_id ?? payload?.list?.id ?? payload?.id;
  if (!listId) return;
  refetchList(Number(listId));
};

const handleListUpdated = (payload: any) => {
  const listId = payload?.list_id ?? payload?.list?.id ?? payload?.id;
  if (!listId) return;
  refetchList(Number(listId));
};

const handleListDeleted = (payload: any) => {
  const listId = payload?.list_id ?? payload?.listId ?? payload?.id;
  if (!listId) return;
  const index = lists.value.findIndex(l => l.id === listId);
  if (index !== -1) {
    lists.value.splice(index, 1);
    cachedLists.value = JSON.parse(JSON.stringify(lists.value));
    cachedTimestamp.value = Date.now();
  }
};

const handleItemEvent = (payload: any) => {
  const listId = payload?.item?.list_id ?? payload?.listId;
  if (!listId) return;
  refetchList(Number(listId));
};

onMounted(() => {
  loadCachedData();
  fetchListsAndGroups().then(() => {
    if (lists.value.length > 0) {
      setupIntersectionObserver();
      startPolling();
    }
  });

  // Establish WebSocket connection for the current household/group (if any)
  if (currentGroupId.value) {
    connectSocket(currentGroupId.value).catch(err => console.error('WebSocket connection failed:', err));
  }

  // Register WebSocket listeners
  onSocket('list:created', handleListCreated);
  onSocket('list:updated', handleListUpdated);
  onSocket('list:deleted', handleListDeleted);
  onSocket('item:created', handleItemEvent);
  onSocket('item:updated', handleItemEvent);
  onSocket('item:deleted', handleItemEvent);
});

watch(currentGroupId, () => {
  loadCachedData();
  haveFetchedArchived.value = false;
  archivedLists.value = [];
  fetchListsAndGroups().then(() => {
    if (lists.value.length > 0) {
      setupIntersectionObserver();
      startPolling();
    } else {
      stopPolling();
    }
  });

  if (currentGroupId.value) {
    connectSocket(currentGroupId.value).catch(err => console.warn('WebSocket reconnection failed:', err));
  }
});

// Pause polling while WebSocket is connected, resume if disconnected
watch(isConnected, (connected) => {
  if (connected) {
    stopPolling();
  } else {
    startPolling();
  }
});

watch(() => lists.value.length, (newLength, oldLength) => {
  if (newLength > 0 && oldLength === 0 && !loading.value) {
    setupIntersectionObserver();
  }
  if (newLength > 0) {
    startPolling();
    nextTick(() => {
      document.querySelectorAll('.neo-list-card[data-list-id]').forEach(card => {
        if (intersectionObserver) {
          intersectionObserver.observe(card);
        }
      });
    });
  }
});

onUnmounted(() => {
  if (intersectionObserver) {
    intersectionObserver.disconnect();
  }
  stopPolling();

  // Cleanup WebSocket listeners
  offSocket('list:created', handleListCreated);
  offSocket('list:updated', handleListUpdated);
  offSocket('list:deleted', handleListDeleted);
  offSocket('item:created', handleItemEvent);
  offSocket('item:updated', handleItemEvent);
  offSocket('item:deleted', handleItemEvent);
});

</script>

<style scoped lang="scss">
@import url('https://fonts.googleapis.com/icon?family=Material+Icons');

/* Enhanced Page Header */
.page-header {
  /* MainLayout handles spacing */
}

.header-content {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 2rem;
  flex-wrap: wrap;

  @media (max-width: 768px) {
    flex-direction: column;
    gap: 1rem;
  }
}

.header-main {
  flex-grow: 1;
}

.page-title {
  font-size: 2rem;
  font-weight: 700;
  color: #1f2937;
  margin: 0 0 0.5rem 0;

  @media (min-width: 768px) {
    font-size: 2.5rem;
  }
}

.page-subtitle {
  font-size: 1rem;
  color: #6b7280;
  margin: 0;
  font-weight: 400;
}

.quick-stats {
  display: flex;
  gap: 2rem;

  @media (max-width: 768px) {
    gap: 1rem;
  }
}

.stat-item {
  text-align: center;

  .stat-number {
    display: block;
    font-size: 2rem;
    font-weight: 700;
    color: #3b82f6;
    line-height: 1;
  }

  .stat-label {
    display: block;
    font-size: 0.875rem;
    color: #6b7280;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    margin-top: 0.25rem;
  }
}

/* Enhanced Error State */
.error-alert {
  margin-bottom: 2rem;
}

.error-content {
  text-align: center;

  h3 {
    margin: 0 0 0.5rem 0;
    font-weight: 600;
  }

  p {
    margin: 0 0 1rem 0;
    color: #6b7280;
  }
}

.retry-button {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}

/* Enhanced Empty State */
.empty-state {
  text-align: center;
  padding: 4rem 2rem;
  max-width: 600px;
  margin: 0 auto;
}

.empty-illustration {
  margin-bottom: 2rem;
}

.empty-icon-container {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 80px;
  height: 80px;
  background: linear-gradient(135deg, #e0e7ff, #c7d2fe);
  border-radius: 50%;
  margin-bottom: 1rem;

  .material-icons {
    font-size: 2.5rem;
    color: #4f46e5;
  }
}

.empty-content {
  .empty-title {
    font-size: 1.5rem;
    font-weight: 600;
    color: #111827;
    margin: 0 0 0.5rem 0;
  }

  .empty-description {
    font-size: 1rem;
    color: #6b7280;
    margin: 0 0 2rem 0;
    line-height: 1.5;
  }
}

.empty-actions {
  .primary-action {
    margin-bottom: 2rem;
    padding: 0.75rem 2rem;
    font-size: 1rem;
  }
}

.suggested-templates {
  .templates-label {
    font-size: 0.875rem;
    color: #6b7280;
    margin: 0 0 1rem 0;
  }

  .template-buttons {
    display: flex;
    justify-content: center;
    gap: 1rem;
    flex-wrap: wrap;
  }
}

.template-button {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 1rem;
  background: white;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.2s ease;
  font-size: 0.875rem;

  &:hover {
    border-color: #3b82f6;
    background: #f8fafc;
  }

  .material-icons {
    font-size: 1.125rem;
    color: #6b7280;
  }
}

/* Enhanced Loading State */
.loading-container {
  padding: 2rem 0;
}

.loading-grid {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
}

.loading-list-card {
  background: white;
  border-radius: 12px;
  padding: 1.5rem;
  border: 1px solid #e5e7eb;
}

.loading-header {
  margin-bottom: 1rem;

  .skeleton-line.title {
    height: 1.25rem;
    width: 70%;
    margin-bottom: 0.5rem;
  }

  .skeleton-line.subtitle {
    height: 1rem;
    width: 50%;
  }
}

.loading-items {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;

  .skeleton-line.item {
    height: 1rem;
    width: 90%;
  }
}

.skeleton-line {
  background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
  background-size: 200% 100%;
  animation: skeleton-shimmer 1.5s infinite;
  border-radius: 4px;
}

@keyframes skeleton-shimmer {
  0% {
    background-position: 200% 0;
  }

  100% {
    background-position: -200% 0;
  }
}

/* Filters Section */
.filters-section {
  margin-bottom: 2rem;
}

.filter-pills {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.filter-pill {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 1rem;
  background: white;
  border: 1px solid #e5e7eb;
  border-radius: 20px;
  cursor: pointer;
  transition: all 0.2s ease;
  font-size: 0.875rem;

  &:hover {
    border-color: #3b82f6;
    background: #f8fafc;
  }

  &.active {
    background: #3b82f6;
    color: white;
    border-color: #3b82f6;
  }

  .material-icons {
    font-size: 1rem;
  }

  .filter-count {
    background: rgba(0, 0, 0, 0.1);
    padding: 0.125rem 0.375rem;
    border-radius: 8px;
    font-size: 0.75rem;
    font-weight: 600;
  }
}

/* Enhanced Lists Grid */
.lists-container {
  max-width: 1400px;
  margin: 0 auto;
}

.lists-grid {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));

  @media (min-width: 1200px) {
    grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
  }
}

/* Enhanced List Cards */
.list-card {
  background: white;
  border-radius: 16px;
  padding: 1.5rem;
  border: 1px solid #e5e7eb;
  cursor: pointer;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  position: relative;

  &:hover {
    transform: translateY(-4px);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
    border-color: #3b82f6;
  }

  &.touch-active {
    transform: scale(0.98);
  }

  &.archived {
    opacity: 0.6;
    background: #f9fafb;
  }

  &.has-activity {
    border-left: 4px solid #10b981;
  }

  &.collaborative {
    border-left: 4px solid #8b5cf6;
  }
}

.list-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  margin-bottom: 1rem;
}

.list-title-section {
  flex-grow: 1;
  min-width: 0;
}

.list-title {
  font-size: 1.125rem;
  font-weight: 600;
  color: #111827;
  margin: 0 0 0.5rem 0;
  line-height: 1.3;
}

.list-metadata {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.metadata-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.25rem 0.5rem;
  font-size: 0.75rem;
  font-weight: 500;
  border-radius: 6px;

  &.group {
    background: #f3f4f6;
    color: #6b7280;
  }

  &.recent {
    background: #dcfce7;
    color: #166534;
  }

  .material-icons {
    font-size: 0.875rem;
  }
}

.list-actions {
  position: relative;
}

.action-trigger {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border: none;
  background: none;
  color: #6b7280;
  border-radius: 6px;
  cursor: pointer;
  transition: all 0.2s ease;

  &:hover {
    background: #f3f4f6;
    color: #374151;
  }
}

.actions-dropdown {
  position: absolute;
  top: calc(100% + 0.5rem);
  right: 0;
  background: white;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  z-index: 10;
  min-width: 150px;
}

.dropdown-action {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  width: 100%;
  padding: 0.75rem 1rem;
  background: none;
  border: none;
  cursor: pointer;
  transition: background-color 0.2s ease;
  font-size: 0.875rem;
  text-align: left;

  &:hover {
    background: #f8f9fa;
  }

  &.danger {
    color: #ef4444;

    &:hover {
      background: #fef2f2;
    }
  }

  .material-icons {
    font-size: 1rem;
  }
}

.list-description {
  color: #6b7280;
  font-size: 0.875rem;
  line-height: 1.5;
  margin: 0 0 1rem 0;

  &.placeholder {
    font-style: italic;
    opacity: 0.7;
  }
}

/* Enhanced Items Preview */
.list-items-preview {
  margin-top: 1rem;
}

.completion-summary {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 1rem;
}

.completion-bar {
  flex-grow: 1;
  height: 6px;
  background: #e5e7eb;
  border-radius: 3px;
  overflow: hidden;
}

.completion-fill {
  height: 100%;
  background: linear-gradient(90deg, #10b981, #059669);
  border-radius: 3px;
  transition: width 0.3s ease;
}

.completion-text {
  font-size: 0.75rem;
  color: #6b7280;
  font-weight: 500;
  white-space: nowrap;
}

.items-preview-list {
  list-style: none;
  padding: 0;
  margin: 0 0 1rem 0;
}

.preview-item {
  margin-bottom: 0.5rem;

  &:last-child {
    margin-bottom: 0;
  }
}

.item-checkbox-label {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  cursor: pointer;
  padding: 0.25rem 0;
}

.item-checkbox {
  width: 1rem;
  height: 1rem;
  accent-color: #3b82f6;
  flex-shrink: 0;
}

.item-text {
  font-size: 0.875rem;
  color: #374151;
  line-height: 1.4;

  &.completed {
    text-decoration: line-through;
    color: #9ca3af;
  }
}

.more-items-indicator {
  padding: 0.5rem 0;
  border-top: 1px solid #f3f4f6;
  margin-top: 0.5rem;
}

.more-text {
  font-size: 0.75rem;
  color: #6b7280;
  font-style: italic;
}

/* Quick Add Input */
.quick-add-container {
  margin-top: 1rem;
  padding-top: 1rem;
  border-top: 1px solid #f3f4f6;
}

.quick-add-input {
  position: relative;
  display: flex;
  align-items: center;
}

.add-input {
  width: 100%;
  padding: 0.5rem 2rem 0.5rem 0.75rem;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  font-size: 0.875rem;
  transition: all 0.2s ease;

  &:focus {
    outline: none;
    border-color: #3b82f6;
    box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
  }

  &::placeholder {
    color: #9ca3af;
  }
}

.add-icon {
  position: absolute;
  right: 0.5rem;
  color: #9ca3af;
  font-size: 1.125rem;
  pointer-events: none;
}

/* Create List Card */
.create-list-card {
  background: linear-gradient(135deg, #f0f9ff, #e0f2fe);
  border: 2px dashed #3b82f6;
  border-radius: 16px;
  padding: 2rem;
  cursor: pointer;
  transition: all 0.3s ease;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 200px;

  &:hover {
    background: linear-gradient(135deg, #e0f2fe, #bae6fd);
    transform: translateY(-2px);
  }
}

.create-content {
  text-align: center;
}

.create-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3rem;
  height: 3rem;
  background: #3b82f6;
  color: white;
  border-radius: 50%;
  margin-bottom: 1rem;

  .material-icons {
    font-size: 1.5rem;
  }
}

.create-title {
  font-size: 1.125rem;
  font-weight: 600;
  color: #1f2937;
  margin: 0 0 0.5rem 0;
}

.create-subtitle {
  font-size: 0.875rem;
  color: #6b7280;
  margin: 0;
}

/* Transitions */
.dropdown-scale-enter-active,
.dropdown-scale-leave-active {
  transition: all 0.2s ease;
  transform-origin: top right;
}

.dropdown-scale-enter-from,
.dropdown-scale-leave-to {
  opacity: 0;
  transform: scale(0.9) translateY(-4px);
}

/* Dark mode support */
@media (prefers-color-scheme: dark) {
  .page-title {
    color: #f1f5f9;
  }

  .page-subtitle {
    color: #cbd5e1;
  }

  .list-card,
  .create-list-card,
  .filter-pill,
  .template-button,
  .loading-list-card {
    background: #334155;
    border-color: #475569;
    color: #f1f5f9;
  }

  .list-title {
    color: #f1f5f9;
  }

  .list-description,
  .item-text {
    color: #cbd5e1;
  }
}

/* Accessibility */
@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
</style>
