const mapJournalEntry = obj => {
  return obj
}

window.app = Vue.createApp({
  el: '#vue',
  mixins: [windowMixin],
  data() {
    return {
      balance: null,
      allUserBalances: [],
      transactions: [],
      accounts: [],
      currencies: [],
      users: [],
      settings: null,
      userWalletSettings: null,
      isAdmin: false,
      isSuperUser: false,
      castleWalletConfigured: false,
      userWalletConfigured: false,
      expenseDialog: {
        show: false,
        description: '',
        amount: null,
        expenseAccount: '',
        isEquity: false,
        reference: '',
        currency: null,
        loading: false
      },
      payDialog: {
        show: false,
        amount: null,
        paymentRequest: null,
        paymentHash: null,
        checkWalletKey: null,
        pollIntervalId: null,
        loading: false
      },
      settingsDialog: {
        show: false,
        castleWalletId: '',
        loading: false
      },
      userWalletDialog: {
        show: false,
        userWalletId: '',
        loading: false
      },
      receivableDialog: {
        show: false,
        selectedUser: '',
        description: '',
        amount: null,
        revenueAccount: '',
        reference: '',
        currency: null,
        loading: false
      },
      manualPaymentDialog: {
        show: false,
        amount: null,
        description: '',
        loading: false
      },
      manualPaymentRequests: [],
      pendingExpenses: [],
      balanceAssertions: [],
      assertionDialog: {
        show: false,
        account_id: '',
        expected_balance_sats: 0,
        expected_balance_fiat: null,
        fiat_currency: null,
        tolerance_sats: 0,
        tolerance_fiat: 0,
        loading: false
      },
      reconciliation: {
        summary: null,
        discrepancies: null,
        checking: false,
        showDiscrepancies: false
      },
      settleReceivableDialog: {
        show: false,
        user_id: '',
        username: '',
        maxAmount: 0,
        amount: 0,
        payment_method: 'cash',
        description: '',
        reference: '',
        loading: false
      }
    }
  },
  watch: {
    'payDialog.show': function(newVal) {
      // When dialog is closed, stop polling
      if (!newVal && this.payDialog.pollIntervalId) {
        clearInterval(this.payDialog.pollIntervalId)
        this.payDialog.pollIntervalId = null
      }
    }
  },
  computed: {
    expenseAccounts() {
      return this.accounts.filter(a => a.account_type === 'expense')
    },
    revenueAccounts() {
      return this.accounts.filter(a => a.account_type === 'revenue')
    },
    amountLabel() {
      if (this.expenseDialog.currency) {
        return `Amount (${this.expenseDialog.currency}) *`
      }
      return 'Amount (sats) *'
    },
    receivableAmountLabel() {
      if (this.receivableDialog.currency) {
        return `Amount (${this.receivableDialog.currency}) *`
      }
      return 'Amount (sats) *'
    },
    currencyOptions() {
      const options = [{label: 'Satoshis (default)', value: null}]
      this.currencies.forEach(curr => {
        options.push({label: curr, value: curr})
      })
      return options
    },
    userOptions() {
      const options = []
      this.users.forEach(user => {
        options.push({
          label: user.username,
          value: user.user_id
        })
      })
      return options
    },
    pendingManualPaymentRequests() {
      return this.manualPaymentRequests.filter(r => r.status === 'pending')
    },
    failedAssertions() {
      return this.balanceAssertions.filter(a => a.status === 'failed')
    },
    passedAssertions() {
      return this.balanceAssertions.filter(a => a.status === 'passed')
    },
    allAccounts() {
      return this.accounts
    }
  },
  methods: {
    async loadBalance() {
      try {
        const response = await LNbits.api.request(
          'GET',
          '/castle/api/v1/balance',
          this.g.user.wallets[0].inkey
        )
        this.balance = response.data

        // If super user, also load all user balances
        if (this.isSuperUser) {
          await this.loadAllUserBalances()
        }
      } catch (error) {
        LNbits.utils.notifyApiError(error)
      }
    },
    async loadAllUserBalances() {
      try {
        const response = await LNbits.api.request(
          'GET',
          '/castle/api/v1/balances/all',
          this.g.user.wallets[0].adminkey
        )
        this.allUserBalances = response.data
      } catch (error) {
        console.error('Error loading all user balances:', error)
      }
    },
    async loadTransactions() {
      try {
        const response = await LNbits.api.request(
          'GET',
          '/castle/api/v1/entries/user',
          this.g.user.wallets[0].inkey
        )
        this.transactions = response.data
      } catch (error) {
        LNbits.utils.notifyApiError(error)
      }
    },
    async loadAccounts() {
      try {
        const response = await LNbits.api.request(
          'GET',
          '/castle/api/v1/accounts',
          this.g.user.wallets[0].inkey
        )
        this.accounts = response.data
      } catch (error) {
        LNbits.utils.notifyApiError(error)
      }
    },
    async loadCurrencies() {
      try {
        const response = await LNbits.api.request(
          'GET',
          '/castle/api/v1/currencies',
          this.g.user.wallets[0].inkey
        )
        this.currencies = response.data
      } catch (error) {
        LNbits.utils.notifyApiError(error)
      }
    },
    async loadUsers() {
      try {
        const response = await LNbits.api.request(
          'GET',
          '/castle/api/v1/users',
          this.g.user.wallets[0].adminkey
        )
        this.users = response.data
      } catch (error) {
        console.error('Error loading users:', error)
      }
    },
    async loadSettings() {
      try {
        // Try with admin key first to check settings
        const response = await LNbits.api.request(
          'GET',
          '/castle/api/v1/settings',
          this.g.user.wallets[0].inkey
        )
        this.settings = response.data
        this.castleWalletConfigured = !!(this.settings && this.settings.castle_wallet_id)

        // Check if user is super user by seeing if they can access admin features
        this.isSuperUser = this.g.user.super_user || false
        this.isAdmin = this.g.user.admin || this.isSuperUser
      } catch (error) {
        // Settings not available
        this.castleWalletConfigured = false
      }
    },
    async loadUserWallet() {
      try {
        const response = await LNbits.api.request(
          'GET',
          '/castle/api/v1/user/wallet',
          this.g.user.wallets[0].inkey
        )
        this.userWalletSettings = response.data
        this.userWalletConfigured = !!(this.userWalletSettings && this.userWalletSettings.user_wallet_id)
      } catch (error) {
        this.userWalletConfigured = false
      }
    },
    showSettingsDialog() {
      this.settingsDialog.castleWalletId = this.settings?.castle_wallet_id || ''
      this.settingsDialog.show = true
    },
    showUserWalletDialog() {
      this.userWalletDialog.userWalletId = this.userWalletSettings?.user_wallet_id || ''
      this.userWalletDialog.show = true
    },
    async submitSettings() {
      if (!this.settingsDialog.castleWalletId) {
        this.$q.notify({
          type: 'warning',
          message: 'Castle Wallet ID is required'
        })
        return
      }

      this.settingsDialog.loading = true
      try {
        await LNbits.api.request(
          'PUT',
          '/castle/api/v1/settings',
          this.g.user.wallets[0].adminkey,
          {
            castle_wallet_id: this.settingsDialog.castleWalletId
          }
        )
        this.$q.notify({
          type: 'positive',
          message: 'Settings updated successfully'
        })
        this.settingsDialog.show = false
        await this.loadSettings()
        // Reload user wallet to reflect castle wallet for super user
        if (this.isSuperUser) {
          await this.loadUserWallet()
        }
      } catch (error) {
        LNbits.utils.notifyApiError(error)
      } finally {
        this.settingsDialog.loading = false
      }
    },
    async submitUserWallet() {
      if (!this.userWalletDialog.userWalletId) {
        this.$q.notify({
          type: 'warning',
          message: 'Wallet ID is required'
        })
        return
      }

      this.userWalletDialog.loading = true
      try {
        await LNbits.api.request(
          'PUT',
          '/castle/api/v1/user/wallet',
          this.g.user.wallets[0].inkey,
          {
            user_wallet_id: this.userWalletDialog.userWalletId
          }
        )
        this.$q.notify({
          type: 'positive',
          message: 'Wallet configured successfully'
        })
        this.userWalletDialog.show = false
        await this.loadUserWallet()
      } catch (error) {
        LNbits.utils.notifyApiError(error)
      } finally {
        this.userWalletDialog.loading = false
      }
    },
    async submitExpense() {
      this.expenseDialog.loading = true
      try {
        await LNbits.api.request(
          'POST',
          '/castle/api/v1/entries/expense',
          this.g.user.wallets[0].inkey,
          {
            description: this.expenseDialog.description,
            amount: this.expenseDialog.amount,
            expense_account: this.expenseDialog.expenseAccount,
            is_equity: this.expenseDialog.isEquity,
            user_wallet: this.g.user.wallets[0].id,
            reference: this.expenseDialog.reference || null,
            currency: this.expenseDialog.currency || null
          }
        )
        this.$q.notify({
          type: 'positive',
          message: 'Expense added successfully'
        })
        this.expenseDialog.show = false
        this.resetExpenseDialog()
        await this.loadBalance()
        await this.loadTransactions()
      } catch (error) {
        LNbits.utils.notifyApiError(error)
      } finally {
        this.expenseDialog.loading = false
      }
    },
    async submitPayment() {
      this.payDialog.loading = true

      // Clear any existing polling interval
      if (this.payDialog.pollIntervalId) {
        clearInterval(this.payDialog.pollIntervalId)
        this.payDialog.pollIntervalId = null
      }

      try {
        // Generate an invoice on the Castle wallet
        const response = await LNbits.api.request(
          'POST',
          '/castle/api/v1/generate-payment-invoice',
          this.g.user.wallets[0].inkey,
          {
            amount: this.payDialog.amount
          }
        )

        // Show the payment request in the dialog
        this.payDialog.paymentRequest = response.data.payment_request
        this.payDialog.paymentHash = response.data.payment_hash
        this.payDialog.checkWalletKey = response.data.check_wallet_key

        this.$q.notify({
          type: 'positive',
          message: 'Invoice generated! Scan QR code or copy to pay.',
          timeout: 3000
        })

        // Poll for payment completion
        this.pollForPayment(response.data.payment_hash, response.data.check_wallet_key)
      } catch (error) {
        LNbits.utils.notifyApiError(error)
      } finally {
        this.payDialog.loading = false
      }
    },
    async pollForPayment(paymentHash, checkWalletKey) {
      // Clear any existing interval
      if (this.payDialog.pollIntervalId) {
        clearInterval(this.payDialog.pollIntervalId)
      }

      // Poll every 2 seconds for payment status
      const checkPayment = async () => {
        try {
          const response = await LNbits.api.request(
            'GET',
            `/api/v1/payments/${paymentHash}`,
            checkWalletKey
          )

          if (response.data && response.data.paid) {
            // Record payment in accounting
            try {
              await LNbits.api.request(
                'POST',
                '/castle/api/v1/record-payment',
                this.g.user.wallets[0].inkey,
                {
                  payment_hash: paymentHash
                }
              )
            } catch (error) {
              console.error('Error recording payment:', error)
            }

            this.$q.notify({
              type: 'positive',
              message: 'Payment received! Your balance has been updated.',
              timeout: 3000
            })
            this.payDialog.show = false
            this.payDialog.paymentRequest = null
            this.payDialog.amount = null
            await this.loadBalance()
            await this.loadTransactions()
            return true
          }
          return false
        } catch (error) {
          // Silently ignore errors (payment might not exist yet)
          return false
        }
      }

      // Check every 2 seconds for up to 5 minutes
      let attempts = 0
      const maxAttempts = 150 // 5 minutes
      this.payDialog.pollIntervalId = setInterval(async () => {
        attempts++
        const paid = await checkPayment()
        if (paid || attempts >= maxAttempts) {
          clearInterval(this.payDialog.pollIntervalId)
          this.payDialog.pollIntervalId = null
        }
      }, 2000)
    },
    showManualPaymentOption() {
      // This is for when user wants to pay their debt manually
      // For now, just notify them to contact castle
      this.$q.notify({
        type: 'info',
        message: 'Please contact Castle directly to arrange manual payment.',
        timeout: 3000
      })
    },
    showManualPaymentDialog() {
      // This is for when Castle owes user and they want to request manual payment
      this.manualPaymentDialog.amount = Math.abs(this.balance.balance)
      this.manualPaymentDialog.description = ''
      this.manualPaymentDialog.show = true
    },
    async submitManualPaymentRequest() {
      this.manualPaymentDialog.loading = true
      try {
        await LNbits.api.request(
          'POST',
          '/castle/api/v1/manual-payment-request',
          this.g.user.wallets[0].inkey,
          {
            amount: this.manualPaymentDialog.amount,
            description: this.manualPaymentDialog.description
          }
        )
        this.$q.notify({
          type: 'positive',
          message: 'Manual payment request submitted successfully!'
        })
        this.manualPaymentDialog.show = false
        this.manualPaymentDialog.amount = null
        this.manualPaymentDialog.description = ''
        await this.loadManualPaymentRequests()
      } catch (error) {
        LNbits.utils.notifyApiError(error)
      } finally {
        this.manualPaymentDialog.loading = false
      }
    },
    async loadManualPaymentRequests() {
      try {
        // If super user, load all requests; otherwise load user's own requests
        const endpoint = this.isSuperUser
          ? '/castle/api/v1/manual-payment-requests/all'
          : '/castle/api/v1/manual-payment-requests'
        const key = this.isSuperUser
          ? this.g.user.wallets[0].adminkey
          : this.g.user.wallets[0].inkey

        const response = await LNbits.api.request(
          'GET',
          endpoint,
          key,
          this.isSuperUser ? {status: 'pending'} : {}
        )
        this.manualPaymentRequests = response.data
      } catch (error) {
        console.error('Error loading manual payment requests:', error)
      }
    },
    async loadPendingExpenses() {
      try {
        if (!this.isSuperUser) return
        if (!this.g.user.wallets[0]?.adminkey) return

        const response = await LNbits.api.request(
          'GET',
          '/castle/api/v1/entries/pending',
          this.g.user.wallets[0].adminkey
        )
        this.pendingExpenses = response.data
      } catch (error) {
        console.error('Error loading pending expenses:', error)
      }
    },
    async approveManualPaymentRequest(requestId) {
      try {
        await LNbits.api.request(
          'POST',
          `/castle/api/v1/manual-payment-requests/${requestId}/approve`,
          this.g.user.wallets[0].adminkey
        )
        this.$q.notify({
          type: 'positive',
          message: 'Manual payment request approved!'
        })
        await this.loadManualPaymentRequests()
        await this.loadBalance()
        await this.loadTransactions()
      } catch (error) {
        LNbits.utils.notifyApiError(error)
      }
    },
    async rejectManualPaymentRequest(requestId) {
      try {
        await LNbits.api.request(
          'POST',
          `/castle/api/v1/manual-payment-requests/${requestId}/reject`,
          this.g.user.wallets[0].adminkey
        )
        this.$q.notify({
          type: 'warning',
          message: 'Manual payment request rejected'
        })
        await this.loadManualPaymentRequests()
      } catch (error) {
        LNbits.utils.notifyApiError(error)
      }
    },
    async approveExpense(entryId) {
      try {
        await LNbits.api.request(
          'POST',
          `/castle/api/v1/entries/${entryId}/approve`,
          this.g.user.wallets[0].adminkey
        )
        this.$q.notify({
          type: 'positive',
          message: 'Expense approved!'
        })
        await this.loadPendingExpenses()
        await this.loadBalance()
        await this.loadTransactions()
        await this.loadAllUserBalances()
      } catch (error) {
        LNbits.utils.notifyApiError(error)
      }
    },
    async rejectExpense(entryId) {
      try {
        await LNbits.api.request(
          'POST',
          `/castle/api/v1/entries/${entryId}/reject`,
          this.g.user.wallets[0].adminkey
        )
        this.$q.notify({
          type: 'warning',
          message: 'Expense rejected'
        })
        await this.loadPendingExpenses()
        await this.loadTransactions()
      } catch (error) {
        LNbits.utils.notifyApiError(error)
      }
    },
    async loadBalanceAssertions() {
      if (!this.isSuperUser) return

      try {
        const response = await LNbits.api.request(
          'GET',
          '/castle/api/v1/assertions',
          this.g.user.wallets[0].adminkey
        )
        this.balanceAssertions = response.data
      } catch (error) {
        LNbits.utils.notifyApiError(error)
      }
    },
    async submitAssertion() {
      this.assertionDialog.loading = true
      try {
        const payload = {
          account_id: this.assertionDialog.account_id,
          expected_balance_sats: this.assertionDialog.expected_balance_sats,
          tolerance_sats: this.assertionDialog.tolerance_sats || 0
        }

        // Add fiat balance check if currency selected
        if (this.assertionDialog.fiat_currency) {
          payload.fiat_currency = this.assertionDialog.fiat_currency
          payload.expected_balance_fiat = this.assertionDialog.expected_balance_fiat
          payload.tolerance_fiat = this.assertionDialog.tolerance_fiat || 0
        }

        await LNbits.api.request(
          'POST',
          '/castle/api/v1/assertions',
          this.g.user.wallets[0].adminkey,
          payload
        )

        this.$q.notify({
          type: 'positive',
          message: 'Balance assertion passed!',
          timeout: 3000
        })

        // Reset dialog
        this.assertionDialog = {
          show: false,
          account_id: '',
          expected_balance_sats: 0,
          expected_balance_fiat: null,
          fiat_currency: null,
          tolerance_sats: 0,
          tolerance_fiat: 0,
          loading: false
        }

        // Reload assertions
        await this.loadBalanceAssertions()
      } catch (error) {
        // Check if it's a 409 Conflict (assertion failed)
        if (error.response && error.response.status === 409) {
          const detail = error.response.data.detail
          this.$q.notify({
            type: 'negative',
            message: `Assertion Failed! Expected: ${this.formatSats(detail.expected_sats)} sats, Got: ${this.formatSats(detail.actual_sats)} sats (diff: ${this.formatSats(detail.difference_sats)} sats)`,
            timeout: 5000,
            html: true
          })
          // Still reload to show the failed assertion
          await this.loadBalanceAssertions()
          this.assertionDialog.show = false
        } else {
          LNbits.utils.notifyApiError(error)
        }
      } finally {
        this.assertionDialog.loading = false
      }
    },
    async recheckAssertion(assertionId) {
      try {
        await LNbits.api.request(
          'POST',
          `/castle/api/v1/assertions/${assertionId}/check`,
          this.g.user.wallets[0].adminkey
        )

        this.$q.notify({
          type: 'positive',
          message: 'Assertion re-checked',
          timeout: 2000
        })

        await this.loadBalanceAssertions()
      } catch (error) {
        LNbits.utils.notifyApiError(error)
      }
    },
    async deleteAssertion(assertionId) {
      try {
        await LNbits.api.request(
          'DELETE',
          `/castle/api/v1/assertions/${assertionId}`,
          this.g.user.wallets[0].adminkey
        )

        this.$q.notify({
          type: 'positive',
          message: 'Assertion deleted',
          timeout: 2000
        })

        await this.loadBalanceAssertions()
      } catch (error) {
        LNbits.utils.notifyApiError(error)
      }
    },
    getAccountName(accountId) {
      const account = this.accounts.find(a => a.id === accountId)
      return account ? account.name : accountId
    },
    async loadReconciliationSummary() {
      if (!this.isSuperUser) return

      try {
        const response = await LNbits.api.request(
          'GET',
          '/castle/api/v1/reconciliation/summary',
          this.g.user.wallets[0].adminkey
        )
        this.reconciliation.summary = response.data
      } catch (error) {
        LNbits.utils.notifyApiError(error)
      }
    },
    async loadReconciliationDiscrepancies() {
      if (!this.isSuperUser) return

      try {
        const response = await LNbits.api.request(
          'GET',
          '/castle/api/v1/reconciliation/discrepancies',
          this.g.user.wallets[0].adminkey
        )
        this.reconciliation.discrepancies = response.data
      } catch (error) {
        LNbits.utils.notifyApiError(error)
      }
    },
    async runFullReconciliation() {
      this.reconciliation.checking = true
      try {
        const response = await LNbits.api.request(
          'POST',
          '/castle/api/v1/reconciliation/check-all',
          this.g.user.wallets[0].adminkey
        )

        const results = response.data
        this.$q.notify({
          type: results.failed > 0 ? 'warning' : 'positive',
          message: `Checked ${results.checked} assertions: ${results.passed} passed, ${results.failed} failed`,
          timeout: 3000
        })

        // Reload reconciliation data
        await this.loadReconciliationSummary()
        await this.loadReconciliationDiscrepancies()
        await this.loadBalanceAssertions()
      } catch (error) {
        LNbits.utils.notifyApiError(error)
      } finally {
        this.reconciliation.checking = false
      }
    },
    copyToClipboard(text) {
      navigator.clipboard.writeText(text)
      this.$q.notify({
        type: 'positive',
        message: 'Copied to clipboard!',
        timeout: 1000
      })
    },
    showPayBalanceDialog() {
      // Clear any existing polling
      if (this.payDialog.pollIntervalId) {
        clearInterval(this.payDialog.pollIntervalId)
        this.payDialog.pollIntervalId = null
      }

      this.payDialog.amount = Math.abs(this.balance.balance)
      this.payDialog.paymentRequest = null
      this.payDialog.paymentHash = null
      this.payDialog.checkWalletKey = null
      this.payDialog.show = true
    },
    async showReceivableDialog() {
      // Load users if not already loaded
      if (this.users.length === 0 && this.isSuperUser) {
        await this.loadUsers()
      }
      this.receivableDialog.show = true
    },
    async submitReceivable() {
      this.receivableDialog.loading = true
      try {
        await LNbits.api.request(
          'POST',
          '/castle/api/v1/entries/receivable',
          this.g.user.wallets[0].adminkey,
          {
            description: this.receivableDialog.description,
            amount: this.receivableDialog.amount,
            revenue_account: this.receivableDialog.revenueAccount,
            user_id: this.receivableDialog.selectedUser,
            reference: this.receivableDialog.reference || null,
            currency: this.receivableDialog.currency || null
          }
        )
        this.$q.notify({
          type: 'positive',
          message: 'Receivable added successfully'
        })
        this.receivableDialog.show = false
        this.resetReceivableDialog()
        await this.loadBalance()
        await this.loadTransactions()
      } catch (error) {
        LNbits.utils.notifyApiError(error)
      } finally {
        this.receivableDialog.loading = false
      }
    },
    resetExpenseDialog() {
      this.expenseDialog.description = ''
      this.expenseDialog.amount = null
      this.expenseDialog.expenseAccount = ''
      this.expenseDialog.isEquity = false
      this.expenseDialog.reference = ''
      this.expenseDialog.currency = null
    },
    resetReceivableDialog() {
      this.receivableDialog.selectedUser = ''
      this.receivableDialog.description = ''
      this.receivableDialog.amount = null
      this.receivableDialog.revenueAccount = ''
      this.receivableDialog.reference = ''
      this.receivableDialog.currency = null
    },
    showSettleReceivableDialog(userBalance) {
      // Only show for users who owe castle (negative balance)
      if (userBalance.balance >= 0) return

      this.settleReceivableDialog = {
        show: true,
        user_id: userBalance.user_id,
        username: userBalance.username,
        maxAmount: Math.abs(userBalance.balance), // Convert negative to positive
        amount: Math.abs(userBalance.balance), // Default to full amount
        payment_method: 'cash',
        description: `Payment from ${userBalance.username}`,
        reference: '',
        loading: false
      }
    },
    async submitSettleReceivable() {
      this.settleReceivableDialog.loading = true
      try {
        const response = await LNbits.api.request(
          'POST',
          '/castle/api/v1/receivables/settle',
          this.g.user.wallets[0].adminkey,
          {
            user_id: this.settleReceivableDialog.user_id,
            amount: this.settleReceivableDialog.amount,
            payment_method: this.settleReceivableDialog.payment_method,
            description: this.settleReceivableDialog.description,
            reference: this.settleReceivableDialog.reference || null
          }
        )

        this.$q.notify({
          type: 'positive',
          message: response.data.message,
          timeout: 3000
        })

        this.settleReceivableDialog.show = false

        // Reload balances
        await this.loadBalance()
        await this.loadTransactions()
        await this.loadAllUserBalances()
      } catch (error) {
        LNbits.utils.notifyApiError(error)
      } finally {
        this.settleReceivableDialog.loading = false
      }
    },
    formatSats(amount) {
      return new Intl.NumberFormat().format(amount)
    },
    formatFiat(amount, currency) {
      return new Intl.NumberFormat('en-US', {
        style: 'currency',
        currency: currency,
        minimumFractionDigits: 2,
        maximumFractionDigits: 2
      }).format(amount)
    },
    formatDate(dateString) {
      return new Date(dateString).toLocaleDateString()
    },
    getTotalAmount(entry) {
      if (!entry.lines || entry.lines.length === 0) return 0
      return entry.lines.reduce((sum, line) => sum + line.debit + line.credit, 0) / 2
    },
    getEntryFiatAmount(entry) {
      // Extract fiat amount from metadata if available
      if (!entry.lines || entry.lines.length === 0) return null

      for (const line of entry.lines) {
        if (line.metadata && line.metadata.fiat_currency && line.metadata.fiat_amount) {
          return this.formatFiat(line.metadata.fiat_amount, line.metadata.fiat_currency)
        }
      }
      return null
    },
    isReceivable(entry) {
      // Check if this is a receivable entry (user owes castle)
      // Receivables have a debit to an "Accounts Receivable" account with the user's ID
      if (!entry.lines || entry.lines.length === 0) return false

      for (const line of entry.lines) {
        // Look for a line with positive debit on an accounts receivable account
        if (line.debit > 0) {
          // Check if the account is associated with this user's receivables
          const account = this.accounts.find(a => a.id === line.account_id)
          if (account && account.name && account.name.includes('Assets:Receivable') && account.account_type === 'asset') {
            return true
          }
        }
      }
      return false
    },
    isPayable(entry) {
      // Check if this is a payable entry (castle owes user)
      // Payables have a credit to an "Accounts Payable" account with the user's ID
      if (!entry.lines || entry.lines.length === 0) return false

      for (const line of entry.lines) {
        // Look for a line with positive credit on an accounts payable account
        if (line.credit > 0) {
          // Check if the account is associated with this user's payables
          const account = this.accounts.find(a => a.id === line.account_id)
          if (account && account.name && account.name.includes('Liabilities:Payable') && account.account_type === 'liability') {
            return true
          }
        }
      }
      return false
    }
  },
  async created() {
    // Load settings first to determine if user is super user
    await this.loadSettings()
    await this.loadUserWallet()
    await this.loadBalance()
    await this.loadTransactions()
    await this.loadAccounts()
    await this.loadCurrencies()
    await this.loadManualPaymentRequests()
    // Load users and pending expenses if super user
    if (this.isSuperUser) {
      await this.loadUsers()
      await this.loadPendingExpenses()
      await this.loadBalanceAssertions()
      await this.loadReconciliationSummary()
      await this.loadReconciliationDiscrepancies()
    }
  }
})
