
'use client';

import { useEffect, useMemo, useState } from 'react';
import React from 'react';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
import { Button } from '@/components/ui/button';
import { type Customer, type Supplier, type SalesInvoice, type PurchaseOrder, type CustomerPayment, type SupplierPayment, type PurchaseReturn } from '@/lib/types';
import { format } from 'date-fns';
import { ar } from 'date-fns/locale';
import { Check, ChevronsUpDown, Share2, ChevronDown, ChevronUp, Printer } from 'lucide-react';
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import { cn } from '@/lib/utils';
import { Input } from '../ui/input';
import { formatCurrency } from '@/lib/currency-formatter';
import type { PrintingSettings } from '@/lib/types';
import { resolveCoverageSplit, resolveInvoiceAmountForParty } from '@/lib/modules/sales/shared/coverage-allocation';

type Party = {
  id: string;
  name: string;
  type: 'customer' | 'supplier';
  balance: number;
  accountCode?: string;
};

type StatementTransaction = {
  type: 'invoice' | 'order' | 'payment' | 'return';
  flow: 'debit' | 'credit';
  id: string;
  date: Date;
  description: string;
  debit: number;
  credit: number;
  balance: number;
  currencyCode: string;
  baseCurrencyCode: string;
  amountTx: number;
  amountBase: number;
  debitBase: number;
  creditBase: number;
  details?: any;
  amount: number;
};

type CurrencyBalanceRow = {
  currencyCode: string;
  debit: number;
  credit: number;
  net: number;
};

type StatementSection = {
  currencyCode: string;
  transactions: StatementTransaction[];
  openingBalance: number;
  finalBalance: number;
};

const ALL_CURRENCIES_FILTER = '__ALL__';

type PartyStatementProps = {
  customers: Customer[];
  suppliers: Supplier[];
  invoices: SalesInvoice[];
  orders: PurchaseOrder[];
  returns?: PurchaseReturn[];
  customerPayments: CustomerPayment[];
  supplierPayments: SupplierPayment[];
  initialPartyId?: string;
  t: any;
  tGlobal: any;
  locale: string;
  currencySymbol?: string;
  currencies?: Array<{ code: string; symbol: string; isDefault?: boolean }>;
  printingSettings?: PrintingSettings;
};

export default function PartyStatement({
  customers,
  suppliers,
  invoices,
  orders,
  returns = [],
  customerPayments,
  supplierPayments,
  initialPartyId,
  t,
  tGlobal,
  locale,
  currencySymbol = '$',
  currencies = [],
  printingSettings,
}: PartyStatementProps) {
  const getSymbol = (code: string): string => {
    if (!code) return currencySymbol;
    const found = currencies.find((c) => c.code.toUpperCase() === code.toUpperCase());
    return found?.symbol || code;
  };
  const getCurrencyLabel = (code: string): string => {
    const symbol = getSymbol(code);
    return symbol && symbol !== code ? `${code} (${symbol})` : code;
  };
  const defaultCurrencyCode = useMemo(() => {
    const preferred = currencies.find((currency) => currency.isDefault && String(currency.code || '').trim());
    if (preferred) return String(preferred.code).trim().toUpperCase();
    const fallback = currencies.find((currency) => String(currency.code || '').trim());
    if (fallback) return String(fallback.code).trim().toUpperCase();
    return String(t.localCurrencyCode || 'LOCAL').trim().toUpperCase() || 'LOCAL';
  }, [currencies, t.localCurrencyCode]);
  const [selectedPartyId, setSelectedPartyId] = useState('');
  const [popoverOpen, setPopoverOpen] = useState(false);
  const [searchTerm, setSearchTerm] = useState('');
  const [expandedRows, setExpandedRows] = useState<Set<string>>(new Set());
  const [dateFrom, setDateFrom] = useState('');
  const [dateTo, setDateTo] = useState('');
  const [currencyFilter, setCurrencyFilter] = useState('');

  const parties = useMemo<Party[]>(() => {
    const customerParties = customers.map((c) => ({
      id: `customer:${c.id}`,
      name: c.name,
      type: 'customer' as const,
      balance: c.balance,
      accountCode: String((c as any)?.accountCode || '').trim() || undefined,
    }));
    const supplierParties = suppliers.map((s) => ({
      id: `supplier:${s.id}`,
      name: s.name,
      type: 'supplier' as const,
      balance: s.balance,
      accountCode: String((s as any)?.accountCode || '').trim() || undefined,
    }));
    return [...customerParties, ...supplierParties];
  }, [customers, suppliers]);

  const filteredParties = useMemo(() => {
    if (!searchTerm) return parties;
    const q = searchTerm.toLowerCase();
    return parties.filter((p) => {
      const typeLabel = p.type === 'customer' ? String(t.partyTypeCustomer ?? 'Customer') : String(t.partyTypeSupplier ?? 'Supplier');
      return [p.name, p.accountCode || '', typeLabel]
        .join(' ')
        .toLowerCase()
        .includes(q);
    });
  }, [parties, searchTerm]);

  const formatPartyLabel = (party: Party | undefined) => {
    if (!party) return t.selectParty ?? 'Select a customer or supplier...';
    const typeLabel = party.type === 'customer'
      ? (t.partyTypeCustomer ?? 'Customer')
      : (t.partyTypeSupplier ?? 'Supplier');
    const accountSegment = party.accountCode ? ` - ${party.accountCode}` : '';
    return `${party.name} (${typeLabel}${accountSegment})`;
  };

  useEffect(() => {
    if (!initialPartyId) return;
    const exists = parties.some((party) => party.id === initialPartyId);
    if (!exists) return;
    if (selectedPartyId === initialPartyId) return;
    setSelectedPartyId(initialPartyId);
  }, [initialPartyId, parties, selectedPartyId]);

  useEffect(() => {
    if (currencyFilter) return;
    setCurrencyFilter(defaultCurrencyCode);
  }, [currencyFilter, defaultCurrencyCode]);

  const selectedParty = useMemo(() => {
    return parties.find((p) => p.id === selectedPartyId);
  }, [selectedPartyId, parties]);

  const statementData = useMemo(() => {
    if (!selectedPartyId || !selectedParty) return null;

    const [partyType, partyId] = selectedPartyId.split(':');
    const localCurrencyCode = defaultCurrencyCode;
    const selectedCustomer = partyType === 'customer'
      ? customers.find((entry) => String(entry.id || '').trim() === partyId)
      : undefined;
    const selectedSupplier = partyType === 'supplier'
      ? suppliers.find((entry) => String(entry.id || '').trim() === partyId)
      : undefined;
    const selectedPartyName = String(selectedParty.name || '').trim();
    const selectedPartyAccountCode = String((selectedCustomer as any)?.accountCode || (selectedSupplier as any)?.accountCode || '').trim();

    const linkedCustomerIds = new Set<string>();
    const linkedSupplierIds = new Set<string>();

    // Strict matching by selected party type to avoid mixing customer/supplier ledgers.
    if (partyType === 'customer') {
      linkedCustomerIds.add(partyId);
      if (selectedPartyAccountCode || selectedPartyName) {
        for (const customer of customers) {
          const customerId = String(customer.id || '').trim();
          if (!customerId) continue;
          const customerName = String((customer as any)?.name || '').trim();
          const customerAccountCode = String((customer as any)?.accountCode || '').trim();
          const isAccountMatch = selectedPartyAccountCode && customerAccountCode && customerAccountCode === selectedPartyAccountCode;
          const isNameMatch = selectedPartyName && customerName && customerName === selectedPartyName;
          if (isAccountMatch || isNameMatch) linkedCustomerIds.add(customerId);
        }
      }

      if (selectedPartyAccountCode || selectedPartyName) {
        for (const supplier of suppliers) {
          const supplierId = String(supplier.id || '').trim();
          if (!supplierId) continue;
          const supplierName = String((supplier as any)?.name || '').trim();
          const supplierAccountCode = String((supplier as any)?.accountCode || '').trim();
          const isAccountMatch = selectedPartyAccountCode && supplierAccountCode && supplierAccountCode === selectedPartyAccountCode;
          const isNameMatch = selectedPartyName && supplierName && supplierName === selectedPartyName;
          if (isAccountMatch || isNameMatch) linkedSupplierIds.add(supplierId);
        }
      }
    }

    if (partyType === 'supplier') {
      linkedSupplierIds.add(partyId);
      if (selectedPartyAccountCode || selectedPartyName) {
        for (const supplier of suppliers) {
          const supplierId = String(supplier.id || '').trim();
          if (!supplierId) continue;
          const supplierName = String((supplier as any)?.name || '').trim();
          const supplierAccountCode = String((supplier as any)?.accountCode || '').trim();
          const isAccountMatch = selectedPartyAccountCode && supplierAccountCode && supplierAccountCode === selectedPartyAccountCode;
          const isNameMatch = selectedPartyName && supplierName && supplierName === selectedPartyName;
          if (isAccountMatch || isNameMatch) linkedSupplierIds.add(supplierId);
        }
      }

      if (selectedPartyAccountCode || selectedPartyName) {
        for (const customer of customers) {
          const customerId = String(customer.id || '').trim();
          if (!customerId) continue;
          const customerName = String((customer as any)?.name || '').trim();
          const customerAccountCode = String((customer as any)?.accountCode || '').trim();
          const isAccountMatch = selectedPartyAccountCode && customerAccountCode && customerAccountCode === selectedPartyAccountCode;
          const isNameMatch = selectedPartyName && customerName && customerName === selectedPartyName;
          if (isAccountMatch || isNameMatch) linkedCustomerIds.add(customerId);
        }
      }
    }

    const normalizeCurrencyCode = (value: unknown) => {
      const normalized = String(value || '').trim().toUpperCase();
      return normalized || localCurrencyCode;
    };

    const toDateOnly = (value: Date) => {
      const next = new Date(value);
      next.setHours(0, 0, 0, 0);
      return next;
    };

    const fromDateValue = dateFrom ? toDateOnly(new Date(`${dateFrom}T00:00:00`)) : null;
    const toDateValue = dateTo ? toDateOnly(new Date(`${dateTo}T00:00:00`)) : null;

    const toBaseAmount = (amount: number, amountBase: unknown, exchangeRate: unknown, currencyCode: string, baseCurrencyCode: string) => {
      if (typeof amountBase === 'number' && Number.isFinite(amountBase)) {
        return amountBase;
      }
      if (currencyCode === baseCurrencyCode) return amount;
      const rate = Number(exchangeRate || 0);
      return Number.isFinite(rate) && rate > 0 ? amount * rate : amount;
    };

    const roundToTwo = (value: number) => Math.round((Number(value || 0) + Number.EPSILON) * 100) / 100;

    const resolveCustomerInvoiceShare = (invoice: SalesInvoice) => {
      const invoiceCustomerId = String(invoice.customerId || '').trim();
      const invoiceCustomerName = String((invoice as any).customerName || '').trim();
      const invoiceSecondaryCustomerId = String((invoice as any).secondaryCustomerId || '').trim();
      const invoiceSecondaryCustomerName = String((invoice as any).secondaryCustomerName || '').trim();
      const totalAmountTx = Number(invoice.grandTotal || 0);
      const split = resolveCoverageSplit({
        totalAmount: totalAmountTx,
        secondaryCoveragePercent: Number((invoice as any).secondaryCoveragePercent || 0),
        secondaryCoverageAmount: Number((invoice as any).secondaryCoverageAmount || 0),
        hasSecondaryCustomer: Boolean(invoiceSecondaryCustomerId),
      });

      const primaryMatched = linkedCustomerIds.has(invoiceCustomerId)
        || (selectedPartyName && invoiceCustomerName === selectedPartyName);
      const secondaryMatched = split.hasSecondaryCoverage && (
        linkedCustomerIds.has(invoiceSecondaryCustomerId)
        || (selectedPartyName && invoiceSecondaryCustomerName === selectedPartyName)
      );

      return resolveInvoiceAmountForParty({
        totalAmount: totalAmountTx,
        primaryMatched,
        secondaryMatched,
        split,
      });
    };

    const inDateRange = (date: Date) => {
      const dateOnly = toDateOnly(date);
      if (fromDateValue && dateOnly < fromDateValue) return false;
      if (toDateValue && dateOnly > toDateValue) return false;
      return true;
    };

    const isBeforeRange = (date: Date) => {
      if (!fromDateValue) return false;
      return toDateOnly(date) < fromDateValue;
    };

    const buildSections = (allTx: StatementTransaction[]) => {
      const currencyBalancesMap = new Map<string, CurrencyBalanceRow>();
      for (const tx of allTx.filter((row) => inDateRange(row.date))) {
        const current = currencyBalancesMap.get(tx.currencyCode) || {
          currencyCode: tx.currencyCode,
          debit: 0,
          credit: 0,
          net: 0,
        };
        const debitAmount = tx.flow === 'debit' ? tx.amountTx : 0;
        const creditAmount = tx.flow === 'credit' ? tx.amountTx : 0;
        current.debit += debitAmount;
        current.credit += creditAmount;
        current.net += debitAmount - creditAmount;
        currencyBalancesMap.set(tx.currencyCode, current);
      }

      const currencyBalances = Array.from(currencyBalancesMap.values()).sort((a, b) => a.currencyCode.localeCompare(b.currencyCode));
      const availableCurrencies = Array.from(new Set(allTx.map((tx) => tx.currencyCode))).sort((a, b) => a.localeCompare(b));
      const selectedCurrencies = currencyFilter === ALL_CURRENCIES_FILTER
        ? availableCurrencies
        : availableCurrencies.filter((code) => code === currencyFilter);

      const sections = selectedCurrencies.map((currencyCode) => {
        const currencyScoped = allTx.filter((tx) => tx.currencyCode === currencyCode);
        const transactions = currencyScoped.filter((tx) => inDateRange(tx.date));
        const openingBalance = currencyScoped
          .filter((tx) => isBeforeRange(tx.date))
          .reduce((sum, tx) => sum + (tx.flow === 'debit' ? tx.amountTx : -tx.amountTx), 0);

        let runningBalance = openingBalance;
        const preparedTransactions = transactions.map((tx) => {
          const debit = tx.flow === 'debit' ? tx.amountTx : 0;
          const credit = tx.flow === 'credit' ? tx.amountTx : 0;
          runningBalance += debit - credit;
          return { ...tx, debit, credit, balance: runningBalance };
        });

        return {
          currencyCode,
          transactions: preparedTransactions,
          openingBalance,
          finalBalance: runningBalance,
        } satisfies StatementSection;
      });

      return {
        sections,
        transactions: sections.flatMap((section) => section.transactions),
        openingBalance: sections.length === 1 ? sections[0].openingBalance : 0,
        finalBalance: sections.length === 1 ? sections[0].finalBalance : 0,
        currencyBalances,
        displayCurrencyCode: sections.length === 1 ? sections[0].currencyCode : '',
        isLocalView: sections.length === 1 ? sections[0].currencyCode === localCurrencyCode : false,
        isAllCurrenciesView: currencyFilter === ALL_CURRENCIES_FILTER,
      };
    };

    if (partyType === 'customer') {
      const partyInvoices = invoices.filter((inv) => {
        const matchesParty = resolveCustomerInvoiceShare(inv) > 0;
        if (!matchesParty) return false;

        // Exclude internal store-flow documents that are not customer-facing billing docs.
        // - Shipment documents (documentType === 'shipment') are logistics-only.
        // - Store order originals (source === 'store' + storeStatus field) are order records,
        //   not accounting entries — the tax_invoice is the billing document.
        const documentType = String((inv as any).documentType || '').trim();
        if (documentType === 'shipment') return false;

        const source = String((inv as any).source || '').trim();
        const hasStoreStatus = (inv as any).storeStatus !== undefined && (inv as any).storeStatus !== null;
        const invoiceNum = String(inv.invoiceNumber || '').trim();
        if (source === 'store' && hasStoreStatus && !invoiceNum.startsWith('ST/') && !invoiceNum.startsWith('S/')) {
          return false;
        }

        return true;
      });
      const partyPayments = customerPayments.filter((p) => {
        const paymentCustomerId = String((p as any).customerId || '').trim();
        const paymentCustomerName = String((p as any).customerName || '').trim();
        return linkedCustomerIds.has(paymentCustomerId)
          || (selectedPartyName && paymentCustomerName === selectedPartyName);
      });

      const partyOrders = orders.filter((ord) => linkedSupplierIds.has(String(ord.supplierId || '').trim()));
      const partyReturnsAsSupplier = returns.filter((ret) => linkedSupplierIds.has(String(ret.supplierId || '').trim()) && ret.status !== 'cancelled');
      const partySupplierPayments = supplierPayments.filter((p) => linkedSupplierIds.has(String(p.supplierId || '').trim()));

      const allTx: StatementTransaction[] = [
        ...partyInvoices.map((inv) => {
          const currencyCode = normalizeCurrencyCode((inv as any).currencyCode || (inv as any).baseCurrencyCode);
          const baseCurrencyCode = normalizeCurrencyCode((inv as any).baseCurrencyCode || localCurrencyCode);
          const amountTx = resolveCustomerInvoiceShare(inv);
          const invoiceBaseTotal = toBaseAmount(Number(inv.grandTotal || 0), (inv as any).grandTotalBase, (inv as any).exchangeRate, currencyCode, baseCurrencyCode);
          const amountBase = Number(inv.grandTotal || 0) > 0
            ? roundToTwo((amountTx / Number(inv.grandTotal || 0)) * invoiceBaseTotal)
            : 0;
          return {
            type: 'invoice' as const,
            flow: 'debit' as const,
            id: inv.id,
            date: new Date(inv.date),
            description: (t.invoiceDescription ?? 'Invoice #{id}').replace('{id}', inv.invoiceNumber || inv.id.slice(-6)),
            amount: amountBase,
            amountTx,
            amountBase,
            currencyCode,
            baseCurrencyCode,
            debit: amountBase,
            credit: 0,
            debitBase: amountBase,
            creditBase: 0,
            balance: 0,
            details: inv,
          };
        }),
      ...partyPayments.flatMap((p) => {
        // Only include unallocated payments directly; allocated payments are shown via their allocations
        if (Array.isArray(p.allocations) && p.allocations.length > 0 && !p.isAdvance) {
          return [];
        }
        const currencyCode = normalizeCurrencyCode(p.currencyCode || p.baseCurrencyCode);
        const baseCurrencyCode = normalizeCurrencyCode(p.baseCurrencyCode || localCurrencyCode);
        const amountTx = Number(p.amount || 0);
        const amountBase = toBaseAmount(amountTx, p.amountBase, p.exchangeRate, currencyCode, baseCurrencyCode);
        return [{
          type: 'payment' as const,
          flow: 'credit' as const,
          id: p.id,
          date: new Date(p.date),
          description: t.paymentDescription ?? 'Payment',
          amount: amountBase,
          amountTx,
          amountBase,
          currencyCode,
          baseCurrencyCode,
          debit: 0,
          credit: amountBase,
          debitBase: 0,
          creditBase: amountBase,
          balance: 0,
          details: p,
        }];
      }),
      // Add allocation entries for multi-currency payments
      ...partyPayments.flatMap((p) => {
        if (!Array.isArray((p as any).allocations) || (p as any).allocations.length === 0) return [];
        return (p as any).allocations.map((alloc: any) => {
          const allocCurrencyCode = normalizeCurrencyCode(alloc.invoiceCurrencyCode || localCurrencyCode);
          const paymentBaseCurrencyCode = normalizeCurrencyCode(p.baseCurrencyCode || localCurrencyCode);
          const allocAmountTx = Number(alloc.amount || 0);
          const allocAmountBase = Number(alloc.amountBase || 0);
          const description = (t.paymentAllocationDescription ?? 'Payment allocation for invoice #{id}').replace('{id}', alloc.invoiceNumber || alloc.invoiceId.slice(-6));
          return {
            type: 'payment' as const,
            flow: 'credit' as const,
            id: `${p.id}:${alloc.invoiceId}`,
            date: new Date(p.date),
            description,
            amount: allocAmountBase,
            amountTx: allocAmountTx,
            amountBase: allocAmountBase,
            currencyCode: allocCurrencyCode,
            baseCurrencyCode: paymentBaseCurrencyCode,
            debit: 0,
            credit: allocAmountTx,
            debitBase: 0,
            creditBase: allocAmountBase,
            balance: 0,
            details: { ...p, allocationDetail: alloc },
          };
        });
      }),
      // Purchases from same party when it also acts as supplier (opposite effect to sales receivable)
      ...partyOrders.map((ord) => {
        const currencyCode = normalizeCurrencyCode(ord.currencyCode || ord.baseCurrencyCode);
        const baseCurrencyCode = normalizeCurrencyCode(ord.baseCurrencyCode || localCurrencyCode);
        const amountTx = Number(ord.grandTotal || 0);
        const amountBase = toBaseAmount(amountTx, ord.grandTotalBase, ord.exchangeRate, currencyCode, baseCurrencyCode);
        const isShipmentDoc = ord.documentType === 'shipment';
        const docLabel = isShipmentDoc ? (t.shipmentDocLabel ?? 'ارسالية') : (t.purchaseInvoice ?? 'فاتورة مشتريات');
        return {
          type: 'order' as const,
          flow: 'credit' as const,
          id: `purch:${ord.id}`,
          date: new Date(ord.date),
          description: `${docLabel} #${ord.orderNumber || ord.id.slice(-6)}`,
          amount: amountBase,
          amountTx,
          amountBase,
          currencyCode,
          baseCurrencyCode,
          debit: 0,
          credit: amountBase,
          debitBase: 0,
          creditBase: amountBase,
          balance: 0,
          details: ord,
        };
      }),
      ...partyReturnsAsSupplier.map((ret) => {
        const currencyCode = normalizeCurrencyCode(ret.currencyCode || ret.baseCurrencyCode);
        const baseCurrencyCode = normalizeCurrencyCode(ret.baseCurrencyCode || localCurrencyCode);
        const amountTx = Number(ret.totalAmount || 0);
        const amountBase = toBaseAmount(amountTx, ret.totalAmountBase, ret.fxRateInvoice, currencyCode, baseCurrencyCode);
        return {
          type: 'return' as const,
          flow: 'debit' as const,
          id: `purch-ret:${ret.id}`,
          date: new Date(ret.createdAt),
          description: (t.returnDescription ?? 'Purchase Return #{id}').replace('{id}', ret.returnNumber || ret.id.slice(-6)),
          amount: amountBase,
          amountTx,
          amountBase,
          currencyCode,
          baseCurrencyCode,
          debit: amountBase,
          credit: 0,
          debitBase: amountBase,
          creditBase: 0,
          balance: 0,
          details: ret,
        };
      }),
      ...partySupplierPayments.flatMap((p) => {
        if (Array.isArray(p.allocations) && p.allocations.length > 0 && !p.isAdvance) {
          return [];
        }
        const currencyCode = normalizeCurrencyCode(p.currencyCode || p.baseCurrencyCode);
        const baseCurrencyCode = normalizeCurrencyCode(p.baseCurrencyCode || localCurrencyCode);
        const amountTx = Number(p.amount || 0);
        const amountBase = toBaseAmount(amountTx, p.amountBase, p.exchangeRate, currencyCode, baseCurrencyCode);
        return [{
          type: 'payment' as const,
          flow: 'debit' as const,
          id: `supp-pay:${p.id}`,
          date: new Date(p.date),
          description: t.paymentDescription ?? 'Payment',
          amount: amountBase,
          amountTx,
          amountBase,
          currencyCode,
          baseCurrencyCode,
          debit: amountBase,
          credit: 0,
          debitBase: amountBase,
          creditBase: 0,
          balance: 0,
          details: p,
        }];
      }),
      ...partySupplierPayments.flatMap((p) => {
        if (!Array.isArray(p.allocations) || p.allocations.length === 0) return [];
        return p.allocations.map((alloc) => {
          const allocCurrencyCode = normalizeCurrencyCode(alloc.invoiceCurrencyCode || localCurrencyCode);
          const paymentBaseCurrencyCode = normalizeCurrencyCode(p.baseCurrencyCode || localCurrencyCode);
          const allocAmountTx = Number(alloc.amount || 0);
          const allocAmountBase = Number(alloc.amountBase || 0);
          const description = (t.paymentAllocationDescription ?? 'Payment allocation for order #{id}').replace('{id}', alloc.purchaseOrderNumber || alloc.purchaseOrderId?.slice(-6) || '');
          return {
            type: 'payment' as const,
            flow: 'debit' as const,
            id: `supp-pay:${p.id}:${alloc.purchaseOrderId}`,
            date: new Date(p.date),
            description,
            amount: allocAmountBase,
            amountTx: allocAmountTx,
            amountBase: allocAmountBase,
            currencyCode: allocCurrencyCode,
            baseCurrencyCode: paymentBaseCurrencyCode,
            debit: allocAmountBase,
            credit: 0,
            debitBase: allocAmountBase,
            creditBase: 0,
            balance: 0,
            details: { ...p, allocationDetail: alloc },
          };
        });
      }),
      ].sort((a, b) => a.date.getTime() - b.date.getTime());

      return buildSections(allTx);
    }

    const partyOrders = orders.filter((ord) => linkedSupplierIds.has(String(ord.supplierId || '').trim()));
    const partyReturns = returns.filter((ret) => linkedSupplierIds.has(String(ret.supplierId || '').trim()) && ret.status !== 'cancelled');
    const partyPayments = supplierPayments.filter((p) => linkedSupplierIds.has(String(p.supplierId || '').trim()));

    const partyInvoices = invoices.filter((inv) => {
      const matchesParty = resolveCustomerInvoiceShare(inv) > 0;
      if (!matchesParty) return false;

      // Keep statement aligned with customer branch: exclude non-billing store-flow docs.
      const documentType = String((inv as any).documentType || '').trim();
      if (documentType === 'shipment') return false;

      const source = String((inv as any).source || '').trim();
      const hasStoreStatus = (inv as any).storeStatus !== undefined && (inv as any).storeStatus !== null;
      const invoiceNum = String(inv.invoiceNumber || '').trim();
      if (source === 'store' && hasStoreStatus && !invoiceNum.startsWith('ST/') && !invoiceNum.startsWith('S/')) {
        return false;
      }

      return true;
    });
    const partyCustomerPayments = customerPayments.filter((p) => {
      const paymentCustomerId = String((p as any).customerId || '').trim();
      const paymentCustomerName = String((p as any).customerName || '').trim();
      return linkedCustomerIds.has(paymentCustomerId)
        || (selectedPartyName && paymentCustomerName === selectedPartyName);
    });

    const allTx: StatementTransaction[] = [
      ...partyOrders.map((ord) => {
        const currencyCode = normalizeCurrencyCode(ord.currencyCode || ord.baseCurrencyCode);
        const baseCurrencyCode = normalizeCurrencyCode(ord.baseCurrencyCode || localCurrencyCode);
        const amountTx = Number(ord.grandTotal || 0);
        const amountBase = toBaseAmount(amountTx, ord.grandTotalBase, ord.exchangeRate, currencyCode, baseCurrencyCode);
        const isShipmentDoc = ord.documentType === 'shipment';
        const docLabel = isShipmentDoc ? (t.shipmentDocLabel ?? 'ارسالية') : (t.purchaseInvoice ?? 'فاتورة مشتريات');
        return {
          type: 'order' as const,
          flow: 'credit' as const,
          id: ord.id,
          date: new Date(ord.date),
          description: `${docLabel} #${ord.orderNumber || ord.id.slice(-6)}`,
          amount: amountBase,
          amountTx,
          amountBase,
          currencyCode,
          baseCurrencyCode,
          debit: amountBase,
          credit: 0,
          debitBase: amountBase,
          creditBase: 0,
          balance: 0,
          details: ord,
        };
      }),
      ...partyPayments.map((p) => {
        // Only include unallocated payments directly; allocated payments are shown via their allocations
        if (Array.isArray(p.allocations) && p.allocations.length > 0 && !p.isAdvance) {
          return null;
        }
        const currencyCode = normalizeCurrencyCode(p.currencyCode || p.baseCurrencyCode);
        const baseCurrencyCode = normalizeCurrencyCode(p.baseCurrencyCode || localCurrencyCode);
        const amountTx = Number(p.amount || 0);
        const amountBase = toBaseAmount(amountTx, p.amountBase, p.exchangeRate, currencyCode, baseCurrencyCode);
        return {
          type: 'payment' as const,
          flow: 'debit' as const,
          id: p.id,
          date: new Date(p.date),
          description: t.paymentDescription ?? 'Payment',
          amount: amountBase,
          amountTx,
          amountBase,
          currencyCode,
          baseCurrencyCode,
          debit: 0,
          credit: amountBase,
          debitBase: 0,
          creditBase: amountBase,
          balance: 0,
          details: p,
        };
      }).filter((tx) => tx !== null) as StatementTransaction[],
      // Add allocation entries for multi-currency payments
      ...partyPayments.flatMap((p) => {
        if (!Array.isArray(p.allocations) || p.allocations.length === 0) return [];
        return p.allocations.map((alloc) => {
          const allocCurrencyCode = normalizeCurrencyCode(alloc.invoiceCurrencyCode || localCurrencyCode);
          const paymentBaseCurrencyCode = normalizeCurrencyCode(p.baseCurrencyCode || localCurrencyCode);
          const allocAmountTx = Number(alloc.amount || 0);
          const allocAmountBase = Number(alloc.amountBase || 0);
          const description = (t.paymentAllocationDescription ?? 'Payment allocation for order #{id}').replace('{id}', alloc.purchaseOrderNumber || alloc.purchaseOrderId.slice(-6));
          return {
            type: 'payment' as const,
            flow: 'debit' as const,
            id: `${p.id}:${alloc.purchaseOrderId}`,
            date: new Date(p.date),
            description,
            amount: allocAmountBase,
            amountTx: allocAmountTx,
            amountBase: allocAmountBase,
            currencyCode: allocCurrencyCode,
            baseCurrencyCode: paymentBaseCurrencyCode,
            debit: 0,
            credit: allocAmountTx,
            debitBase: 0,
            creditBase: allocAmountBase,
            balance: 0,
            details: { ...p, allocationDetail: alloc },
          };
        });
      }),
      ...partyReturns.map((ret) => {
        const currencyCode = normalizeCurrencyCode(ret.currencyCode || ret.baseCurrencyCode);
        const baseCurrencyCode = normalizeCurrencyCode(ret.baseCurrencyCode || localCurrencyCode);
        const amountTx = Number(ret.totalAmount || 0);
        const amountBase = toBaseAmount(amountTx, ret.totalAmountBase, ret.fxRateInvoice, currencyCode, baseCurrencyCode);
        return {
          type: 'return' as const,
          flow: 'debit' as const,
          id: ret.id,
          date: new Date(ret.createdAt),
          description: (t.returnDescription ?? 'Purchase Return #{id}').replace('{id}', ret.returnNumber || ret.id.slice(-6)),
          amount: amountBase,
          amountTx,
          amountBase,
          currencyCode,
          baseCurrencyCode,
          debit: 0,
          credit: amountBase,
          debitBase: 0,
          creditBase: amountBase,
          balance: 0,
          details: ret,
        };
      }),
      ...partyInvoices.map((inv) => {
        const currencyCode = normalizeCurrencyCode((inv as any).currencyCode || (inv as any).baseCurrencyCode);
        const baseCurrencyCode = normalizeCurrencyCode((inv as any).baseCurrencyCode || localCurrencyCode);
        const amountTx = resolveCustomerInvoiceShare(inv);
        const invoiceBaseTotal = toBaseAmount(Number(inv.grandTotal || 0), (inv as any).grandTotalBase, (inv as any).exchangeRate, currencyCode, baseCurrencyCode);
        const amountBase = Number(inv.grandTotal || 0) > 0
          ? roundToTwo((amountTx / Number(inv.grandTotal || 0)) * invoiceBaseTotal)
          : 0;
        return {
          type: 'invoice' as const,
          flow: 'debit' as const,
          id: `sale:${inv.id}`,
          date: new Date(inv.date),
          description: (t.invoiceDescription ?? 'Invoice #{id}').replace('{id}', inv.invoiceNumber || inv.id.slice(-6)),
          amount: amountBase,
          amountTx,
          amountBase,
          currencyCode,
          baseCurrencyCode,
          debit: amountBase,
          credit: 0,
          debitBase: amountBase,
          creditBase: 0,
          balance: 0,
          details: inv,
        };
      }),
      ...partyCustomerPayments.flatMap((p) => {
        if (Array.isArray(p.allocations) && p.allocations.length > 0 && !p.isAdvance) {
          return [];
        }
        const currencyCode = normalizeCurrencyCode(p.currencyCode || p.baseCurrencyCode);
        const baseCurrencyCode = normalizeCurrencyCode(p.baseCurrencyCode || localCurrencyCode);
        const amountTx = Number(p.amount || 0);
        const amountBase = toBaseAmount(amountTx, p.amountBase, p.exchangeRate, currencyCode, baseCurrencyCode);
        return [{
          type: 'payment' as const,
          flow: 'credit' as const,
          id: `cust-pay:${p.id}`,
          date: new Date(p.date),
          description: t.paymentDescription ?? 'Payment',
          amount: amountBase,
          amountTx,
          amountBase,
          currencyCode,
          baseCurrencyCode,
          debit: 0,
          credit: amountBase,
          debitBase: 0,
          creditBase: amountBase,
          balance: 0,
          details: p,
        }];
      }),
      ...partyCustomerPayments.flatMap((p) => {
        if (!Array.isArray((p as any).allocations) || (p as any).allocations.length === 0) return [];
        return (p as any).allocations.map((alloc: any) => {
          const allocCurrencyCode = normalizeCurrencyCode(alloc.invoiceCurrencyCode || localCurrencyCode);
          const paymentBaseCurrencyCode = normalizeCurrencyCode(p.baseCurrencyCode || localCurrencyCode);
          const allocAmountTx = Number(alloc.amount || 0);
          const allocAmountBase = Number(alloc.amountBase || 0);
          const description = (t.paymentAllocationDescription ?? 'Payment allocation for invoice #{id}').replace('{id}', alloc.invoiceNumber || alloc.invoiceId?.slice(-6) || '');
          return {
            type: 'payment' as const,
            flow: 'credit' as const,
            id: `cust-pay:${p.id}:${alloc.invoiceId}`,
            date: new Date(p.date),
            description,
            amount: allocAmountBase,
            amountTx: allocAmountTx,
            amountBase: allocAmountBase,
            currencyCode: allocCurrencyCode,
            baseCurrencyCode: paymentBaseCurrencyCode,
            debit: 0,
            credit: allocAmountBase,
            debitBase: 0,
            creditBase: allocAmountBase,
            balance: 0,
            details: { ...p, allocationDetail: alloc },
          };
        });
      }),
    ].sort((a, b) => a.date.getTime() - b.date.getTime());

    return buildSections(allTx);
  }, [
    defaultCurrencyCode,
    selectedPartyId,
    selectedParty,
    customers,
    suppliers,
    invoices,
    orders,
    returns,
    customerPayments,
    supplierPayments,
    t,
    dateFrom,
    dateTo,
    currencyFilter,
  ]);

  const currencyOptions = useMemo(() => {
    const values = new Map<string, { code: string; label: string }>();

    currencies.forEach((currency) => {
      const code = String(currency.code || '').trim().toUpperCase();
      if (!code) return;
      values.set(code, { code, label: getCurrencyLabel(code) });
    });

    if (statementData) {
      statementData.transactions.forEach((tx) => {
        const code = String(tx.currencyCode || '').trim().toUpperCase();
        if (!code || values.has(code)) return;
        values.set(code, { code, label: getCurrencyLabel(code) });
      });
      statementData.currencyBalances.forEach((row) => {
        const code = String(row.currencyCode || '').trim().toUpperCase();
        if (!code || values.has(code)) return;
        values.set(code, { code, label: getCurrencyLabel(code) });
      });
    }

    return [
      { code: ALL_CURRENCIES_FILTER, label: t.allCurrenciesOption ?? 'كل العملات' },
      ...Array.from(values.values()).sort((a, b) => a.code.localeCompare(b.code)),
    ];
  }, [currencies, statementData]);

  const formatStatementAmount = (amount: number, currencyCode: string) => {
    const sym = getSymbol(currencyCode);
    if (!Number.isFinite(amount)) return `0.00 ${sym}`;
    return formatCurrency(amount, sym);
  };

  const formatStatementDate = (date: Date) => {
    if (!(date instanceof Date) || Number.isNaN(date.getTime())) {
      return t.invalidDate ?? '—';
    }
    return format(date, 'PPP', { locale: locale === 'ar' ? ar : undefined });
  };

  const getVoucherTypeLabel = (row: StatementTransaction) => {
    if (row.type === 'invoice') {
      return t.salesInvoice ?? 'فاتورة مبيعات';
    }
    if (row.type === 'order') {
      const isShipmentDoc = String((row.details as any)?.documentType || '') === 'shipment';
      return isShipmentDoc ? (t.shipmentDocLabel ?? 'ارسالية') : (t.purchaseInvoice ?? 'فاتورة مشتريات');
    }
    if (row.type === 'payment') {
      return row.flow === 'credit' ? (t.receiptVoucher ?? 'سند قبض') : (t.paymentVoucher ?? 'سند دفع');
    }
    if (row.type === 'return') {
      return t.purchaseReturn ?? 'مرتجع مشتريات';
    }
    return t.voucherType ?? 'نوع السند';
  };

  const toggleRow = (id: string) => {
    const newExpanded = new Set(expandedRows);
    if (newExpanded.has(id)) {
      newExpanded.delete(id);
    } else {
      newExpanded.add(id);
    }
    setExpandedRows(newExpanded);
  };

  const handleShare = () => {
    if (!statementData || !selectedParty) return;

    const header = `${t.accountStatementTitle ?? 'Account Statement'} - ${selectedParty.name}\n`;
    const date = `${t.date ?? 'Date'}: ${format(new Date(), 'yyyy-MM-dd')}\n\n`;
    const separator = '═══════════════════════════════════════\n';

    const sectionDetails = statementData.sections
      .map((section) => {
        const openingRow = `${getCurrencyLabel(section.currencyCode)}\n${t.openingBalance ?? 'Opening Balance'}: ${formatStatementAmount(section.openingBalance, section.currencyCode)}\n${separator}`;
        const transactionDetails = section.transactions
          .map((row) => {
            let detail = `\n${format(row.date, 'yyyy-MM-dd')} | ${row.description}\n`;
            detail += `${t.debit ?? 'Debit'}: ${formatStatementAmount(row.debit, row.currencyCode)} | ${t.credit ?? 'Credit'}: ${formatStatementAmount(row.credit, row.currencyCode)} | ${t.balance ?? 'Balance'}: ${formatStatementAmount(row.balance, row.currencyCode)}\n`;

            if ((row.type === 'invoice' || row.type === 'order') && row.details && row.details.items) {
              detail += `  ${t.items ?? 'Items'}:\n`;
              const rowSym = getSymbol(row.currencyCode);
              row.details.items.forEach((item: any) => {
                detail += `    - ${item.name}: ${item.quantity} × ${formatCurrency(item.unitPrice, rowSym)} = ${formatCurrency(item.total, rowSym)}\n`;
              });
              detail += `  ${t.subTotal ?? 'Subtotal'}: ${formatCurrency(row.details.subTotal, rowSym)}\n`;
              if (row.details.discountAmount && row.details.discountAmount > 0) {
                detail += `  ${t.discount ?? 'Discount'}: -${formatCurrency(row.details.discountAmount, rowSym)}\n`;
              }
              detail += `  ${t.grandTotal ?? 'Grand Total'}: ${formatCurrency(row.details.grandTotal, rowSym)}\n`;
              detail += `  ${t.amountPaid ?? 'Amount Paid'}: ${formatCurrency(row.details.amountPaid, rowSym)}\n`;
              detail += `  ${t.amountDue ?? 'Amount Due'}: ${formatCurrency(row.details.amountDue, rowSym)}\n`;
            }

            return detail;
          })
          .join('\n');

        return `${openingRow}${transactionDetails}\n${separator}${t.finalBalance ?? 'Final Balance'}: ${formatStatementAmount(section.finalBalance, section.currencyCode)}\n`;
      })
      .join(`\n${separator}`);

    const fullText = header + date + separator + sectionDetails;
    const encodedText = encodeURIComponent(fullText);
    window.open(`https://wa.me/?text=${encodedText}`);
  };

  const handlePrint = (includeDetails: boolean) => {
    if (!statementData || !selectedParty) return;

    const safeToFixed = (value: unknown, digits: number = 2) => {
      const numeric = Number(value ?? 0);
      const safe = Number.isFinite(numeric) ? numeric : 0;
      return safe.toFixed(digits);
    };

    const printWindow = window.open('', '', 'height=600,width=900');
    if (!printWindow) return;

    const printHeaderLeftText = String(printingSettings?.printHeaderLeftText || '').trim();
    const printHeaderCenterText = String(printingSettings?.printHeaderCenterText || '').trim();
    const printHeaderRightText = String(printingSettings?.printHeaderRightText || '').trim();
    const printHeaderText = String(printingSettings?.printHeaderText || '').trim();
    const printFooterText = String(printingSettings?.printFooterText || '').trim();
    const toPrintMultilineHtml = (value: string) => value
      .split(/\r?\n/)
      .map((line) => line.trim())
      .filter(Boolean)
      .map((line) => line
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#39;'))
      .join('<br/>');

    const hasSplitHeader = Boolean(printHeaderLeftText || printHeaderCenterText || printHeaderRightText);
    const headerHtml = hasSplitHeader
      ? `<div class="custom-print-header-grid"><div class="custom-print-header-cell">${toPrintMultilineHtml(printHeaderRightText)}</div><div class="custom-print-header-cell center">${toPrintMultilineHtml(printHeaderCenterText)}</div><div class="custom-print-header-cell left">${toPrintMultilineHtml(printHeaderLeftText)}</div></div>`
      : (printHeaderText ? `<div class="custom-print-header">${toPrintMultilineHtml(printHeaderText)}</div>` : '');
    const footerHtml = printFooterText
      ? `<div class="custom-print-footer">${toPrintMultilineHtml(printFooterText)}</div>`
      : '';

    const htmlContent = `
        <html dir="rtl">
        <head>
            <title>${t.accountStatementTitle ?? 'Account Statement'}</title>
            <style>
                * { margin: 0; padding: 0; box-sizing: border-box; }
          body { font-family: Arial, sans-serif; padding: 16px; direction: rtl; color: #111827; }
          .header { text-align: center; margin-bottom: 18px; border-bottom: 2px solid #e5e7eb; padding-bottom: 12px; }
          .header h1 { font-size: 22px; margin-bottom: 8px; }
          .header p { color: #4b5563; margin: 4px 0; font-size: 13px; }
          .filters { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; margin: 12px 0; }
          .filter-box { background: #f9fafb; border: 1px solid #e5e7eb; border-radius: 8px; padding: 8px; font-size: 12px; }
                table { width: 100%; border-collapse: collapse; margin: 20px 0; }
          th, td { padding: 8px; border: 1px solid #e5e7eb; text-align: right; font-size: 12px; }
          th { background-color: #f3f4f6; font-weight: bold; }
                .debit { color: #d32f2f; }
                .credit { color: #388e3c; }
          .summary { margin: 12px 0; }
                .summary-row { display: flex; justify-content: space-between; padding: 8px 0; border-bottom: 1px solid #ddd; }
          .summary-row.total { font-weight: bold; font-size: 14px; }
          .summary-inline { display: flex; flex-wrap: nowrap; align-items: center; gap: 12px; white-space: nowrap; font-size: 11px; }
          .summary-inline-item { display: inline-flex; align-items: center; gap: 6px; }
          .summary-inline-item.total { font-weight: 700; }
                .details-table { margin-left: 20px; font-size: 12px; }
          .currency-summary { margin-top: 12px; margin-bottom: 12px; }
          .currency-summary h3 { font-size: 14px; margin-bottom: 6px; }
          .currency-chip { display: inline-block; margin: 0 0 6px 6px; padding: 6px 8px; border: 1px solid #d1d5db; border-radius: 999px; font-size: 11px; }
          .doc-type-chip { display: inline-block; border: 1px solid #d1d5db; background: #f9fafb; border-radius: 999px; padding: 2px 8px; font-size: 10px; font-weight: 600; margin-left: 6px; }
          .custom-print-header { text-align: center; border: 1px solid #e5e7eb; background: #f8fafc; border-radius: 8px; padding: 8px; margin-bottom: 10px; font-size: 12px; line-height: 1.6; font-weight: 600; }
          .custom-print-header-grid { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px; border: 1px solid #e5e7eb; background: #f8fafc; border-radius: 8px; padding: 8px; margin-bottom: 10px; }
          .custom-print-header-cell { min-height: 34px; padding: 6px; border: 1px solid #e5e7eb; border-radius: 6px; background: #ffffff; font-size: 11px; line-height: 1.5; text-align: right; white-space: pre-wrap; }
          .custom-print-header-cell.center { text-align: center; }
          .custom-print-header-cell.left { text-align: left; }
          .custom-print-footer { text-align: center; border-top: 1px dashed #d1d5db; margin-top: 14px; padding-top: 8px; font-size: 11px; color: #374151; line-height: 1.5; }
          @media print {
            body { margin: 0; padding: 8px; }
            .summary-inline { font-size: 10px; gap: 8px; }
            .summary-inline-item { gap: 4px; }
          }
            </style>
        </head>
        <body>
            ${headerHtml}
            <div class="header">
                <h1>${t.accountStatementTitle ?? 'Account Statement'}</h1>
                <p><strong>${t.partyName ?? 'Party Name'}:</strong> ${selectedParty.name}</p>
                <p><strong>${t.date ?? 'Date'}:</strong> ${format(new Date(), 'PPP')}</p>
            </div>

        <div class="filters">
          <div class="filter-box"><strong>${t.fromDateLabel ?? 'من تاريخ'}:</strong> ${dateFrom || '-'}</div>
          <div class="filter-box"><strong>${t.toDateLabel ?? 'إلى تاريخ'}:</strong> ${dateTo || '-'}</div>
          <div class="filter-box"><strong>${t.currencyFilterLabel ?? 'العملة'}:</strong> ${currencyFilter === ALL_CURRENCIES_FILTER ? (t.allCurrenciesOption ?? 'كل العملات') : getCurrencyLabel(currencyFilter)}</div>
          <div class="filter-box"><strong>${t.finalBalance ?? 'Final Balance'}:</strong> ${statementData.isAllCurrenciesView ? (t.multiCurrencySeparatedHint ?? 'معروض بشكل منفصل لكل عملة') : formatStatementAmount(statementData.finalBalance, statementData.displayCurrencyCode)}</div>
        </div>

        <div class="currency-summary">
          <h3>${t.currencyBalancesLabel ?? 'الرصيد حسب العملة'}</h3>
          ${statementData.currencyBalances.map((row) => `<span class="currency-chip">${row.currencyCode}: ${safeToFixed(row.net)}</span>`).join('')}
        </div>

            <table>
                <thead>
                    <tr>
                        <th>${t.date ?? 'Date'}</th>
              <th>${t.currencyFilterLabel ?? 'العملة'}</th>
                        <th>${t.statementDescriptionCol ?? 'Description'}</th>
                        <th>${t.debit ?? 'Debit'}</th>
                        <th>${t.credit ?? 'Credit'}</th>
                        <th>${t.balance ?? 'Balance'}</th>
                    </tr>
                </thead>
                <tbody>
                    ${statementData.sections
                      .map((section) => `
                        <tr style="background-color: #eef2ff; font-weight: bold;">
                          <td colspan="6">${getCurrencyLabel(section.currencyCode)}</td>
                        </tr>
                        <tr style="background-color: #f9f9f9;">
                          <td colspan="5"><strong>${t.openingBalance ?? 'Opening Balance'}</strong></td>
                          <td><strong>${formatStatementAmount(section.openingBalance, section.currencyCode)}</strong></td>
                        </tr>
                        ${section.transactions
                      .map((row) => {
                        let rowHtml = `
                        <tr>
                            <td>${format(row.date, 'yyyy-MM-dd')}</td>
                          <td>${row.currencyCode}</td>
                            <td><span class="doc-type-chip">${getVoucherTypeLabel(row)}</span>${row.description}</td>
                          <td class="debit">${row.debit > 0 ? formatStatementAmount(row.debit, row.currencyCode) : '-'}</td>
                          <td class="credit">${row.credit > 0 ? formatStatementAmount(row.credit, row.currencyCode) : '-'}</td>
                          <td><strong>${formatStatementAmount(row.balance, row.currencyCode)}</strong></td>
                        </tr>`;

                        if (includeDetails && (row.type === 'invoice' || row.type === 'order') && row.details && row.details.items) {
                          const printSym = getSymbol(row.currencyCode);
                          rowHtml += `
                          <tr style="background-color: #f5f5f5;">
                              <td colspan="6">
                                  <table class="details-table" style="width: 100%;">
                                      <thead>
                                          <tr>
                                              <th>${t.item ?? 'Item'}</th>
                                              <th>${t.quantity ?? 'Qty'}</th>
                                              <th>${t.price ?? 'Price'}</th>
                                              ${row.type === 'invoice' ? `<th>${t.bonus ?? 'Bonus'}</th>` : ''}
                                              <th>${t.total ?? 'Total'}</th>
                                          </tr>
                                      </thead>
                                      <tbody>
                                          ${row.details.items
                                            .map((item: any) => `
                                            <tr>
                                                <td>${item.name}</td>
                                                <td>${item.quantity}</td>
                                              <td>${printSym}${safeToFixed(item.unitPrice)}</td>
                                                ${row.type === 'invoice' ? `<td>${item.bonus || 0}</td>` : ''}
                                              <td>${printSym}${safeToFixed(item.total)}</td>
                                            </tr>`)
                                            .join('')}
                                      </tbody>
                                  </table>
                                    <div style="margin-top: 10px; overflow-x: auto;">
                                      <div class="summary-inline">
                                        <div class="summary-inline-item"><span>${t.subTotal ?? 'Subtotal'}:</span> <span>${printSym}${safeToFixed(row.details.subTotal)}</span></div>
                                        ${row.details.discountAmount && Number(row.details.discountAmount) > 0 ? `<div class="summary-inline-item" style="color: #388e3c;"><span>${t.discount ?? 'Discount'}:</span> <span>-${printSym}${safeToFixed(row.details.discountAmount)}</span></div>` : ''}
                                        <div class="summary-inline-item total"><span>${t.grandTotal ?? 'Grand Total'}:</span> <span>${printSym}${safeToFixed(row.details.grandTotal)}</span></div>
                                        <div class="summary-inline-item"><span>${t.amountPaid ?? 'Amount Paid'}:</span> <span>${printSym}${safeToFixed(row.details.amountPaid)}</span></div>
                                        <div class="summary-inline-item total"><span>${t.amountDue ?? 'Amount Due'}:</span> <span style="color: ${Number(row.details.amountDue || 0) > 0 ? '#d32f2f' : '#388e3c'};">${printSym}${safeToFixed(row.details.amountDue)}</span></div>
                                      </div>
                                    </div>
                              </td>
                          </tr>`;
                        }

                        return rowHtml;
                      })
                      .join('')}
                        <tr style="background-color: #f0f0f0; font-weight: bold; font-size: 14px;">
                          <td colspan="5">${t.finalBalance ?? 'Final Balance'}</td>
                          <td>${formatStatementAmount(section.finalBalance, section.currencyCode)}</td>
                        </tr>`)
                      .join('')}
                </tbody>
            </table>

            ${footerHtml}

            <script>
                window.print();
                window.close();
            </script>
        </body>
        </html>`;

    printWindow.document.write(htmlContent);
    printWindow.document.close();
  };

  return (
    <Card>
      <CardHeader>
        <CardTitle>{t.accountStatementTitle ?? 'Account Statement'}</CardTitle>
        <CardDescription>{t.accountStatementDescription ?? 'Select a customer or supplier to view the statement.'}</CardDescription>
      </CardHeader>
      <CardContent className="space-y-6">
        <Popover open={popoverOpen} onOpenChange={setPopoverOpen}>
          <PopoverTrigger asChild>
            <Button
              variant="outline"
              role="combobox"
              aria-expanded={popoverOpen}
              className="w-full justify-between md:w-1/2"
            >
              {selectedPartyId
                ? formatPartyLabel(parties.find((p) => p.id === selectedPartyId))
                : (t.selectParty ?? 'Select a customer or supplier...')}
              <ChevronsUpDown className="ms-2 h-4 w-4 shrink-0 opacity-50" />
            </Button>
          </PopoverTrigger>
          <PopoverContent className="w-[--radix-popover-trigger-width] p-0">
            <div className="p-2">
              <Input
                placeholder={t.searchParty ?? 'Search...'}
                value={searchTerm}
                onChange={(e) => setSearchTerm(e.target.value)}
                autoFocus
              />
            </div>
            <div className="max-h-60 overflow-y-auto">
              {filteredParties.length === 0 ? (
                <div className="p-2 text-center text-sm text-muted-foreground">
                  {t.noPartiesFound ?? 'No results found.'}
                </div>
              ) : (
                filteredParties.map((party) => (
                  <div
                    key={party.id}
                    onClick={() => {
                      setSelectedPartyId(party.id);
                      setPopoverOpen(false);
                      setSearchTerm('');
                    }}
                    className={cn(
                      'relative flex cursor-pointer select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[selected=true]:bg-accent hover:bg-accent',
                    )}
                    data-selected={party.id === selectedPartyId}
                  >
                    <Check
                      className={cn(
                        'me-2 h-4 w-4',
                        selectedPartyId === party.id ? 'opacity-100' : 'opacity-0'
                      )}
                    />
                    <span className="truncate">
                      {formatPartyLabel(party)}
                    </span>
                  </div>
                ))
              )}
            </div>
          </PopoverContent>
        </Popover>

        {selectedParty && (
          <div>
            {statementData ? (
              <>
                <div className="grid grid-cols-1 gap-3 md:grid-cols-4">
                  <div>
                    <div className="mb-1 text-xs text-muted-foreground">{t.fromDateLabel ?? 'من تاريخ'}</div>
                    <Input type="date" value={dateFrom} onChange={(e) => setDateFrom(e.target.value)} />
                  </div>
                  <div>
                    <div className="mb-1 text-xs text-muted-foreground">{t.toDateLabel ?? 'إلى تاريخ'}</div>
                    <Input type="date" value={dateTo} onChange={(e) => setDateTo(e.target.value)} />
                  </div>
                  <div>
                    <div className="mb-1 text-xs text-muted-foreground">{t.currencyFilterLabel ?? 'العملة'}</div>
                    <select
                      value={currencyFilter}
                      onChange={(e) => setCurrencyFilter(e.target.value)}
                      className="h-10 w-full rounded-md border bg-background px-3 text-sm"
                    >
                      {currencyOptions.map((currency) => (
                        <option key={currency.code} value={currency.code}>{currency.label}</option>
                      ))}
                    </select>
                  </div>
                  <div className="flex items-end">
                    <Button
                      type="button"
                      variant="outline"
                      className="w-full"
                      onClick={() => {
                        setDateFrom('');
                        setDateTo('');
                        setCurrencyFilter(ALL_CURRENCIES_FILTER);
                      }}
                    >
                      {t.resetFilters ?? 'إعادة ضبط الفلاتر'}
                    </Button>
                  </div>
                </div>

                <div className="rounded-md border bg-muted/20 p-3">
                  <div className="mb-2 text-sm font-semibold">{t.currencyBalancesLabel ?? 'الرصيد حسب العملة'}</div>
                  <div className="grid grid-cols-1 gap-2 md:grid-cols-3">
                    {statementData.currencyBalances.length === 0 ? (
                      <div className="text-sm text-muted-foreground">{t.noTransactions ?? 'No transactions found.'}</div>
                    ) : (
                      statementData.currencyBalances.map((row) => (
                        <div key={row.currencyCode} className="rounded-md border bg-background p-2 text-sm">
                          <div className="font-semibold">{row.currencyCode}</div>
                          <div className="text-muted-foreground">{t.debit ?? 'Debit'}: {formatStatementAmount(row.debit, row.currencyCode)}</div>
                          <div className="text-muted-foreground">{t.credit ?? 'Credit'}: {formatStatementAmount(row.credit, row.currencyCode)}</div>
                          <div className="font-medium">{t.finalBalance ?? 'Final Balance'}: {formatStatementAmount(row.net, row.currencyCode)}</div>
                        </div>
                      ))
                    )}
                  </div>
                </div>

                <div className="overflow-x-auto">
                  <Table>
                    <TableHeader>
                      <TableRow>
                        <TableHead className="w-8"></TableHead>
                        <TableHead className="text-start">{t.date ?? 'Date'}</TableHead>
                        <TableHead className="text-start">{t.currencyFilterLabel ?? 'العملة'}</TableHead>
                        <TableHead className="text-start">{t.statementDescriptionCol ?? 'Description'}</TableHead>
                        <TableHead className="text-end">{t.debit ?? 'Debit'}</TableHead>
                        <TableHead className="text-end">{t.credit ?? 'Credit'}</TableHead>
                        <TableHead className="text-end">{t.balance ?? 'Balance'}</TableHead>
                      </TableRow>
                    </TableHeader>
                    <TableBody>
                      {statementData.sections.length === 0 ? (
                        <TableRow>
                          <TableCell colSpan={7} className="text-center h-24 text-muted-foreground">
                            {t.noTransactions ?? 'No transactions found.'}
                          </TableCell>
                        </TableRow>
                      ) : (
                        statementData.sections.map((section) => (
                          <React.Fragment key={section.currencyCode}>
                            <TableRow className="bg-muted/40">
                              <TableCell></TableCell>
                              <TableCell colSpan={6} className="font-bold text-start">
                                {getCurrencyLabel(section.currencyCode)}
                              </TableCell>
                            </TableRow>
                            <TableRow>
                              <TableCell></TableCell>
                              <TableCell colSpan={4} className="font-bold text-start">
                                {t.openingBalance ?? 'Opening Balance'}
                              </TableCell>
                              <TableCell className="text-end font-bold">
                                {formatStatementAmount(section.openingBalance, section.currencyCode)}
                              </TableCell>
                            </TableRow>
                            {section.transactions.map((row) => (
                              <React.Fragment key={row.id}>
                                <TableRow className="hover:bg-muted/50 cursor-pointer" onClick={() => toggleRow(row.id)}>
                                  <TableCell className="text-center">
                                    {(row.type === 'invoice' || row.type === 'order') && (
                                      expandedRows.has(row.id) ? <ChevronUp className="h-4 w-4" /> : <ChevronDown className="h-4 w-4" />
                                    )}
                                  </TableCell>
                                  <TableCell className="text-start">{formatStatementDate(row.date)}</TableCell>
                                  <TableCell className="text-start">
                                    <span className="rounded-full border px-2 py-0.5 text-xs">{row.currencyCode}</span>
                                  </TableCell>
                                  <TableCell className="text-start">
                                    <div className="flex items-center gap-2">
                                      <span className="rounded-full border bg-muted px-2 py-0.5 text-[11px] font-medium text-muted-foreground">
                                        {getVoucherTypeLabel(row)}
                                      </span>
                                      <span>{row.description}</span>
                                    </div>
                                  </TableCell>
                                  <TableCell className="text-end text-red-600">
                                    {row.debit > 0 ? formatStatementAmount(row.debit, row.currencyCode) : '-'}
                                  </TableCell>
                                  <TableCell className="text-end text-green-600">
                                    {row.credit > 0 ? formatStatementAmount(row.credit, row.currencyCode) : '-'}
                                  </TableCell>
                                  <TableCell className="text-end font-medium">
                                    {formatStatementAmount(row.balance, row.currencyCode)}
                                  </TableCell>
                                </TableRow>
                                {expandedRows.has(row.id) && (row.type === 'invoice' || row.type === 'order') && row.details && (
                                  <TableRow className="bg-muted/30">
                                    <TableCell colSpan={7}>
                                      <div className="p-4 space-y-4">
                                        {row.details.items && row.details.items.length > 0 && (
                                          <div>
                                            <h4 className="font-semibold mb-2 text-sm">{t.items ?? 'Items'}</h4>
                                            <Table className="text-xs">
                                              <TableHeader>
                                                <TableRow>
                                                  <TableHead>{t.item ?? 'Item'}</TableHead>
                                                  <TableHead className="text-center">{t.quantity ?? 'Qty'}</TableHead>
                                                  <TableHead className="text-end">{t.price ?? 'Price'}</TableHead>
                                                  {row.type === 'invoice' && <TableHead className="text-center">{t.bonus ?? 'Bonus'}</TableHead>}
                                                  <TableHead className="text-end">{t.total ?? 'Total'}</TableHead>
                                                </TableRow>
                                              </TableHeader>
                                              <TableBody>
                                                {row.details.items.map((item: any, idx: number) => (
                                                  <TableRow key={idx}>
                                                    <TableCell>{item.name}</TableCell>
                                                    <TableCell className="text-center">{item.quantity}</TableCell>
                                                    <TableCell className="text-end">{formatCurrency(item.unitPrice, getSymbol(row.currencyCode))}</TableCell>
                                                    {row.type === 'invoice' && (
                                                      <TableCell className="text-center">{item.bonus || 0}</TableCell>
                                                    )}
                                                    <TableCell className="text-end">{formatCurrency(item.total, getSymbol(row.currencyCode))}</TableCell>
                                                  </TableRow>
                                                ))}
                                              </TableBody>
                                            </Table>
                                          </div>
                                        )}
                                        <div className="border-t pt-2">
                                          <div className="flex flex-wrap items-center gap-3 text-sm">
                                            <div className="flex items-center gap-1.5 whitespace-nowrap">
                                              <span>{t.subTotal ?? 'Subtotal'}:</span>
                                              <span className="font-medium">{formatCurrency(row.details.subTotal, getSymbol(row.currencyCode))}</span>
                                            </div>
                                            {row.details.discountAmount && row.details.discountAmount > 0 && (
                                              <div className="flex items-center gap-1.5 whitespace-nowrap text-green-600">
                                                <span>{t.discount ?? 'Discount'}:</span>
                                                <span className="font-medium">-{formatCurrency(row.details.discountAmount, getSymbol(row.currencyCode))}</span>
                                              </div>
                                            )}
                                            <div className="flex items-center gap-1.5 whitespace-nowrap font-semibold">
                                              <span>{t.grandTotal ?? 'Grand Total'}:</span>
                                              <span>{formatCurrency(row.details.grandTotal, getSymbol(row.currencyCode))}</span>
                                            </div>
                                            <div className="flex items-center gap-1.5 whitespace-nowrap">
                                              <span>{t.amountPaid ?? 'Amount Paid'}:</span>
                                              <span className="font-medium">{formatCurrency(row.details.amountPaid, getSymbol(row.currencyCode))}</span>
                                            </div>
                                            <div className="flex items-center gap-1.5 whitespace-nowrap font-semibold text-red-600">
                                              <span>{t.amountDue ?? 'Amount Due'}:</span>
                                              <span>{formatCurrency(row.details.amountDue, getSymbol(row.currencyCode))}</span>
                                            </div>
                                          </div>
                                        </div>
                                      </div>
                                    </TableCell>
                                  </TableRow>
                                )}
                              </React.Fragment>
                            ))}
                            <TableRow className="bg-muted/50">
                              <TableCell></TableCell>
                              <TableCell colSpan={4} className="text-end font-extrabold text-lg">
                                {t.finalBalance ?? 'Final Balance'}
                              </TableCell>
                              <TableCell className="text-end font-extrabold text-lg">
                                {formatStatementAmount(section.finalBalance, section.currencyCode)}
                              </TableCell>
                            </TableRow>
                          </React.Fragment>
                        ))
                      )}
                    </TableBody>
                  </Table>
                </div>
              </>
            ) : (
              <div className="text-center text-muted-foreground py-8">
                {t.noTransactions ?? 'No transactions found for this period.'}
              </div>
            )}
            <div className="flex justify-end gap-2 mt-4">
              <DropdownMenu>
                <DropdownMenuTrigger asChild>
                  <Button variant="outline" disabled={!statementData}>
                    <Printer className="me-2 h-4 w-4" />
                    {t.print ?? 'Print'}
                  </Button>
                </DropdownMenuTrigger>
                <DropdownMenuContent align="end">
                  <DropdownMenuItem onClick={() => handlePrint(true)}>
                    {t.printDetailedStatement ?? 'طباعة كشف مفصل'}
                  </DropdownMenuItem>
                  <DropdownMenuItem onClick={() => handlePrint(false)}>
                    {t.printStatementWithoutDetails ?? 'طباعة كشف بدون تفاصيل'}
                  </DropdownMenuItem>
                </DropdownMenuContent>
              </DropdownMenu>
              <Button onClick={handleShare} disabled={!statementData}>
                <Share2 className="me-2 h-4 w-4" />
                {t.shareOnWhatsApp ?? 'Share on WhatsApp'}
              </Button>
            </div>
          </div>
        )}
      </CardContent>
    </Card>
  );
}
