<template>
  <main class="neo-container page-padding">
    <div v-if="pageInitialLoad && !list && !error" class="text-center py-10">
      <VSpinner label="Loading list..." size="lg" />
    </div>

    <VAlert v-else-if="error && !list" type="error" :message="error" class="mb-4">
      <template #actions>
        <VButton @click="fetchListDetails">Retry</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">Cost Summary
          </VButton>
          <VButton @click="openOcrDialog" :disabled="!isOnline" icon-left="plus">Add via OCR</VButton>
          <VBadge :text="list.group_id ? 'Group List' : 'Personal List'" :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="Loading items..." size="lg" />
      </VCard>
      <VCard v-else-if="!itemsAreLoading && list.items.length === 0" variant="empty-state" empty-icon="clipboard"
        empty-title="No Items Yet!" empty-message="Add some items using the form below." class="mt-4" />
      <VCard v-else class="mt-4">
        <VList class="item-list-tight">
          <VListItem v-for="item in list.items" :key="item.id" class="item-with-actions"
            :class="{ 'bg-gray-100 opacity-70': item.is_complete }">
            <template #default>
              <div class="flex items-center flex-grow gap-2">
                <VCheckbox :model-value="item.is_complete" @update:modelValue="confirmUpdateItem(item, $event)"
                  :disabled="item.updating" :aria-label="item.name" />
                <div class="flex-grow">
                  <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>
                  <div v-if="item.is_complete" class="mt-1">
                    <VInput type="number" :model-value="item.priceInput || ''"
                      @update:modelValue="item.priceInput = $event" placeholder="Price" size="sm" class="w-24"
                      step="0.01" @blur="updateItemPrice(item)"
                      @keydown.enter.prevent="($event.target as HTMLInputElement).blur()" />
                  </div>
                </div>
              </div>
              <div class="flex items-center gap-1 ml-2">
                <VButton :icon-only="true" size="sm" variant="neutral" @click.stop="editItem(item)"
                  aria-label="Edit item">
                  <VIcon name="edit" />
                </VButton>
                <VButton :icon-only="true" size="sm" variant="neutral" color="danger"
                  @click.stop="confirmDeleteItem(item)" :disabled="item.deleting" aria-label="Delete item">
                  <VIcon name="trash" />
                </VButton>
              </div>
            </template>
          </VListItem>
        </VList>
      </VCard>

      <!-- 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="New item name" :label-sr-only="true">
          <VInput v-model="newItem.name" placeholder="Add a new item" required ref="itemNameInputRef" />
        </VFormField>
        <VFormField label="Quantity" :label-sr-only="true" class="w-24 shrink-0">
          <VInput type="number" :model-value="newItem.quantity || ''" @update:modelValue="newItem.quantity = $event"
            placeholder="Qty" min="1" />
        </VFormField>
        <VButton type="submit" :disabled="addingItem" class="shrink-0">
          <VSpinner v-if="addingItem" size="sm" />
          <span v-else>Add</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">Expenses</h2>
        <button class="neo-action-button" @click="showCreateExpenseForm = true">
          <svg class="icon">
            <use xlink:href="#icon-plus" />
          </svg>
          Add Expense
        </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>Loading expenses...</p>
      </div>
      <div v-else-if="listDetailStore.error" class="neo-error-state">
        <p>{{ listDetailStore.error }}</p>
        <button class="neo-button" @click="listDetailStore.fetchListWithExpenses(String(list?.id))">Retry</button>
      </div>
      <div v-else-if="!expenses || expenses.length === 0" class="neo-empty-state">
        <p>No expenses recorded for this list yet.</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">
            Paid by: <strong>{{ expense.paid_by_user?.name || expense.paid_by_user?.email || `User ID:
              ${expense.paid_by_user_id}` }}</strong>
            on {{ 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> owes {{
                  formatCurrency(split.owed_amount) }}
                <span class="neo-expense-status" :class="getStatusClass(split.status)">
                  {{ getSplitStatusText(split.status) }}
                </span>
              </div>
              <div class="neo-split-details">
                Paid: {{ getPaidAmountForSplitDisplay(split) }}
                <span v-if="split.paid_at"> on {{ 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">
                Settle My Share
              </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">
                  Activity: {{ formatCurrency(activity.amount_paid) }} by {{ activity.payer?.name || `User
                  ${activity.paid_by_user_id}` }} on {{ 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="Add Items via OCR" @update:modelValue="!$event && closeOcrDialog()">
      <template #default>
        <div v-if="ocrLoading" class="text-center">
          <VSpinner label="Processing image..." />
        </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="Upload Image" :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">Cancel</VButton>
        <VButton v-if="ocrItems.length > 0" type="button" variant="primary" @click="addOcrItems"
          :disabled="addingOcrItems">
          <VSpinner v-if="addingOcrItems" size="sm" /> Add Items
        </VButton>
      </template>
    </VModal>

    <!-- Confirmation Dialog -->
    <VModal v-model="showConfirmDialogState" title="Confirmation" @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">Cancel</VButton>
        <VButton variant="primary" @click="handleConfirmedAction">Confirm</VButton>
      </template>
    </VModal>

    <!-- Cost Summary Dialog -->
    <VModal v-model="showCostSummaryDialog" title="List Cost Summary" @update:modelValue="showCostSummaryDialog = false"
      size="lg">
      <template #default>
        <div v-if="costSummaryLoading" class="text-center">
          <VSpinner label="Loading summary..." />
        </div>
        <VAlert v-else-if="costSummaryError" type="error" :message="costSummaryError" />
        <div v-else-if="listCostSummary">
          <div class="mb-3 cost-overview">
            <p><strong>Total List Cost:</strong> {{ formatCurrency(listCostSummary.total_list_cost) }}</p>
            <p><strong>Equal Share Per User:</strong> {{ formatCurrency(listCostSummary.equal_share_per_user) }}</p>
            <p><strong>Participating Users:</strong> {{ listCostSummary.num_participating_users }}</p>
          </div>
          <h4>User Balances</h4>
          <div class="table-container mt-2">
            <table class="table">
              <thead>
                <tr>
                  <th>User</th>
                  <th class="text-right">Items Added Value</th>
                  <th class="text-right">Amount Due</th>
                  <th class="text-right">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>No cost summary available.</p>
      </template>
      <template #footer>
        <VButton variant="primary" @click="showCostSummaryDialog = false">Close</VButton>
      </template>
    </VModal>

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

    <!-- Edit Item Dialog -->
    <VModal v-model="showEditDialog" title="Edit Item" @update:modelValue="!$event && closeEditDialog()">
      <template #default>
        <VFormField v-if="editingItem" label="Item Name" class="mb-4">
          <VInput type="text" id="editItemName" v-model="editingItem.name" required />
        </VFormField>
        <VFormField v-if="editingItem" label="Quantity">
          <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">Cancel</VButton>
        <VButton variant="primary" @click="handleConfirmEdit" :disabled="!editingItem?.name.trim()">Save Changes
        </VButton>
      </template>
    </VModal>

    <VAlert v-if="!list && !pageInitialLoad" type="info" message="Group not found or an error occurred." />
  </main>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted, watch, nextTick, computed } from 'vue';
import { useRoute } from 'vue-router';
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


// 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 is still true here, it means no shell was loaded.
  // The main spinner might be showing. We're about to fetch details, so turn off main spinner.
  if (pageInitialLoad.value) {
    pageInitialLoad.value = false;
  }
  itemsAreLoading.value = true;

  // Check for pre-fetched full data first
  const routeId = String(route.params.id);
  const cachedFullData = sessionStorage.getItem(`listDetailFull_${routeId}`);

  try {
    let response;
    if (cachedFullData) {
      // Use cached data
      response = { data: JSON.parse(cachedFullData) };
      // Clear the cache after using it
      sessionStorage.removeItem(`listDetailFull_${routeId}`);
    } else {
      // Fetch fresh data
      response = await apiClient.get(API_ENDPOINTS.LISTS.BY_ID(routeId));
    }

    const rawList = response.data as ListWithExpenses;
    // Map API response to local List type
    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 errorMessage = (err instanceof Error ? err.message : String(err)) || 'Failed to load list details.';
    if (!list.value) { // If there was no shell AND this fetch failed
      error.value = errorMessage; // This error is for the whole page
    } else {
      // We have a shell, but items failed to load.
      // Show a notification for item loading failure. list.items will remain as per shell (empty).
      notificationStore.addNotification({ message: `Failed to load items: ${errorMessage}`, type: 'error' });
    }
  } finally {
    itemsAreLoading.value = false;
    // If list is still null and no error was set (e.g. silent failure), ensure pageInitialLoad is 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: 'Please enter an item name.', type: 'warning' });
    if (itemNameInputRef.value?.$el) {
      (itemNameInputRef.value.$el as HTMLElement).focus();
    }
    return;
  }
  addingItem.value = true;

  if (!isOnline.value) {
    const offlinePayload: any = {
      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(),
      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,
      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;
    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();
    }
  } catch (err) {
    notificationStore.addNotification({ message: (err instanceof Error ? err.message : String(err)) || 'Failed to add item.', 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;
    return;
  }

  try {
    await apiClient.put(
      API_ENDPOINTS.LISTS.ITEM(String(list.value.id), String(item.id)),
      { completed: newCompleteStatus, version: item.version }
    );
    item.version++;
  } catch (err) {
    item.is_complete = originalCompleteStatus;
    notificationStore.addNotification({ message: (err instanceof Error ? err.message : String(err)) || 'Failed to update item.', 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;
  item.updating = true;
  const originalPrice = item.price;
  const originalPriceInput = item.priceInput;
  item.price = newPrice?.toString() || null;
  if (!isOnline.value) {
    offlineStore.addAction({
      type: 'update_list_item',
      payload: {
        listId: String(list.value.id),
        itemId: String(item.id),
        data: {
          price: newPrice ?? null,
          completed: item.is_complete
        },
        version: item.version
      }
    });
    item.updating = false;
    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++;
  } catch (err) {
    item.price = originalPrice;
    item.priceInput = originalPriceInput;
    notificationStore.addNotification({ message: (err instanceof Error ? err.message : String(err)) || 'Failed to update item price.', type: 'error' });
  } finally {
    item.updating = false;
  }
};

const deleteItem = async (item: ItemWithUI) => {
  if (!list.value) return;
  item.deleting = true;

  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);
    item.deleting = false;
    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);
  } catch (err) {
    notificationStore.addNotification({ message: (err instanceof Error ? err.message : String(err)) || 'Failed to delete item.', type: 'error' });
  } finally {
    item.deleting = false;
  }
};

const confirmUpdateItem = (item: ItemWithUI, newCompleteStatus: boolean) => {
  confirmDialogMessage.value = `Mark "${item.name}" as ${newCompleteStatus ? 'complete' : 'incomplete'}?`;
  pendingAction.value = () => updateItem(item, newCompleteStatus);
  showConfirmDialogState.value = true;
};

const confirmDeleteItem = (item: ItemWithUI) => {
  confirmDialogMessage.value = `Delete "${item.name}"? This cannot be undone.`;
  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;
};

const openOcrDialog = () => {
  ocrItems.value = [];
  ocrError.value = null;
  resetOcrFileDialog();
  showOcrDialogState.value = true;
  nextTick(() => {
    // For VInput type file, direct .value = '' might not work or be needed.
    // VInput should handle its own reset if necessary, or this ref might target the native input inside.
    if (ocrFileInputRef.value && ocrFileInputRef.value.$el) { // Assuming VInput exposes $el
      const inputElement = ocrFileInputRef.value.$el.querySelector('input[type="file"]') || ocrFileInputRef.value.$el;
      if (inputElement) (inputElement as HTMLInputElement).value = '';
    } else if (ocrFileInputRef.value) { // Fallback if ref is 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 = "No items extracted from the image.";
    }
  } catch (err) {
    ocrError.value = (err instanceof Error ? err.message : String(err)) || 'Failed to process image.';
  } finally {
    ocrLoading.value = false;
    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) {
      (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" } // Assuming default quantity 1 for OCR items
      );
      const addedItem = response.data as Item;
      list.value.items.push(processListItems([addedItem])[0]);
      successCount++;
    }
    if (successCount > 0) notificationStore.addNotification({ message: `${successCount} item(s) added successfully from OCR.`, type: 'success' });
    closeOcrDialog();
  } catch (err) {
    notificationStore.addNotification({ message: (err instanceof Error ? err.message : String(err)) || 'Failed to add OCR items.', 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)) || 'Failed to load cost summary.';
    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 'Paid';
    case ExpenseSplitStatusEnum.PARTIALLY_PAID: return 'Partially Paid';
    case ExpenseSplitStatusEnum.UNPAID: return 'Unpaid';
    default: return status;
  }
};

const getOverallExpenseStatusText = (status: ExpenseOverallStatusEnum): string => {
  switch (status) {
    case ExpenseOverallStatusEnum.PAID: return 'Settled';
    case ExpenseOverallStatusEnum.PARTIALLY_PAID: return 'Partially Settled';
    case ExpenseOverallStatusEnum.UNPAID: return 'Unsettled';
    default: return status;
  }
};

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;
    }
    if (showOcrDialogState.value || showCostSummaryDialog.value || showConfirmDialogState.value) {
      return;
    }
    event.preventDefault();
    if (itemNameInputRef.value?.$el) {
      (itemNameInputRef.value.$el as HTMLElement).focus();
    }
  }
});

let touchStartX = 0;
const SWIPE_THRESHOLD = 50;

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

const handleTouchMove = () => {
};

const handleTouchEnd = () => {
};


onMounted(() => {
  pageInitialLoad.value = true;
  itemsAreLoading.value = false;
  error.value = null; // Clear stale errors on mount

  if (!route.params.id) {
    error.value = 'No list ID provided';
    pageInitialLoad.value = false; // Stop initial load phase, show error
    listDetailStore.setError('No list ID provided for expenses.'); // Set error in expense store
    return;
  }

  // Attempt to load shell data from sessionStorage
  const listShellJSON = sessionStorage.getItem('listDetailShell');
  const routeId = String(route.params.id);

  if (listShellJSON) {
    const shellData = JSON.parse(listShellJSON);
    // Ensure the shell data is for the current list
    if (shellData.id === parseInt(routeId, 10)) {
      list.value = {
        id: shellData.id,
        name: shellData.name,
        description: shellData.description,
        is_complete: false, // Assume not complete until full data loaded
        items: [], // Start with no items, they will be fetched by fetchListDetails
        version: 0, // Placeholder, will be updated
        updated_at: new Date().toISOString(), // Placeholder
        group_id: shellData.group_id,
      };
      pageInitialLoad.value = false; // Shell loaded, main page spinner can go
      // Optionally, clear the sessionStorage item after use
      // sessionStorage.removeItem('listDetailShell');
    } else {
      // Shell data is for a different list, clear it
      sessionStorage.removeItem('listDetailShell');
      // pageInitialLoad remains true, will be set to false by fetchListDetails
    }
  }

  fetchListDetails().then(() => { // Fetches items
    startPolling();
  });
  // Fetch expenses using the store when component is mounted
  const routeParamsId = route.params.id;
  listDetailStore.fetchListWithExpenses(String(routeParamsId));
});

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

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

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

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

  const item = editingItem.value;
  const originalItem = list.value.items.find(i => i.id === item.id);
  if (!originalItem) return;

  try {
    const response = await apiClient.put(
      API_ENDPOINTS.LISTS.ITEM(String(list.value.id), String(item.id)),
      {
        name: item.name,
        quantity: item.quantity?.toString(),
        version: item.version
      }
    );

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

    notificationStore.addNotification({
      message: 'Item updated successfully',
      type: 'success'
    });
    closeEditDialog();
  } catch (err) {
    notificationStore.addNotification({
      message: (err instanceof Error ? err.message : String(err)) || 'Failed to update item',
      type: 'error'
    });
  }
};

const openSettleShareModal = (expense: Expense, split: ExpenseSplit) => {
  if (split.user_id !== authStore.user?.id) {
    notificationStore.addNotification({ message: "You can only settle your own shares.", 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 = 'Please enter an amount.';
    return false;
  }
  const amount = new Decimal(settleAmount.value);
  if (amount.isNaN() || amount.isNegative() || amount.isZero()) {
    settleAmountError.value = 'Please enter a positive amount.';
    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')))) { // Epsilon for float issues
      settleAmountError.value = `Amount cannot exceed remaining: ${formatCurrency(remaining.toFixed(2))}.`;
      return false;
    }
  } else {
    settleAmountError.value = 'Error: No split selected.'; // Should not happen
    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: 'Cannot process settlement: missing data.', type: 'error' });
    return;
  }
  // Use settleAmount.value which is the confirmed amount (remaining amount for MVP)
  const activityData: SettlementActivityCreate = {
    expense_split_id: selectedSplitForSettlement.value.id,
    paid_by_user_id: Number(authStore.user.id), // Convert to number
    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: 'Share settled successfully!', type: 'success' });
    closeSettleShareModal();
  } else {
    notificationStore.addNotification({ message: listDetailStore.error || 'Failed to settle share.', type: 'error' });
  }
};

const handleExpenseCreated = (expense: any) => {
  // Refresh the expenses list
  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 {
  list-style: none;
  padding: 0;
  margin: 0 0 2rem 0;
  break-inside: avoid;
  width: 100%;
  background: var(--light);
  display: flex;
  flex-direction: column;
}

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

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

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

.neo-item-complete {
  background: #f9f9f9;
}

.neo-item-content {
  display: flex;
  align-items: center;
}

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

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

.neo-item-details {
  flex-grow: 1;
  display: flex;
  flex-direction: column;
}

.item-name {
  /* Added for VListItem content */
  font-size: 1.1rem;
  font-weight: 700;
}

.neo-item-complete .item-name {
  /* Adjusted for VListItem */
  text-decoration: line-through;
  /* opacity: 0.6; Combined with bg-gray-100 opacity-70 on VListItem */
}


.neo-item-quantity {
  font-size: 0.9rem;
  color: #555;
  margin-top: 0.2rem;
}

.neo-price-input {
  margin-top: 0.5rem;
}

.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;
}

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

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

.neo-delete-button {
  background: none;
  border: none;
  cursor: pointer;
  color: #e74c3c;
  padding: 0.5rem;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-left: 0;
}

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

.neo-actions {
  display: flex;
  gap: 1rem;
  margin-bottom: 2rem;
}

.neo-action-button {
  /* General button, mostly replaced by VButton */
  background: #111;
  color: white;
  border: none;
  border-radius: 8px;
  padding: 0.6rem 1rem;
  font-weight: 700;
  cursor: pointer;
}

.neo-action-button:hover {
  transform: translateY(-2px);
  box-shadow: 3px 5px 0 #111;
}

.neo-action-button .icon {
  width: 1.2rem;
  height: 1.2rem;
}

.neo-disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.add-item-form {
  /* Added for new form styling */
  /* display: flex; (already on class) */
  /* gap: 0.5rem; (already on class) */
  /* margin-top: 1rem; (original was 2rem, now mt-4) */
  /* padding: 1rem; (original was 1rem) */
  /* border: 3px solid #111; (original was 3px) */
  /* border-radius: 12px; (original was 12px) */
  /* background: #f9f9f9; (original was #f9f9f9) */
  /* box-shadow: 4px 4px 0 #111; (original was 4px) */
}


.neo-new-item-form {
  /* Kept for reference, but form tag itself is now styled */
  width: 100%;
  gap: 10px;
}

.neo-text-input {
  /* Not directly used by VInput, but kept for reference */
  flex-grow: 1;
  border: 2px solid #111;
  border-radius: 8px;
  padding: 0.8rem;
  font-size: 1.1rem;
  font-weight: 500;
}

.neo-new-item-input {
  /* Not directly used by VInput, but kept for reference */
  background: transparent;
  border: none;
  outline: none;
  all: unset;
  width: 100%;
  font-size: 1.1rem;
  font-weight: 500;
  color: #444;
  flex-grow: 1;
}

.neo-new-item-input::placeholder {
  /* VInput handles its own placeholder styling */
  color: #999;
  font-weight: 500;
}

.neo-quantity-input {
  /* Not directly used by VInput, but kept for reference */
  width: 80px;
  /* This specific width is now on VFormField for quantity */
  border: 2px solid #111;
  border-radius: 8px;
  padding: 0.4rem;
  font-size: 1rem;
  font-weight: 500;
}

.neo-number-input {
  /* For price input, now VInput with class="w-24" */
  border: 2px solid #111;
  border-radius: 6px;
  padding: 0.5rem;
  font-size: 1rem;
  width: 100px;
}

.neo-add-button {
  /* Replaced by VButton */
  background: #111;
  color: white;
  border: none;
  border-radius: 8px;
  padding: 0 1rem;
  font-weight: 700;
  cursor: pointer;
  min-width: 60px;
  height: 2rem;
}

.neo-button {
  /* General button, mostly replaced by VButton */
  background: #111;
  color: white;
  border: none;
  border-radius: 8px;
  padding: 0.8rem 1.5rem;
  font-weight: 700;
  margin-top: 1rem;
  cursor: pointer;
}

.new-item-input {
  /* Styling for the old li wrapper of add item form, can be removed */
  margin-top: 0.5rem;
  padding: 0.5rem;
}

/* Responsive adjustments */
@media (max-width: 900px) {
  .neo-container {
    padding: 0.8rem;
  }

  .neo-title {
    font-size: 1.8rem;
  }

  /* .neo-item { // VListItem might have its own padding
    padding: 1rem;
  } */
}

@media (max-width: 600px) {
  .neo-container {
    padding: 0.5rem;
  }

  .neo-list-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.8rem;
  }

  .neo-title {
    font-size: 1.5rem;
    margin-bottom: 0.5rem;
  }

  .neo-header-actions {
    flex-wrap: wrap;
    gap: 0.5rem;
  }

  .neo-action-button {
    /* VButton has its own sizing */
    padding: 0.8rem;
    font-size: 0.9rem;
  }

  .neo-description {
    font-size: 1rem;
    margin-bottom: 1.5rem;
  }

  /* .neo-item { // VListItem
    padding: 1rem;
  } */

  .item-name {
    /* Adjusted for VListItem */
    font-size: 1rem;
  }

  .neo-item-quantity {
    font-size: 0.85rem;
  }

  /* .neo-checkbox-label input[type="checkbox"] { // VCheckbox has its own styling
    width: 1.4em;
    height: 1.4em;
  } */

  .neo-icon-button {
    /* VButton icon-only replaces this */
    padding: 0.6rem;
  }

  .add-item-form {
    /* Adjusted form class */
    flex-wrap: wrap;
    gap: 0.5rem;
  }

  /* VInput placeholder styling is internal to VInput */
  /* .neo-new-item-input {
    width: 100%;
    font-size: 1rem;
  } */

  /* VInput type number styling is internal or via props */
  /* .neo-quantity-input {
    width: 80px;
    font-size: 0.9rem;
  } */

  /* VButton styling replaces this */
  /* .neo-add-button {
    width: 100%;
    margin-top: 0.5rem;
    padding: 0.8rem;
  } */

  /* Optimize modals for mobile */
  .modal-container {
    /* VModal has its own responsive sizing via props/CSS */
    width: 95%;
    max-height: 85vh;
    margin: 1rem;
  }

  .modal-header {
    /* VModal slot */
    padding: 1rem;
  }

  .modal-body {
    /* VModal slot */
    padding: 1rem;
  }

  .modal-footer {
    /* VModal slot */
    padding: 1rem;
  }

  /* Improve touch targets - general principle, components should handle this */
  /* button,
  input[type="checkbox"],
  .neo-checkbox-label {
    min-height: 44px;
  } */

  /* Optimize loading states for mobile */
  .neo-loading-state {
    /* VSpinner used instead */
    padding: 2rem 1rem;
  }

  .spinner-dots span {
    /* VSpinner has its own dot styling */
    width: 10px;
    height: 10px;
  }

  /* Improve scrolling performance */
  .item-list-tight {
    /* Assuming VList with this class */
    -webkit-overflow-scrolling: touch;
  }

  /* Optimize expense cards for mobile */
  .neo-expense-card {
    padding: 0.8rem;
  }

  .neo-expense-header {
    font-size: 1.1rem;
  }

  .neo-split-item {
    padding: 0.8rem 0;
  }
}

/* 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>
