import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { apiClient, API_ENDPOINTS } from '@/services/api'
import type {
  Expense,
  ExpenseSplit,
  SettlementActivity,
  SettlementActivityPublic,
} from '@/types/expense'
import type { SettlementActivityCreate } from '@/types/expense'
import type { List } from '@/types/list'
import type { AxiosResponse } from 'axios'
import type { Item } from '@/types/item'
import { useSocket } from '@/composables/useSocket'

export interface ListWithExpenses extends List {
  id: number
  expenses: Expense[]
}

export const useListDetailStore = defineStore('listDetail', () => {
  // State
  const currentList = ref<ListWithExpenses | null>(null)
  const isLoading = ref(false)
  const error = ref<string | null>(null)
  const isSettlingSplit = ref(false)

  // Real-time state
  const { isConnected, on, off, emit } = useSocket()

  // ---- Real-time Event Handlers ----
  function setupWebSocketListeners() {
    on('list:updated', handleListUpdated)
    on('expense:created', handleExpenseCreated)
    on('expense:updated', handleExpenseUpdated)
    on('expense:deleted', handleExpenseDeleted)
  }

  function cleanupWebSocketListeners() {
    off('list:updated', handleListUpdated)
    off('expense:created', handleExpenseCreated)
    off('expense:updated', handleExpenseUpdated)
    off('expense:deleted', handleExpenseDeleted)
  }

  function handleListUpdated(payload: { list: List }) {
    const { list } = payload
    if (currentList.value && currentList.value.id === list.id) {
      // Update the list portion while preserving expenses
      currentList.value = {
        ...currentList.value,
        ...list,
        expenses: currentList.value.expenses // Keep existing expenses
      }
    }
  }

  function handleExpenseCreated(payload: { expense: Expense }) {
    const { expense } = payload
    if (currentList.value && expense.list_id === currentList.value.id) {
      // Add the new expense if not already present
      if (!currentList.value.expenses.find(e => e.id === expense.id)) {
        currentList.value.expenses.push(expense)
      }
    }
  }

  function handleExpenseUpdated(payload: { expense: Expense }) {
    const { expense } = payload
    if (currentList.value && expense.list_id === currentList.value.id) {
      const index = currentList.value.expenses.findIndex(e => e.id === expense.id)
      if (index >= 0) {
        currentList.value.expenses[index] = expense
      }
    }
  }

  function handleExpenseDeleted(payload: { expenseId: number, listId: number }) {
    const { expenseId, listId } = payload
    if (currentList.value && currentList.value.id === listId) {
      currentList.value.expenses = currentList.value.expenses.filter(e => e.id !== expenseId)
    }
  }

  // Getters (as computed properties or methods)
  const getExpenses = computed((): Expense[] => {
    return currentList.value?.expenses || []
  })

  const getPaidAmountForSplit = (splitId: number): number => {
    let totalPaid = 0
    if (currentList.value && currentList.value.expenses) {
      for (const expense of currentList.value.expenses) {
        const split = expense.splits.find((s) => s.id === splitId)
        if (split && split.settlement_activities) {
          totalPaid = split.settlement_activities.reduce((sum, activity) => {
            return sum + parseFloat(activity.amount_paid)
          }, 0)
          break
        }
      }
    }
    return totalPaid
  }

  const getExpenseSplitById = (splitId: number): ExpenseSplit | undefined => {
    if (!currentList.value || !currentList.value.expenses) return undefined
    for (const expense of currentList.value.expenses) {
      const split = expense.splits.find((s) => s.id === splitId)
      if (split) return split
    }
    return undefined
  }

  // Actions (as functions)
  async function fetchListWithExpenses(listId: string) {
    if (!listId || listId === 'undefined' || listId === 'null') {
      error.value = 'Invalid list ID provided.'
      console.warn(`fetchListWithExpenses called with invalid ID: ${listId}`)
      return
    }
    isLoading.value = true
    error.value = null
    try {
      // Get list details
      const listEndpoint = API_ENDPOINTS.LISTS.BY_ID(listId)
      const listResponse = await apiClient.get(listEndpoint)
      const listData = listResponse.data as List

      // Get expenses for this list
      const expensesEndpoint = API_ENDPOINTS.LISTS.EXPENSES(listId)
      const expensesResponse = await apiClient.get(expensesEndpoint)
      const expensesData = expensesResponse.data as Expense[]

      // Combine into ListWithExpenses
      currentList.value = {
        ...listData,
        expenses: expensesData,
      } as ListWithExpenses
    } catch (err: any) {
      error.value = err.response?.data?.detail || err.message || 'Failed to fetch list details'
      currentList.value = null
      console.error('Error fetching list details:', err)
    } finally {
      isLoading.value = false
    }
  }

  async function settleExpenseSplit(payload: {
    list_id_for_refetch: string
    expense_split_id: number
    activity_data: SettlementActivityCreate
  }): Promise<boolean> {
    isSettlingSplit.value = true
    error.value = null
    try {
      const endpoint = `/financials/expense_splits/${payload.expense_split_id}/settle`
      await apiClient.post(endpoint, payload.activity_data)

      if (payload.list_id_for_refetch) {
        await fetchListWithExpenses(payload.list_id_for_refetch)
      } else if (currentList.value?.id) {
        await fetchListWithExpenses(String(currentList.value.id))
      } else {
        console.warn(
          'Could not refetch list details: list_id_for_refetch not provided and no currentList available.',
        )
      }

      isSettlingSplit.value = false
      return true
    } catch (err: any) {
      const errorMessage =
        err.response?.data?.detail || err.message || 'Failed to settle expense split.'
      error.value = errorMessage
      console.error('Error settling expense split:', err)
      isSettlingSplit.value = false
      return false
    }
  }

  function setError(errorMessage: string) {
    error.value = errorMessage
    isLoading.value = false
  }

  // Initialize WebSocket listeners
  setupWebSocketListeners()

  return {
    currentList,
    isLoading,
    error,
    isSettlingSplit,
    fetchListWithExpenses,
    settleExpenseSplit,
    setError,
    getExpenses,
    getPaidAmountForSplit,
    getExpenseSplitById,

    // Real-time
    isConnected,
    setupWebSocketListeners,
    cleanupWebSocketListeners,
  }
})

// Assuming List interface might be defined in fe/src/types/list.ts
// If not, it should be defined like this:
/*
export interface List {
  id: number;
  name: string;
  description?: string | null;
  is_complete: boolean;
  group_id?: number | null;
  // items: Item[]; // Item interface would also need to be defined
  // version: number;
  // updated_at: string;
}
*/
