<template>
  <main class="neo-container page-padding">
    <div v-if="pageInitialLoad && !list && !error" class="text-center py-10">
      <VSpinner :label="$t('listDetailPage.loading.list')" size="lg" />
    </div>

    <VAlert v-else-if="error && !list" type="error" :message="error" class="mb-4">
      <template #actions>
        <VButton @click="fetchListDetails">{{ $t('listDetailPage.retryButton') }}</VButton>
      </template>
    </VAlert>

    <template v-else-if="list">
      <!-- Header -->
      <div class="neo-list-header">
        <VHeading :level="1" :text="list.name" class="mb-3 neo-title" />
        <div class="neo-header-actions">
          <VButton @click="showCostSummaryDialog = true" :disabled="!isOnline" icon-left="clipboard">{{ $t('listDetailPage.buttons.costSummary') }}
          </VButton>
          <VButton @click="openOcrDialog" :disabled="!isOnline" icon-left="plus">{{ $t('listDetailPage.buttons.addViaOcr') }}</VButton>
          <VBadge :text="list.group_id ? $t('listDetailPage.badges.groupList') : $t('listDetailPage.badges.personalList')" :variant="list.group_id ? 'accent' : 'settled'"
            class="neo-status" />
        </div>
      </div>
      <p v-if="list.description" class="neo-description">{{ list.description }}</p>

      <!-- Items List Section -->
      <VCard v-if="itemsAreLoading" class="py-10 text-center mt-4">
        <VSpinner :label="$t('listDetailPage.loading.items')" size="lg" />
      </VCard>
      <VCard v-else-if="!itemsAreLoading && list.items.length === 0" variant="empty-state" empty-icon="clipboard"
        :empty-title="$t('listDetailPage.items.emptyState.title')" :empty-message="$t('listDetailPage.items.emptyState.message')" class="mt-4" />
      <div v-else class="neo-item-list-container mt-4">
        <ul class="neo-item-list">
          <li v-for="item in list.items" :key="item.id" class="neo-list-item"
            :class="{ 'bg-gray-100 opacity-70': item.is_complete }">
            <div class="neo-item-content">
              <label class="neo-checkbox-label" @click.stop>
                <input type="checkbox" :checked="item.is_complete"
                  @change="(e) => confirmUpdateItem(item, (e.target as HTMLInputElement)?.checked ?? false)" />
                <span class="item-name" :class="{ 'line-through': item.is_complete }">{{ item.name }}</span>
                <span v-if="item.quantity" class="text-sm text-gray-500 ml-1">× {{ item.quantity }}</span>
              </label>
              <div class="neo-item-actions">
                <button class="neo-icon-button neo-edit-button" @click.stop="editItem(item)" :aria-label="$t('listDetailPage.items.editItemAriaLabel')">
                  <VIcon name="edit" />
                </button>
                <button class="neo-icon-button neo-delete-button" @click.stop="confirmDeleteItem(item)"
                  :disabled="item.deleting" :aria-label="$t('listDetailPage.items.deleteItemAriaLabel')">
                  <VIcon name="trash" />
                </button>
              </div>
            </div>
            <div v-if="item.is_complete" class="neo-price-input">
              <VInput type="number" :model-value="item.priceInput || ''" @update:modelValue="item.priceInput = $event"
                :placeholder="$t('listDetailPage.items.pricePlaceholder')" size="sm" class="w-24" step="0.01" @blur="updateItemPrice(item)"
                @keydown.enter.prevent="($event.target as HTMLInputElement).blur()" />
            </div>
          </li>
        </ul>
      </div>

      <!-- Add New Item Form -->
      <form @submit.prevent="onAddItem" class="add-item-form mt-4 p-4 border rounded-lg shadow flex items-center gap-2">
        <VIcon name="plus-circle" class="text-gray-400 shrink-0" />
        <VFormField class="flex-grow" :label="$t('listDetailPage.items.addItemForm.itemNameSrLabel')" :label-sr-only="true">
          <VInput v-model="newItem.name" :placeholder="$t('listDetailPage.items.addItemForm.placeholder')" required ref="itemNameInputRef" />
        </VFormField>
        <VFormField :label="$t('listDetailPage.items.addItemForm.quantitySrLabel')" :label-sr-only="true" class="w-24 shrink-0">
          <VInput type="number" :model-value="newItem.quantity || ''" @update:modelValue="newItem.quantity = $event"
            :placeholder="$t('listDetailPage.items.addItemForm.quantityPlaceholder')" min="1" />
        </VFormField>
        <VButton type="submit" :disabled="addingItem" class="shrink-0">
          <VSpinner v-if="addingItem" size="sm" />
          <span v-else>{{ $t('listDetailPage.buttons.addItem') }}</span>
        </VButton>
      </form>
    </template>

    <!-- Expenses Section (Original Content - Part 3 will refactor this) -->
    <section v-if="list && !itemsAreLoading" class="neo-expenses-section">
      <div class="neo-expenses-header">
        <h2 class="neo-expenses-title">{{ $t('listDetailPage.expensesSection.title') }}</h2>
        <button class="neo-action-button" @click="showCreateExpenseForm = true">
          <svg class="icon">
            <use xlink:href="#icon-plus" />
          </svg>
          {{ $t('listDetailPage.expensesSection.addExpenseButton') }}
        </button>
      </div>
      <div v-if="listDetailStore.isLoading && expenses.length === 0" class="neo-loading-state">
        <div class="spinner-dots" role="status"><span /><span /><span /></div>
        <p>{{ $t('listDetailPage.expensesSection.loading') }}</p>
      </div>
      <div v-else-if="listDetailStore.error" class="neo-error-state">
        <p>{{ listDetailStore.error }}</p> <!-- Assuming listDetailStore.error is a backend message or already translated if generic -->
        <button class="neo-button" @click="listDetailStore.fetchListWithExpenses(String(list?.id))">{{ $t('listDetailPage.expensesSection.retryButton') }}</button>
      </div>
      <div v-else-if="!expenses || expenses.length === 0" class="neo-empty-state">
        <p>{{ $t('listDetailPage.expensesSection.emptyState') }}</p>
      </div>
      <div v-else>
        <div v-for="expense in expenses" :key="expense.id" class="neo-expense-card">
          <div class="neo-expense-header">
            {{ expense.description }} - {{ formatCurrency(expense.total_amount) }}
            <span class="neo-expense-status" :class="getStatusClass(expense.overall_settlement_status)">
              {{ getOverallExpenseStatusText(expense.overall_settlement_status) }}
            </span>
          </div>
          <div class="neo-expense-details">
            {{ $t('listDetailPage.expensesSection.paidBy') }} <strong>{{ expense.paid_by_user?.name || expense.paid_by_user?.email || `User ID:
              ${expense.paid_by_user_id}` }}</strong>
            {{ $t('listDetailPage.expensesSection.onDate') }} {{ new Date(expense.expense_date).toLocaleDateString() }}
          </div>

          <div class="neo-splits-list">
            <div v-for="split in expense.splits" :key="split.id" class="neo-split-item">
              <div class="neo-split-details">
                <strong>{{ split.user?.name || split.user?.email || `User ID: ${split.user_id}` }}</strong> {{ $t('listDetailPage.expensesSection.owes') }} {{
                  formatCurrency(split.owed_amount) }}
                <span class="neo-expense-status" :class="getStatusClass(split.status)">
                  {{ getSplitStatusText(split.status) }}
                </span>
              </div>
              <div class="neo-split-details">
                {{ $t('listDetailPage.expensesSection.paidAmount') }} {{ getPaidAmountForSplitDisplay(split) }}
                <span v-if="split.paid_at"> {{ $t('listDetailPage.expensesSection.onDate') }} {{ new Date(split.paid_at).toLocaleDateString() }}</span>
              </div>
              <button v-if="split.user_id === authStore.user?.id && split.status !== ExpenseSplitStatusEnum.PAID"
                class="neo-button neo-button-primary" @click="openSettleShareModal(expense, split)"
                :disabled="isSettlementLoading">
                {{ $t('listDetailPage.expensesSection.settleShareButton') }}
              </button>
              <ul v-if="split.settlement_activities && split.settlement_activities.length > 0"
                class="neo-settlement-activities">
                <li v-for="activity in split.settlement_activities" :key="activity.id">
                  {{ $t('listDetailPage.expensesSection.activityLabel') }} {{ formatCurrency(activity.amount_paid) }} {{ $t('listDetailPage.expensesSection.byUser') }} {{ activity.payer?.name || `User
                  ${activity.paid_by_user_id}` }} {{ $t('listDetailPage.expensesSection.onDate') }} {{ new Date(activity.paid_at).toLocaleDateString() }}
                </li>
              </ul>
            </div>
          </div>
        </div>
      </div>
    </section>

    <!-- Create Expense Form (Original Content) -->
    <CreateExpenseForm v-if="showCreateExpenseForm" :list-id="list?.id" :group-id="list?.group_id ?? undefined"
      @close="showCreateExpenseForm = false" @created="handleExpenseCreated" />

    <!-- OCR Dialog -->
    <VModal v-model="showOcrDialogState" :title="$t('listDetailPage.modals.ocr.title')" @update:modelValue="!$event && closeOcrDialog()">
      <template #default>
        <div v-if="ocrLoading" class="text-center">
          <VSpinner :label="$t('listDetailPage.loading.ocrProcessing')" />
        </div>
        <VList v-else-if="ocrItems.length > 0">
          <VListItem v-for="(ocrItem, index) in ocrItems" :key="index">
            <div class="flex items-center gap-2">
              <VInput type="text" v-model="ocrItem.name" class="flex-grow" required />
              <VButton variant="danger" size="sm" :icon-only="true" iconLeft="trash"
                @click="ocrItems.splice(index, 1)" />
            </div>
          </VListItem>
        </VList>
        <VFormField v-else :label="$t('listDetailPage.modals.ocr.uploadLabel')" :error-message="ocrError || undefined">
          <VInput type="file" id="ocrFile" accept="image/*" @change="handleOcrFileUpload" ref="ocrFileInputRef"
            :model-value="''" />
        </VFormField>
      </template>
      <template #footer>
        <VButton variant="neutral" @click="closeOcrDialog">{{ $t('listDetailPage.buttons.cancel') }}</VButton>
        <VButton v-if="ocrItems.length > 0" type="button" variant="primary" @click="addOcrItems"
          :disabled="addingOcrItems">
          <VSpinner v-if="addingOcrItems" size="sm" :label="$t('listDetailPage.loading.addingOcrItems')" /> {{ $t('listDetailPage.buttons.addItems') }}
        </VButton>
      </template>
    </VModal>

    <!-- Confirmation Dialog -->
    <VModal v-model="showConfirmDialogState" :title="$t('listDetailPage.modals.confirmation.title')" @update:modelValue="!$event && cancelConfirmation()"
      size="sm">
      <template #default>
        <div class="text-center">
          <VIcon name="alert-triangle" size="lg" class="text-yellow-500 mb-2" />
          <p>{{ confirmDialogMessage }}</p>
        </div>
      </template>
      <template #footer>
        <VButton variant="neutral" @click="cancelConfirmation">{{ $t('listDetailPage.buttons.cancel') }}</VButton>
        <VButton variant="primary" @click="handleConfirmedAction">{{ $t('listDetailPage.buttons.confirm') }}</VButton>
      </template>
    </VModal>

    <!-- Cost Summary Dialog -->
    <VModal v-model="showCostSummaryDialog" :title="$t('listDetailPage.modals.costSummary.title')" @update:modelValue="showCostSummaryDialog = false"
      size="lg">
      <template #default>
        <div v-if="costSummaryLoading" class="text-center">
          <VSpinner :label="$t('listDetailPage.loading.costSummary')" />
        </div>
        <VAlert v-else-if="costSummaryError" type="error" :message="costSummaryError" />
        <div v-else-if="listCostSummary">
          <div class="mb-3 cost-overview">
            <p><strong>{{ $t('listDetailPage.costSummaryModal.totalCostLabel') }}</strong> {{ formatCurrency(listCostSummary.total_list_cost) }}</p>
            <p><strong>{{ $t('listDetailPage.costSummaryModal.equalShareLabel') }}</strong> {{ formatCurrency(listCostSummary.equal_share_per_user) }}</p>
            <p><strong>{{ $t('listDetailPage.costSummaryModal.participantsLabel') }}</strong> {{ listCostSummary.num_participating_users }}</p>
          </div>
          <h4>{{ $t('listDetailPage.costSummaryModal.userBalancesHeader') }}</h4>
          <div class="table-container mt-2">
            <table class="table">
              <thead>
                <tr>
                  <th>{{ $t('listDetailPage.costSummaryModal.tableHeaders.user') }}</th>
                  <th class="text-right">{{ $t('listDetailPage.costSummaryModal.tableHeaders.itemsAddedValue') }}</th>
                  <th class="text-right">{{ $t('listDetailPage.costSummaryModal.tableHeaders.amountDue') }}</th>
                  <th class="text-right">{{ $t('listDetailPage.costSummaryModal.tableHeaders.balance') }}</th>
                </tr>
              </thead>
              <tbody>
                <tr v-for="userShare in listCostSummary.user_balances" :key="userShare.user_id">
                  <td>{{ userShare.user_identifier }}</td>
                  <td class="text-right">{{ formatCurrency(userShare.items_added_value) }}</td>
                  <td class="text-right">{{ formatCurrency(userShare.amount_due) }}</td>
                  <td class="text-right">
                    <VBadge :text="formatCurrency(userShare.balance)"
                      :variant="parseFloat(String(userShare.balance)) >= 0 ? 'settled' : 'pending'" />
                  </td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>
        <p v-else>{{ $t('listDetailPage.costSummaryModal.emptyState') }}</p>
      </template>
      <template #footer>
        <VButton variant="primary" @click="showCostSummaryDialog = false">{{ $t('listDetailPage.buttons.close') }}</VButton>
      </template>
    </VModal>

    <!-- Settle Share Modal -->
    <VModal v-model="showSettleModal" :title="$t('listDetailPage.settleShareModal.title')" @update:modelValue="!$event && closeSettleShareModal()"
      size="md">
      <template #default>
        <div v-if="isSettlementLoading" class="text-center">
          <VSpinner :label="$t('listDetailPage.loading.settlement')" />
        </div>
        <VAlert v-else-if="settleAmountError" type="error" :message="settleAmountError" />
        <div v-else>
          <p>{{ $t('listDetailPage.settleShareModal.settleAmountFor', { userName: selectedSplitForSettlement?.user?.name || selectedSplitForSettlement?.user?.email || `User ID: ${selectedSplitForSettlement?.user_id}` }) }}</p>
          <VFormField :label="$t('listDetailPage.settleShareModal.amountLabel')" :error-message="settleAmountError || undefined">
            <VInput type="number" v-model="settleAmount" id="settleAmount" required />
          </VFormField>
        </div>
      </template>
      <template #footer>
        <VButton variant="neutral" @click="closeSettleShareModal">{{ $t('listDetailPage.settleShareModal.cancelButton') }}</VButton>
        <VButton variant="primary" @click="handleConfirmSettle">{{ $t('listDetailPage.settleShareModal.confirmButton') }}</VButton>
      </template>
    </VModal>

    <!-- Edit Item Dialog -->
    <VModal v-model="showEditDialog" :title="$t('listDetailPage.modals.editItem.title')" @update:modelValue="!$event && closeEditDialog()">
      <template #default>
        <VFormField v-if="editingItem" :label="$t('listDetailPage.modals.editItem.nameLabel')" class="mb-4">
          <VInput type="text" id="editItemName" v-model="editingItem.name" required />
        </VFormField>
        <VFormField v-if="editingItem" :label="$t('listDetailPage.modals.editItem.quantityLabel')">
          <VInput type="number" id="editItemQuantity" :model-value="editingItem.quantity || ''"
            @update:modelValue="editingItem.quantity = $event" min="1" />
        </VFormField>
      </template>
      <template #footer>
        <VButton variant="neutral" @click="closeEditDialog">{{ $t('listDetailPage.buttons.cancel') }}</VButton>
        <VButton variant="primary" @click="handleConfirmEdit" :disabled="!editingItem?.name.trim()">{{ $t('listDetailPage.buttons.saveChanges') }}
        </VButton>
      </template>
    </VModal>

    <VAlert v-if="!list && !pageInitialLoad" type="info" :message="$t('listDetailPage.errors.genericLoadFailure')" />
  </main>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted, watch, nextTick, computed } from 'vue';
import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n';
import { apiClient, API_ENDPOINTS } from '@/config/api'; // Keep for item management
import { useEventListener, useFileDialog, useNetwork } from '@vueuse/core'; // onClickOutside removed
import { useNotificationStore } from '@/stores/notifications';
import { useOfflineStore, type CreateListItemPayload } from '@/stores/offline';
import { useListDetailStore } from '@/stores/listDetailStore';
import type { ListWithExpenses } from '@/types/list';
import type { Expense, ExpenseSplit } from '@/types/expense';
import { ExpenseOverallStatusEnum, ExpenseSplitStatusEnum } from '@/types/expense';
import { useAuthStore } from '@/stores/auth';
import { Decimal } from 'decimal.js';
import type { SettlementActivityCreate } from '@/types/expense';
import SettleShareModal from '@/components/SettleShareModal.vue';
import CreateExpenseForm from '@/components/CreateExpenseForm.vue';
import type { Item } from '@/types/item';
import VHeading from '@/components/valerie/VHeading.vue';
import VSpinner from '@/components/valerie/VSpinner.vue';
import VAlert from '@/components/valerie/VAlert.vue';
import VButton from '@/components/valerie/VButton.vue';
import VBadge from '@/components/valerie/VBadge.vue';
import VIcon from '@/components/valerie/VIcon.vue';
import VModal from '@/components/valerie/VModal.vue';
import VFormField from '@/components/valerie/VFormField.vue';
import VInput from '@/components/valerie/VInput.vue';
import VList from '@/components/valerie/VList.vue';
import VListItem from '@/components/valerie/VListItem.vue';
import VCheckbox from '@/components/valerie/VCheckbox.vue';
// VTextarea and VSelect are not used in this part of the refactor for ListDetailPage

const { t } = useI18n();

// UI-specific properties that we add to items
interface ItemWithUI extends Item {
  updating: boolean;
  deleting: boolean;
  priceInput: string | number | null;
  swiped: boolean;
}

interface List {
  id: number;
  name: string;
  description?: string;
  is_complete: boolean;
  items: ItemWithUI[];
  version: number;
  updated_at: string;
  group_id?: number;
}

interface UserCostShare {
  user_id: number;
  user_identifier: string;
  items_added_value: string | number;
  amount_due: string | number;
  balance: string | number;
}

interface ListCostSummaryData {
  list_id: number;
  list_name: string;
  total_list_cost: string | number;
  num_participating_users: number;
  equal_share_per_user: string | number;
  user_balances: UserCostShare[];
}

const route = useRoute();
const { isOnline } = useNetwork();
const notificationStore = useNotificationStore();
const offlineStore = useOfflineStore();
const list = ref<List | null>(null);
const pageInitialLoad = ref(true); // True until shell is loaded or first fetch begins
const itemsAreLoading = ref(false); // True when items are actively being fetched/processed
const error = ref<string | null>(null); // For page-level errors
const addingItem = ref(false);
const pollingInterval = ref<ReturnType<typeof setInterval> | null>(null);
const lastListUpdate = ref<string | null>(null);
const lastItemUpdate = ref<string | null>(null);

const newItem = ref<{ name: string; quantity?: number }>({ name: '' });
const itemNameInputRef = ref<InstanceType<typeof VInput> | null>(null); // Changed type

// OCR
const showOcrDialogState = ref(false);
// const ocrModalRef = ref<HTMLElement | null>(null); // Removed
const ocrLoading = ref(false);
const ocrItems = ref<{ name: string }[]>([]); // Items extracted from OCR
const addingOcrItems = ref(false);
const ocrError = ref<string | null>(null);
const ocrFileInputRef = ref<InstanceType<typeof VInput> | null>(null); // Changed to VInput ref type
const { files: ocrFiles, reset: resetOcrFileDialog } = useFileDialog({
  accept: 'image/*',
  multiple: false,
});


// Confirmation Dialog
const showConfirmDialogState = ref(false);
// const confirmModalRef = ref<HTMLElement | null>(null); // Removed
const confirmDialogMessage = ref('');
const pendingAction = ref<(() => Promise<void>) | null>(null);

// Cost Summary
const showCostSummaryDialog = ref(false);
// const costSummaryModalRef = ref<HTMLElement | null>(null); // Removed
const listCostSummary = ref<ListCostSummaryData | null>(null);
const costSummaryLoading = ref(false);
const costSummaryError = ref<string | null>(null);

// Settle Share
const authStore = useAuthStore();
const showSettleModal = ref(false);
// const settleModalRef = ref<HTMLElement | null>(null); // Removed
const selectedSplitForSettlement = ref<ExpenseSplit | null>(null);
const parentExpenseOfSelectedSplit = ref<Expense | null>(null);
const settleAmount = ref<string>('');
const settleAmountError = ref<string | null>(null);
const isSettlementLoading = computed(() => listDetailStore.isSettlingSplit);

// Create Expense
const showCreateExpenseForm = ref(false);

// Edit Item
const showEditDialog = ref(false);
// const editModalRef = ref<HTMLElement | null>(null); // Removed
const editingItem = ref<Item | null>(null);

// onClickOutside for ocrModalRef, costSummaryModalRef, etc. are removed as VModal handles this.


const formatCurrency = (value: string | number | undefined | null): string => {
  if (value === undefined || value === null) return '$0.00';
  // Ensure that string "0.00" or "0" are handled correctly before parseFloat
  if (typeof value === 'string' && !value.trim()) return '$0.00';
  const numValue = typeof value === 'string' ? parseFloat(value) : value;
  return isNaN(numValue) ? '$0.00' : `$${numValue.toFixed(2)}`;
};

const processListItems = (items: Item[]): ItemWithUI[] => {
  return items.map(item => ({
    ...item,
    updating: false,
    deleting: false,
    priceInput: item.price || null,
    swiped: false
  }));
};

const fetchListDetails = async () => {
  if (pageInitialLoad.value) {
    pageInitialLoad.value = false;
  }
  itemsAreLoading.value = true;
  const routeId = String(route.params.id);
  const cachedFullData = sessionStorage.getItem(`listDetailFull_${routeId}`);

  try {
    let response;
    if (cachedFullData) {
      response = { data: JSON.parse(cachedFullData) };
      sessionStorage.removeItem(`listDetailFull_${routeId}`);
    } else {
      response = await apiClient.get(API_ENDPOINTS.LISTS.BY_ID(routeId));
    }

    const rawList = response.data as ListWithExpenses;
    const localList: List = {
      id: rawList.id,
      name: rawList.name,
      description: rawList.description ?? undefined,
      is_complete: rawList.is_complete,
      items: processListItems(rawList.items),
      version: rawList.version,
      updated_at: rawList.updated_at,
      group_id: rawList.group_id ?? undefined
    };
    list.value = localList;
    lastListUpdate.value = rawList.updated_at;
    lastItemUpdate.value = rawList.items.reduce((latest: string, item: Item) => {
      return item.updated_at > latest ? item.updated_at : latest;
    }, '');
    if (showCostSummaryDialog.value) {
      await fetchListCostSummary();
    }
  } catch (err: unknown) {
    const apiErrorMessage = err instanceof Error ? err.message : String(err);
    const fallbackErrorMessage = t('listDetailPage.errors.fetchFailed');
    if (!list.value) {
      error.value = apiErrorMessage || fallbackErrorMessage;
    } else {
      notificationStore.addNotification({ message: t('listDetailPage.errors.fetchItemsFailed', { errorMessage: apiErrorMessage }), type: 'error' });
    }
  } finally {
    itemsAreLoading.value = false;
    if (!list.value && !error.value) {
      pageInitialLoad.value = false;
    }
  }
};

const checkForUpdates = async () => {
  if (!list.value) return;
  try {
    const response = await apiClient.get(API_ENDPOINTS.LISTS.BY_ID(String(list.value.id)));
    const { updated_at: newListUpdatedAt, items: newItems } = response.data as ListWithExpenses;
    const newLastItemUpdate = newItems.reduce((latest: string, item: Item) =>
      item.updated_at > latest ? item.updated_at : latest,
      '');

    if ((lastListUpdate.value && newListUpdatedAt > lastListUpdate.value) ||
      (lastItemUpdate.value && newLastItemUpdate > lastItemUpdate.value)) {
      await fetchListDetails();
    }
  } catch (err) {
    console.warn('Polling for updates failed:', err);
  }
};

const startPolling = () => {
  stopPolling();
  pollingInterval.value = setInterval(() => checkForUpdates(), 15000);
};
const stopPolling = () => {
  if (pollingInterval.value) clearInterval(pollingInterval.value);
};

const isItemPendingSync = (item: Item) => {
  return offlineStore.pendingActions.some(action => {
    if (action.type === 'update_list_item' || action.type === 'delete_list_item') {
      const payload = action.payload as { listId: string; itemId: string };
      return payload.itemId === String(item.id);
    }
    return false;
  });
};

const onAddItem = async () => {
  if (!list.value || !newItem.value.name.trim()) {
    notificationStore.addNotification({ message: t('listDetailPage.notifications.enterItemName'), type: 'warning' });
    if (itemNameInputRef.value?.$el) {
      (itemNameInputRef.value.$el as HTMLElement).focus();
    }
    return;
  }
  addingItem.value = true;

  if (!isOnline.value) {
    const offlinePayload: any = { // Define explicit type later if needed
      name: newItem.value.name
    };
    if (typeof newItem.value.quantity !== 'undefined') {
      offlinePayload.quantity = String(newItem.value.quantity);
    }
    offlineStore.addAction({
      type: 'create_list_item',
      payload: {
        listId: String(list.value.id),
        itemData: offlinePayload
      }
    });
    const optimisticItem: ItemWithUI = {
      id: Date.now(), // Temporary ID for offline
      name: newItem.value.name,
      quantity: typeof newItem.value.quantity === 'string' ? Number(newItem.value.quantity) : (newItem.value.quantity || null),
      is_complete: false,
      price: null,
      version: 1, // Assuming initial version
      updated_at: new Date().toISOString(),
      created_at: new Date().toISOString(),
      list_id: list.value.id,
      updating: false,
      deleting: false,
      priceInput: null,
      swiped: false
    };
    list.value.items.push(optimisticItem);
    newItem.value = { name: '' };
    if (itemNameInputRef.value?.$el) {
      (itemNameInputRef.value.$el as HTMLElement).focus();
    }
    addingItem.value = false;
    notificationStore.addNotification({ message: t('listDetailPage.notifications.itemAddedSuccess'), type: 'success' }); // Optimistic UI
    return;
  }

  try {
    const response = await apiClient.post(
      API_ENDPOINTS.LISTS.ITEMS(String(list.value.id)),
      {
        name: newItem.value.name,
        quantity: newItem.value.quantity ? String(newItem.value.quantity) : null
      }
    );
    const addedItem = response.data as Item;
    list.value.items.push(processListItems([addedItem])[0]);
    newItem.value = { name: '' };
    if (itemNameInputRef.value?.$el) {
      (itemNameInputRef.value.$el as HTMLElement).focus();
    }
    notificationStore.addNotification({ message: t('listDetailPage.notifications.itemAddedSuccess'), type: 'success' });
  } catch (err) {
    notificationStore.addNotification({ message: (err instanceof Error ? err.message : String(err)) || t('listDetailPage.errors.addItemFailed'), type: 'error' });
  } finally {
    addingItem.value = false;
  }
};

const updateItem = async (item: ItemWithUI, newCompleteStatus: boolean) => {
  if (!list.value) return;
  item.updating = true;
  const originalCompleteStatus = item.is_complete;
  item.is_complete = newCompleteStatus;

  if (!isOnline.value) {
    offlineStore.addAction({
      type: 'update_list_item',
      payload: {
        listId: String(list.value.id),
        itemId: String(item.id),
        data: {
          completed: newCompleteStatus
        },
        version: item.version
      }
    });
    item.updating = false;
    notificationStore.addNotification({ message: t('listDetailPage.notifications.itemUpdatedSuccess'), type: 'success' }); // Optimistic UI
    return;
  }

  try {
    await apiClient.put(
      API_ENDPOINTS.LISTS.ITEM(String(list.value.id), String(item.id)),
      { completed: newCompleteStatus, version: item.version }
    );
    item.version++;
    notificationStore.addNotification({ message: t('listDetailPage.notifications.itemUpdatedSuccess'), type: 'success' });
  } catch (err) {
    item.is_complete = originalCompleteStatus; // Revert optimistic update
    notificationStore.addNotification({ message: (err instanceof Error ? err.message : String(err)) || t('listDetailPage.errors.updateItemFailed'), type: 'error' });
  } finally {
    item.updating = false;
  }
};

const updateItemPrice = async (item: ItemWithUI) => {
  if (!list.value || !item.is_complete) return;
  const newPrice = item.priceInput !== undefined && String(item.priceInput).trim() !== '' ? parseFloat(String(item.priceInput)) : null;
  if (item.price === newPrice?.toString()) return; // No change
  item.updating = true;
  const originalPrice = item.price;
  const originalPriceInput = item.priceInput;
  item.price = newPrice?.toString() || null; // Optimistic update

  if (!isOnline.value) {
    offlineStore.addAction({
      type: 'update_list_item',
      payload: {
        listId: String(list.value.id),
        itemId: String(item.id),
        data: {
          price: newPrice ?? null, // Ensure null is sent if cleared
          completed: item.is_complete // Keep completion status
        },
        version: item.version
      }
    });
    item.updating = false;
    notificationStore.addNotification({ message: t('listDetailPage.notifications.itemUpdatedSuccess'), type: 'success' }); // Optimistic UI
    return;
  }

  try {
    await apiClient.put(
      API_ENDPOINTS.LISTS.ITEM(String(list.value.id), String(item.id)),
      { price: newPrice?.toString(), completed: item.is_complete, version: item.version }
    );
    item.version++;
    notificationStore.addNotification({ message: t('listDetailPage.notifications.itemUpdatedSuccess'), type: 'success' });
  } catch (err) {
    item.price = originalPrice; // Revert optimistic update
    item.priceInput = originalPriceInput;
    notificationStore.addNotification({ message: (err instanceof Error ? err.message : String(err)) || t('listDetailPage.errors.updateItemPriceFailed'), type: 'error' });
  } finally {
    item.updating = false;
  }
};

const deleteItem = async (item: ItemWithUI) => {
  if (!list.value) return;
  item.deleting = true;
  const originalItems = [...list.value.items]; // For potential revert

  if (!isOnline.value) {
    offlineStore.addAction({
      type: 'delete_list_item',
      payload: {
        listId: String(list.value.id),
        itemId: String(item.id)
      }
    });
    list.value.items = list.value.items.filter(i => i.id !== item.id); // Optimistic UI
    item.deleting = false;
    notificationStore.addNotification({ message: t('listDetailPage.notifications.itemDeleteSuccess'), type: 'success' });
    return;
  }

  try {
    await apiClient.delete(API_ENDPOINTS.LISTS.ITEM(String(list.value.id), String(item.id)));
    list.value.items = list.value.items.filter(i => i.id !== item.id);
    notificationStore.addNotification({ message: t('listDetailPage.notifications.itemDeleteSuccess'), type: 'success' });
  } catch (err) {
    list.value.items = originalItems; // Revert optimistic UI
    notificationStore.addNotification({ message: (err instanceof Error ? err.message : String(err)) || t('listDetailPage.errors.deleteItemFailed'), type: 'error' });
  } finally {
    item.deleting = false;
  }
};

const confirmUpdateItem = (item: ItemWithUI, newCompleteStatus: boolean) => {
  confirmDialogMessage.value = t('listDetailPage.confirmations.updateMessage', {
    itemName: item.name,
    status: newCompleteStatus ? t('listDetailPage.confirmations.statusComplete') : t('listDetailPage.confirmations.statusIncomplete')
  });
  pendingAction.value = () => updateItem(item, newCompleteStatus);
  showConfirmDialogState.value = true;
};

const confirmDeleteItem = (item: ItemWithUI) => {
  confirmDialogMessage.value = t('listDetailPage.confirmations.deleteMessage', { itemName: item.name });
  pendingAction.value = () => deleteItem(item);
  showConfirmDialogState.value = true;
};

const handleConfirmedAction = async () => {
  if (pendingAction.value) {
    await pendingAction.value();
  }
  cancelConfirmation();
};
const cancelConfirmation = () => {
  showConfirmDialogState.value = false;
  pendingAction.value = null;
  confirmDialogMessage.value = ''; // Clear message
};

const openOcrDialog = () => {
  ocrItems.value = [];
  ocrError.value = null;
  resetOcrFileDialog(); // From useFileDialog
  showOcrDialogState.value = true;
  nextTick(() => {
    if (ocrFileInputRef.value && ocrFileInputRef.value.$el) {
      const inputElement = ocrFileInputRef.value.$el.querySelector('input[type="file"]') || ocrFileInputRef.value.$el;
      if (inputElement) (inputElement as HTMLInputElement).value = '';
    } else if (ocrFileInputRef.value) { // Native input
      (ocrFileInputRef.value as any).value = '';
    }
  });
};
const closeOcrDialog = () => {
  showOcrDialogState.value = false;
  ocrItems.value = [];
  ocrError.value = null;
};

watch(ocrFiles, async (newFiles) => {
  if (newFiles && newFiles.length > 0) {
    const file = newFiles[0];
    await handleOcrUpload(file);
  }
});

const handleOcrFileUpload = (event: Event) => {
  const target = event.target as HTMLInputElement;
  if (target.files && target.files.length > 0) {
    handleOcrUpload(target.files[0]);
  }
};

const handleOcrUpload = async (file: File) => {
  if (!file) return;
  ocrLoading.value = true;
  ocrError.value = null;
  ocrItems.value = [];
  try {
    const formData = new FormData();
    formData.append('image_file', file);
    const response = await apiClient.post(API_ENDPOINTS.OCR.PROCESS, formData, {
      headers: { 'Content-Type': 'multipart/form-data' }
    });
    ocrItems.value = response.data.extracted_items.map((nameStr: string) => ({ name: nameStr.trim() })).filter((item: { name: string }) => item.name);
    if (ocrItems.value.length === 0) {
      ocrError.value = t('listDetailPage.errors.ocrNoItems');
    }
  } catch (err) {
    ocrError.value = (err instanceof Error ? err.message : String(err)) || t('listDetailPage.errors.ocrFailed');
  } finally {
    ocrLoading.value = false;
    // Reset file input
    if (ocrFileInputRef.value && ocrFileInputRef.value.$el) {
      const inputElement = ocrFileInputRef.value.$el.querySelector('input[type="file"]') || ocrFileInputRef.value.$el;
      if (inputElement) (inputElement as HTMLInputElement).value = '';
    } else if (ocrFileInputRef.value) { // Native input
       (ocrFileInputRef.value as any).value = '';
    }
  }
};

const addOcrItems = async () => {
  if (!list.value || !ocrItems.value.length) return;
  addingOcrItems.value = true;
  let successCount = 0;
  try {
    for (const item of ocrItems.value) {
      if (!item.name.trim()) continue;
      const response = await apiClient.post(
        API_ENDPOINTS.LISTS.ITEMS(String(list.value.id)),
        { name: item.name, quantity: "1" } // Default quantity 1
      );
      const addedItem = response.data as Item;
      list.value.items.push(processListItems([addedItem])[0]);
      successCount++;
    }
    if (successCount > 0) {
      notificationStore.addNotification({ message: t('listDetailPage.notifications.itemsAddedSuccessOcr', { count: successCount }), type: 'success' });
    }
    closeOcrDialog();
  } catch (err) {
    notificationStore.addNotification({ message: (err instanceof Error ? err.message : String(err)) || t('listDetailPage.errors.addOcrItemsFailed'), type: 'error' });
  } finally {
    addingOcrItems.value = false;
  }
};

const fetchListCostSummary = async () => {
  if (!list.value || list.value.id === 0) return;
  costSummaryLoading.value = true;
  costSummaryError.value = null;
  try {
    const response = await apiClient.get(API_ENDPOINTS.COSTS.LIST_SUMMARY(list.value.id));
    listCostSummary.value = response.data;
  } catch (err) {
    costSummaryError.value = (err instanceof Error ? err.message : String(err)) || t('listDetailPage.errors.loadCostSummaryFailed');
    listCostSummary.value = null;
  } finally {
    costSummaryLoading.value = false;
  }
};
watch(showCostSummaryDialog, (newVal) => {
  if (newVal && (!listCostSummary.value || listCostSummary.value.list_id !== list.value?.id)) {
    fetchListCostSummary();
  }
});

// --- Expense and Settlement Status Logic ---
const listDetailStore = useListDetailStore();
const expenses = computed(() => listDetailStore.getExpenses);

const getPaidAmountForSplitDisplay = (split: ExpenseSplit): string => {
  const amount = listDetailStore.getPaidAmountForSplit(split.id);
  return formatCurrency(amount);
};

const getSplitStatusText = (status: ExpenseSplitStatusEnum): string => {
  switch (status) {
    case ExpenseSplitStatusEnum.PAID: return t('listDetailPage.status.paid');
    case ExpenseSplitStatusEnum.PARTIALLY_PAID: return t('listDetailPage.status.partiallyPaid');
    case ExpenseSplitStatusEnum.UNPAID: return t('listDetailPage.status.unpaid');
    default: return t('listDetailPage.status.unknown');
  }
};

const getOverallExpenseStatusText = (status: ExpenseOverallStatusEnum): string => {
  switch (status) {
    case ExpenseOverallStatusEnum.PAID: return t('listDetailPage.status.settled');
    case ExpenseOverallStatusEnum.PARTIALLY_PAID: return t('listDetailPage.status.partiallySettled');
    case ExpenseOverallStatusEnum.UNPAID: return t('listDetailPage.status.unsettled');
    default: return t('listDetailPage.status.unknown');
  }
};

const getStatusClass = (status: ExpenseSplitStatusEnum | ExpenseOverallStatusEnum): string => {
  if (status === ExpenseSplitStatusEnum.PAID || status === ExpenseOverallStatusEnum.PAID) return 'status-paid';
  if (status === ExpenseSplitStatusEnum.PARTIALLY_PAID || status === ExpenseOverallStatusEnum.PARTIALLY_PAID) return 'status-partially_paid';
  if (status === ExpenseSplitStatusEnum.UNPAID || status === ExpenseOverallStatusEnum.UNPAID) return 'status-unpaid';
  return '';
};

// Keyboard shortcut
useEventListener(window, 'keydown', (event: KeyboardEvent) => {
  if (event.key === 'n' && !event.ctrlKey && !event.metaKey && !event.altKey) {
    const activeElement = document.activeElement;
    if (activeElement && (activeElement.tagName === 'INPUT' || activeElement.tagName === 'TEXTAREA')) {
      return; // Don't interfere with typing
    }
    // Check if any modal is open, if so, don't trigger
    if (showOcrDialogState.value || showCostSummaryDialog.value || showConfirmDialogState.value || showEditDialog.value || showSettleModal.value || showCreateExpenseForm.value) {
      return;
    }
    event.preventDefault();
    if (itemNameInputRef.value?.$el) { // Focus the add item input
      (itemNameInputRef.value.$el as HTMLElement).focus();
    }
  }
});

let touchStartX = 0;
const SWIPE_THRESHOLD = 50; // Pixels

const handleTouchStart = (event: TouchEvent) => {
  touchStartX = event.changedTouches[0].clientX;
};

const handleTouchMove = (event: TouchEvent, item: ItemWithUI) => {
  // This function might be used for swipe-to-reveal actions in the future
  // For now, it's a placeholder or can be removed if not used.
};

const handleTouchEnd = (event: TouchEvent, item: ItemWithUI) => {
  // This function might be used for swipe-to-reveal actions in the future
  // For now, it's a placeholder or can be removed if not used.
};


onMounted(() => {
  pageInitialLoad.value = true;
  itemsAreLoading.value = false;
  error.value = null;

  if (!route.params.id) {
    error.value = t('listDetailPage.errors.fetchFailed'); // Generic error if no ID
    pageInitialLoad.value = false;
    listDetailStore.setError(t('listDetailPage.errors.fetchFailed'));
    return;
  }

  const listShellJSON = sessionStorage.getItem('listDetailShell');
  const routeId = String(route.params.id);

  if (listShellJSON) {
    const shellData = JSON.parse(listShellJSON);
    if (shellData.id === parseInt(routeId, 10)) {
      list.value = {
        id: shellData.id,
        name: shellData.name,
        description: shellData.description,
        is_complete: false,
        items: [],
        version: 0,
        updated_at: new Date().toISOString(),
        group_id: shellData.group_id,
      };
      pageInitialLoad.value = false;
    } else {
      sessionStorage.removeItem('listDetailShell');
    }
  }

  fetchListDetails().then(() => {
    startPolling();
  });
  const routeParamsId = route.params.id;
  listDetailStore.fetchListWithExpenses(String(routeParamsId));
});

onUnmounted(() => {
  stopPolling();
});

const editItem = (item: Item) => {
  editingItem.value = { ...item }; // Clone item for editing
  showEditDialog.value = true;
};

const closeEditDialog = () => {
  showEditDialog.value = false;
  editingItem.value = null;
};

const handleConfirmEdit = async () => {
  if (!editingItem.value || !list.value) return;

  const itemToUpdate = editingItem.value; // Already a clone

  try {
    const response = await apiClient.put(
      API_ENDPOINTS.LISTS.ITEM(String(list.value.id), String(itemToUpdate.id)),
      {
        name: itemToUpdate.name,
        quantity: itemToUpdate.quantity?.toString(), // Ensure quantity is string or null
        version: itemToUpdate.version
      }
    );

    const updatedItemFromApi = response.data as Item;
    const index = list.value.items.findIndex(i => i.id === updatedItemFromApi.id);
    if (index !== -1) {
      list.value.items[index] = processListItems([updatedItemFromApi])[0];
    }

    notificationStore.addNotification({
      message: 'Item updated successfully',
      type: 'success'
    });
    closeEditDialog();
  } catch (err) {
    notificationStore.addNotification({
      message: (err instanceof Error ? err.message : String(err)) || t('listDetailPage.errors.updateItemFailed'),
      type: 'error'
    });
  }
};

const openSettleShareModal = (expense: Expense, split: ExpenseSplit) => {
  if (split.user_id !== authStore.user?.id) {
    notificationStore.addNotification({ message: t('listDetailPage.notifications.cannotSettleOthersShares'), type: 'warning' });
    return;
  }
  selectedSplitForSettlement.value = split;
  parentExpenseOfSelectedSplit.value = expense;
  const alreadyPaid = new Decimal(listDetailStore.getPaidAmountForSplit(split.id));
  const owed = new Decimal(split.owed_amount);
  const remaining = owed.minus(alreadyPaid);
  settleAmount.value = remaining.toFixed(2);
  settleAmountError.value = null;
  showSettleModal.value = true;
};

const closeSettleShareModal = () => {
  showSettleModal.value = false;
  selectedSplitForSettlement.value = null;
  parentExpenseOfSelectedSplit.value = null;
  settleAmount.value = '';
  settleAmountError.value = null;
};

const validateSettleAmount = (): boolean => {
  settleAmountError.value = null;
  if (!settleAmount.value.trim()) {
    settleAmountError.value = t('listDetailPage.settleShareModal.errors.enterAmount');
    return false;
  }
  const amount = new Decimal(settleAmount.value);
  if (amount.isNaN() || amount.isNegative() || amount.isZero()) {
    settleAmountError.value = t('listDetailPage.settleShareModal.errors.positiveAmount');
    return false;
  }
  if (selectedSplitForSettlement.value) {
    const alreadyPaid = new Decimal(listDetailStore.getPaidAmountForSplit(selectedSplitForSettlement.value.id));
    const owed = new Decimal(selectedSplitForSettlement.value.owed_amount);
    const remaining = owed.minus(alreadyPaid);
    if (amount.greaterThan(remaining.plus(new Decimal('0.001')))) {
      settleAmountError.value = t('listDetailPage.settleShareModal.errors.exceedsRemaining', { amount: formatCurrency(remaining.toFixed(2)) });
      return false;
    }
  } else {
    settleAmountError.value = t('listDetailPage.settleShareModal.errors.noSplitSelected');
    return false;
  }
  return true;
};

const currentListIdForRefetch = computed(() => listDetailStore.currentList?.id || null);

const handleConfirmSettle = async () => {
  if (!selectedSplitForSettlement.value || !authStore.user?.id || !currentListIdForRefetch.value) {
    notificationStore.addNotification({ message: t('listDetailPage.notifications.settlementDataMissing'), type: 'error' });
    return;
  }

  const activityData: SettlementActivityCreate = {
    expense_split_id: selectedSplitForSettlement.value.id,
    paid_by_user_id: Number(authStore.user.id),
    amount_paid: new Decimal(settleAmount.value).toString(),
    paid_at: new Date().toISOString(),
  };

  const success = await listDetailStore.settleExpenseSplit({
    list_id_for_refetch: String(currentListIdForRefetch.value),
    expense_split_id: selectedSplitForSettlement.value.id,
    activity_data: activityData,
  });

  if (success) {
    notificationStore.addNotification({ message: t('listDetailPage.notifications.settleShareSuccess'), type: 'success' });
    closeSettleShareModal();
  } else {
    notificationStore.addNotification({ message: listDetailStore.error || t('listDetailPage.notifications.settleShareFailed'), type: 'error' });
  }
};

const handleExpenseCreated = (expense: any) => {
  if (list.value?.id) {
    listDetailStore.fetchListWithExpenses(String(list.value.id));
  }
};

</script>

<style scoped>
/* Existing styles */

.neo-expenses-section {
  margin-top: 3rem;
  padding: 1.5rem;
  border: 3px solid #111;
  border-radius: 18px;
  background: #fdfdfd;
  /* Slightly different background for distinction */
  box-shadow: 6px 6px 0 #111;
}

.neo-expenses-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 1rem;
}

.neo-expenses-title {
  font-size: 2rem;
  font-weight: 900;
  margin-bottom: 1.5rem;
  text-align: center;
  color: #111;
}

.neo-expense-card {
  background: #fff;
  border: 2px solid #111;
  border-radius: 12px;
  margin-bottom: 1.5rem;
  padding: 1rem;
  box-shadow: 4px 4px 0 #ddd;
}

.neo-expense-header {
  font-size: 1.3rem;
  font-weight: 700;
  margin-bottom: 0.5rem;
}

.neo-expense-details,
.neo-split-details {
  font-size: 0.95rem;
  color: #333;
  margin-bottom: 0.3rem;
}

.neo-expense-details strong,
.neo-split-details strong {
  color: #111;
}

.neo-expense-status {
  display: inline-block;
  padding: 0.25em 0.6em;
  font-size: 0.85em;
  font-weight: 700;
  line-height: 1;
  text-align: center;
  white-space: nowrap;
  vertical-align: baseline;
  border-radius: 0.375rem;
  /* Tailwind's rounded-md */
  margin-left: 0.5rem;
}

.status-unpaid {
  background-color: #fee2e2;
  color: #dc2626;
  /* red-100, red-600 */
}

.status-partially_paid {
  background-color: #ffedd5;
  color: #f97316;
  /* orange-100, orange-600 */
}

.status-paid {
  background-color: #dcfce7;
  color: #22c55e;
  /* green-100, green-600 */
}


.neo-splits-list {
  margin-top: 1rem;
  padding-left: 1rem;
  border-left: 2px solid #eee;
}

.neo-split-item {
  padding: 0.5rem 0;
  border-bottom: 1px dashed #f0f0f0;
}

.neo-split-item:last-child {
  border-bottom: none;
}

.neo-settlement-activities {
  font-size: 0.8em;
  color: #555;
  padding-left: 1em;
  list-style-type: disc;
  /* Ensure bullets are shown */
  margin-top: 0.5em;
}

.neo-settlement-activities li {
  margin-top: 0.2em;
}


.neo-container {
  padding: 1rem;
  max-width: 1200px;
  margin: 0 auto;
}

.page-padding {
  padding: 1rem;
  max-width: 1200px;
  margin: 0 auto;
}

.mb-3 {
  margin-bottom: 1.5rem;
}

.neo-loading-state,
.neo-error-state,
.neo-empty-state {
  text-align: center;
  padding: 3rem 1rem;
  margin: 2rem 0;
  border: 3px solid #111;
  border-radius: 18px;
  background: #fff;
  box-shadow: 6px 6px 0 #111;
}

.neo-error-state {
  border-color: #e74c3c;
}

.neo-list-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 1.5rem;
}

.neo-title {
  font-size: 2.5rem;
  font-weight: 900;
  margin: 0;
  line-height: 1.2;
}

.neo-header-actions {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.neo-description {
  font-size: 1.2rem;
  margin-bottom: 2rem;
  color: #555;
}

.neo-status {
  font-weight: 900;
  font-size: 1rem;
  padding: 0.4rem 1rem;
  border: 3px solid #111;
  border-radius: 50px;
  background: var(--light);
  box-shadow: 3px 3px 0 #111;
}

.neo-status-active {
  background: #f7f7d4;
}

.neo-status-complete {
  background: #d4f7dd;
}

.neo-list-card {
  break-inside: avoid;
  border-radius: 18px;
  box-shadow: 6px 6px 0 #111;
  width: 100%;
  margin: 0 0 2rem 0;
  background: var(--light);
  display: flex;
  flex-direction: column;
  cursor: pointer;
  border: 3px solid #111;
  overflow: hidden;
}

.neo-item-list-container {
  border: 3px solid #111;
  border-radius: 18px;
  background: var(--light);
  box-shadow: 6px 6px 0 #111;
  overflow: hidden;
}

.neo-item-list {
  list-style: none;
  padding: 0;
  margin: 0;
}

.neo-list-item {
  padding: 1.2rem;
  margin-bottom: 0;
  border-bottom: 1px solid #eee;
  background: var(--light);
  transition: background-color 0.1s ease-in-out;
}

.neo-list-item:last-child {
  border-bottom: none;
}

.neo-list-item:hover {
  background-color: #f9f9f9;
}

.neo-item-content {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.neo-checkbox-label {
  display: flex;
  align-items: center;
  gap: 0.7em;
  cursor: pointer;
  flex-grow: 1;
}

.neo-checkbox-label input[type="checkbox"] {
  width: 1.2em;
  height: 1.2em;
  accent-color: #111;
  border: 2px solid #111;
  border-radius: 4px;
}

.item-name {
  font-size: 1.1rem;
  font-weight: 700;
}

.neo-item-actions {
  display: flex;
  gap: 0.5rem;
}

.neo-icon-button {
  background: none;
  border: none;
  cursor: pointer;
  padding: 0.5rem;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.1s ease-out, opacity 0.1s ease-out;
  -webkit-tap-highlight-color: transparent;
}

.neo-icon-button:active {
  transform: scale(0.98);
  opacity: 0.9;
}

.neo-edit-button {
  color: #3498db;
}

.neo-edit-button:hover {
  background: #eef7fd;
}

.neo-delete-button {
  color: #e74c3c;
}

.neo-delete-button:hover {
  background: #fee;
}

.neo-price-input {
  margin-top: 0.5rem;
  padding-left: 2.2em;
}

@media (max-width: 600px) {
  .neo-list-item {
    padding: 1rem;
  }

  .neo-checkbox-label input[type="checkbox"] {
    width: 1.4em;
    height: 1.4em;
  }

  .item-name {
    font-size: 1rem;
  }

  .neo-icon-button {
    padding: 0.6rem;
  }
}

/* Add smooth transitions for all interactive elements - VComponents have their own */
/* .neo-action-button,
.neo-icon-button,
.neo-checkbox-label,
.neo-add-button {
  transition: transform 0.1s ease-out, opacity 0.1s ease-out;
  -webkit-tap-highlight-color: transparent;
}

.neo-action-button:active,
.neo-icon-button:active,
.neo-checkbox-label:active,
.neo-add-button:active {
  transform: scale(0.98);
  opacity: 0.9;
} */

/* Improve scrolling performance */
.item-list-tight {
  /* Assuming VList with this class */
  will-change: transform;
  transform: translateZ(0);
}

/* Modal styles are now handled by VModal component */
/* .modal-backdrop { ... } */
/* .modal-container { ... } */
/* .modal-header { ... } */
/* .modal-body { ... } */
/* .modal-footer { ... } */
/* .close-button { ... } */


/* Item badge styles are now handled by VBadge */
/* .item-badge { ... } */
/* .badge-settled { ... } */
/* .badge-pending { ... } */


.text-right {
  text-align: right;
}

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

/* Spinner styles are now handled by VSpinner */
/* .spinner-dots { ... } */
/* .spinner-dots span { ... } */
/* .spinner-dots-sm { ... } */
/* .spinner-dots-sm span { ... } */
/* @keyframes dot-pulse { ... } */

/* Utility classes that might still be used or can be replaced by Tailwind/global equivalents */
.flex {
  display: flex;
}

.items-center {
  align-items: center;
}

.justify-between {
  justify-content: space-between;
}

.gap-1 {
  gap: 0.25rem;
}

.gap-2 {
  gap: 0.5rem;
}

.ml-1 {
  margin-left: 0.25rem;
}

.ml-2 {
  margin-left: 0.5rem;
}

.mt-1 {
  margin-top: 0.25rem;
}

.mt-2 {
  margin-top: 0.5rem;
}

.mt-4 {
  margin-top: 1rem;
}

.mb-2 {
  margin-bottom: 0.5rem;
}

.mb-3 {
  margin-bottom: 1rem;
}

/* Adjusted from 1.5rem to match common spacing */
.mb-4 {
  margin-bottom: 1.5rem;
}

.py-10 {
  padding-top: 2.5rem;
  padding-bottom: 2.5rem;
}

.py-4 {
  padding-top: 1rem;
  padding-bottom: 1rem;
}

.p-4 {
  padding: 1rem;
}

.border {
  border-width: 1px;
  /* Assuming default border color from global styles or Tailwind */
}

.rounded-lg {
  border-radius: 0.5rem;
}

.shadow {
  box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
  /* Example shadow */
}

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

.w-24 {
  width: 6rem;
}

/* Tailwind w-24 */
.text-sm {
  font-size: 0.875rem;
}

.text-gray-500 {
  color: #6b7280;
}

/* Tailwind gray-500 */
.text-gray-400 {
  color: #9ca3af;
}

/* Tailwind gray-400 */
.text-green-600 {
  color: #16a34a;
}

/* Tailwind green-600 */
.text-yellow-500 {
  color: #eab308;
}

/* Tailwind yellow-500 */
.line-through {
  text-decoration: line-through;
}

.opacity-50 {
  opacity: 0.5;
}

.opacity-60 {
  opacity: 0.6;
}

/* Added for completed item name */
.opacity-70 {
  opacity: 0.7;
}

/* Added for completed item background */
.shrink-0 {
  flex-shrink: 0;
}

.bg-gray-100 {
  background-color: #f3f4f6;
}

/* Tailwind gray-100 */

/* Styles for .neo-list-card, .neo-item-list, .neo-item might be replaced by VCard/VList/VListItem defaults or props */
/* Keeping some specific styles for .neo-item-details, .item-name, etc. if they are distinct. */
.item-with-actions {
  /* Custom class for VListItem if needed for specific layout */
  /* Default VListItem is display:flex, so this might not be needed or just for minor tweaks */
}
</style>
