'use server';

import * as fs from 'fs';
import * as path from 'path';
import { addMonths, format, getDaysInMonth, parseISO } from 'date-fns';
import { revalidatePath } from 'next/cache';
import { cookies } from 'next/headers';
import { redirect } from 'next/navigation';
import { z } from 'zod';
import { createSession, destroySession, getSession } from './auth';
import { hasEmployeePermission } from './employee-permissions';
import { isPostgresProviderEnabled } from './config';
import { createDefaultPurchaseSideEffectsPort } from './modules/purchases/infrastructure/default-purchase-side-effects.port';
// eslint-disable-next-line @typescript-eslint/no-require-imports
const {
    getInternalTransferDocumentById,
    confirmInternalTransferReceipt,
    addInternalTransferDocument,
    resolveInternalTransferShortage,
    addInventoryMovements,
    reconcilePurchaseOrderInventory,
    generateJournalForInventoryAdjustment,
    getEmployees,
    writeData,
    recordAttendance,
    addEmployee: addEmployeeData,
    updateEmployee,
    getEmployeeById,
    updatePassword: updatePasswordData,
    getSetting,
    updateSetting,
    deleteEmployee: deleteEmployeeData,
    dbUpdateFinancialRecord,
    addLeaveRequest,
    updateLeaveRequestStatus,
    getEmployeeByUsername,
    recordCheckOut,
    dbSwapShifts,
    updateShiftSwapStatus,
    deleteFinancialRecord,
    getShiftForEmployee,
    getShiftOverrides,
    dbEditAdvanceSchedule,
    addProductionReport,
    getCustomers,
    addMaterial,
    updateMaterial,
    deleteMaterial,
    addExpense,
    getExpenses,
    updateExpense,
    deleteExpense,
    addProductShapeDefinition,
    updateProductShapeDefinition,
    deleteProductShapeDefinition,
    getProductShapeDefinitions,
    addProductShapeDefinitions,
    addCustomer,
    updateCustomer,
    deleteCustomer,
    updateCustomerPricing,
    addInvoice,
    getMaterials,
    getCustomerPricing,
    updateCustomerBalance,
    addPayment,
    getSettings,
    addCustomerCategory,
    getCustomerCategories,
    deleteCustomerCategory,
    createCustomerPaymentJournalEntry,
    createSupplierPaymentJournalEntry,
    getInvoices,
    updateInvoice,
    lockInvoice,
    unlockInvoice,
    cancelInvoice,
    getJournalEntries,
    getSuppliers,
    addSupplier,
    updateSupplier,
    updateSupplierBalance,
    addSupplierPayment,
    acquireSupplierPaymentLock,
    releaseSupplierPaymentLock,
    getSupplierPaymentLockByBeneficiary,
    getSupplierPaymentLocks,
    getIncomingChecks,
    endorseIncomingCheck,
    updateSupplierPaymentMetadata,
    updateSupplierPaymentFull,
    cancelSupplierPayment,
    deleteSupplier,
    addPurchaseOrder,
    getInvoicesPurchase,
    updatePurchaseOrder,
    lockPurchaseOrder,
    unlockPurchaseOrder,
    cancelPurchaseOrder,
    receivePurchaseOrder,
    getPurchaseOrderById,
    addJournalEntry,
    getInternalTransferDocuments,
    getSupplierPayments,
    getInventoryMovements,
    addPurchaseReturn,
    updatePurchaseReturn,
    getPurchaseReturns,
    getPurchaseReturnsByOrder,
    getPurchaseReturnById,
    createShipment,
    getAvailableStock,
    getBankById,
    getDefaultCurrency,
    getCurrencies,
    getDailyExchangeRates,
    getExchangeRate,
    convertCurrency,
    addItemGroup,
    updateItemGroup,
    deleteItemGroup,
    addSalesRep,
    getSalesReps,
    updateSalesRep,
    deleteSalesRep,
    addWarehouse,
    updateWarehouseData,
    deleteWarehouseData,
    getWarehouses,
    addShelvesToWarehouse,
    addShelfToWarehouse,
    updateShelfInWarehouse,
    deleteShelfFromWarehouse,
    getInternalTransfers,
    updateInternalTransfer,
    deleteInternalTransfer,
    acquireTransferLock,
    releaseTransferLock,
    updateInternalTransferDocument,
    cancelInternalTransferDocument,
    getItemUnits,
    addManagedUnit,
    getManagedUnits,
    updateManagedUnit,
    deleteManagedUnit,
    ensureManagedUnit,
    nextNamedSequence,
    getAvailableItemUnitsByItemId,
    upsertItemUnitsBulk,
    updateItemUnitsStatusByIds,
    getCoupons,
    getCampaigns,
    addCoupon,
    addCampaign,
    updateCampaign,
    deleteCampaign,
    updateCouponStatus,
    redeemCouponsBatch,
    applyCouponFxDifference,
    getStockLocationsByMaterial,
    assertNotLockedByPeriod,
    assertReverseQuantity,
    nextPrefixedId,
    getShipments,
    getPosShiftSessions,
    savePosShiftSessions,
} = require('./data') as typeof import('./data');
import type {
    Employee,
    FinancialRecord,
    Installment,
    LeaveRequest,
    ProductionReport,
    CustomerPricing,
    SalesInvoice,
    SalesInvoiceItem,
    JournalEntry,
    JournalEntryLine,
    Supplier,
    PurchaseOrder,
    PurchaseOrderDocument,
    Shipment,
    ShipmentType,
    InventoryMovement,
    SupplierPayment,
    PurchaseReturnItem,
    PurchaseOrderLogEntry,
    CustomerCategory,
    DisassemblyRecord,
    RealEstateProject,
    RealEstateUnit,
    RealEstateInstallment,
    Campaign,
} from './types';
import { SHIFT_TIMES } from './config';
import { getSalesInvoiceService } from './modules/sales';
import { getIpAddress } from './ip';
import { enqueueBackgroundJob, getBackgroundJobs, processNextBackgroundJob } from './background-jobs';
import { getChartOfAccountsWithSeedMerge } from './accounting/chart-of-accounts-runtime';
import { mapPurchaseCreateDtoToCommand } from './modules/purchases/application/create-purchase-order.mapper';
import { PurchaseApplicationService } from './modules/purchases/application/purchase-application-service';
import { getPgPool } from './postgres/client';
import {
    pgAddIncomingCheck,
    pgAddPayment,
    pgAddIssuedCheck,
    pgAddSupplierPayment,
    pgAcquireSupplierPaymentLock,
    pgCreateCustomer,
    pgCreateExpense,
    pgCreateItemGroup,
    pgCreateManagedUnit,
    pgCreateMaterial,
    pgCreateProductShapeDefinition,
    pgCreateSalesRep,
    pgGetSalesReps,
    pgCreateSupplier,
    pgCreateWarehouse,
    pgGetCustomers,
    pgDeleteWarehouse,
    pgGetCurrencies,
    pgGetDefaultCurrency,
    pgGetEmployees,
    pgGetExpenses,
    pgGetInvoices,
    pgGetItemUnits,
    pgGetJournalEntries,
    pgGetPurchaseOrders,
    pgGetPurchaseReturns,
    pgGetChecksReceived,
    pgGetDailyExchangeRates,
    pgGetSettings,
    pgGetSuppliers,
    pgGetInternalTransfers,
    pgDeleteCustomer,
    pgDeleteExpense,
    pgDeleteItemGroup,
    pgDeleteManagedUnit,
    pgDeleteMaterial,
    pgDeleteProductShapeDefinition,
    pgDeleteSalesRep,
    pgDeleteSupplier,
    pgEndorseIncomingCheck,
        pgGetSupplierPaymentLockByBeneficiary,
        pgGetSupplierPaymentLocks,
    pgGetBankById,
    pgGetGeneralBankById,
    pgGetCustomerCategories,
    pgCreateCustomerCategory,
    pgDeleteCustomerCategory,
    pgGetCustomerPricing,
    pgGetItemGroups,
    pgGetMaterialById,
    pgGetMaterials,
    pgGetManagedUnits,
    pgGetProductShapeDefinitions,
    pgGetWarehouses,
    pgReleaseSupplierPaymentLock,
    pgSaveCurrencies,
    pgSaveCustomers,
    pgSaveEmployees,
    pgSaveInvoices,
    pgSaveJournalEntries,
    pgSaveSettings,
    pgSaveChartOfAccounts,
    pgSaveCustomerCategories,
    pgSaveSuppliers,
    pgSaveJournalEntry,
    pgSaveInternalTransfers,
    pgSaveInventoryMovements,
    pgUpdateSupplierBalance,
    pgSetCustomerPricing,
    pgUpdateCustomer,
    pgUpdateCustomerBalance,
    pgUpdateExpense,
    pgUpdateItemGroup,
    pgUpdateManagedUnit,
    pgUpdateMaterial,
    pgUpdateProductShapeDefinition,
    pgUpdateSalesRep,
    pgUpdateSupplier,
    pgUpdateWarehouse,
    pgGetShipments,
    pgSaveShipments,
    pgGetShipmentSequences,
    pgSaveShipmentSequences,
    pgNextNamedSequence,
    pgGetInventoryMovements,
    pgGetCoupons,
    pgGetCampaigns,
    pgCreateCampaign,
    pgUpdateCampaign,
    pgDeleteCampaign,
    pgCreateCoupon,
    pgUpdateCouponStatus,
    pgApplyCouponFxDifference,
    pgRedeemCouponsBatch,
} from './postgres/data-access';
import { pgQuery } from './postgres/client';

async function getChartOfAccountsRuntime() {
    return getChartOfAccountsWithSeedMerge();
}

async function saveChartOfAccountsRuntime(accounts: any[]) {
    if (isPostgresProviderEnabled()) {
        await pgSaveChartOfAccounts(accounts);
        return;
    }

    writeData('chart_of_accounts.json', accounts);
}

async function getCurrenciesRuntime() {
    if (isPostgresProviderEnabled()) {
        const { items } = await pgGetCurrencies({ page: 1, pageSize: 10000 });
        return items as any[];
    }

    return getCurrencies() as any[];
}

async function getDefaultCurrencyRuntime() {
    if (isPostgresProviderEnabled()) {
        return await pgGetDefaultCurrency();
    }

    return getDefaultCurrency();
}

async function getMaterialsRuntime() {
    if (isPostgresProviderEnabled()) {
        const { items } = await pgGetMaterials({ page: 1, pageSize: 10000 });
        return items as any[];
    }

    return getMaterials() as any[];
}

async function getExpensesRuntime() {
    if (isPostgresProviderEnabled()) {
        const { items } = await pgGetExpenses({ page: 1, pageSize: 10000 });
        return items as any[];
    }

    return getExpenses() as any[];
}

async function saveCurrenciesRuntime(currencies: any[]) {
    if (isPostgresProviderEnabled()) {
        await pgSaveCurrencies(currencies);
        return;
    }

    writeData('currencies.json', currencies);
}

async function getJournalEntriesRuntime() {
    if (isPostgresProviderEnabled()) {
        const { items } = await pgGetJournalEntries({ page: 1, pageSize: 10000 });
        return items as any[];
    }

    return getJournalEntries() as any[];
}

async function saveJournalEntriesRuntime(entries: any[]) {
    if (isPostgresProviderEnabled()) {
        await pgSaveJournalEntries(entries);
        return;
    }

    writeData('journal_entries.json', entries);
}

async function getCustomersRuntime() {
    if (isPostgresProviderEnabled()) {
        const { items } = await pgGetCustomers({ page: 1, pageSize: 10000 });
        return items as any[];
    }

    return getCustomers() as any[];
}

async function saveCustomersRuntime(customers: any[]) {
    if (isPostgresProviderEnabled()) {
        await pgSaveCustomers(customers);
        return;
    }

    writeData('customers.json', customers);
}

async function getSuppliersRuntime() {
    if (isPostgresProviderEnabled()) {
        const { items } = await pgGetSuppliers({ page: 1, pageSize: 10000 });
        return items as any[];
    }

    return getSuppliers() as any[];
}

async function getCouponsRuntime() {
    if (isPostgresProviderEnabled()) {
        return await pgGetCoupons();
    }
    return getCoupons();
}

async function getCampaignsRuntime() {
    if (isPostgresProviderEnabled()) {
        return await pgGetCampaigns();
    }
    return getCampaigns();
}

async function getActiveCampaignsRuntime(atIso?: string) {
    const allCampaigns = await getCampaignsRuntime();
    const now = new Date(atIso || new Date().toISOString()).getTime();
    return (allCampaigns || [])
        .filter((campaign: any) => {
            if (String(campaign?.status || 'inactive') !== 'active') return false;
            const start = new Date(String(campaign?.startDate || '')).getTime();
            const end = new Date(String(campaign?.endDate || '')).getTime();
            if (!Number.isNaN(start) && now < start) return false;
            if (!Number.isNaN(end) && now > end) return false;
            return true;
        })
        .sort((a: any, b: any) => Number(b?.priority || 0) - Number(a?.priority || 0));
}

async function createCampaignRuntime(payload: {
    name: string;
    type?: 'multi_buy' | 'mix_match' | 'buy_x_get_y' | 'tier_pricing' | 'fixed_bundle';
    startDate: string;
    endDate: string;
    status?: 'active' | 'scheduled' | 'expired' | 'inactive';
    description?: string;
    branchIds?: string[];
    customerTags?: string[];
    autoApplyInPos?: boolean;
    allowRepeats?: boolean;
    allowStacking?: boolean;
    priority?: number;
    maxApplicationsPerInvoice?: number;
    items: Array<{
        productId?: string;
        categoryId?: string;
        minQty: number;
        bundlePrice: number;
        regularUnitPrice?: number;
        maxApplications?: number;
    }>;
    createdBy?: string;
}) {
    if (isPostgresProviderEnabled()) {
        return await pgCreateCampaign(payload);
    }
    return addCampaign(payload);
}

async function updateCampaignRuntime(campaignId: string, updates: Partial<Omit<Campaign, 'id' | 'createdAt' | 'createdBy'>>) {
    if (isPostgresProviderEnabled()) {
        return await pgUpdateCampaign(campaignId, updates);
    }
    return updateCampaign(campaignId, updates);
}

async function deleteCampaignRuntime(campaignId: string) {
    if (isPostgresProviderEnabled()) {
        return await pgDeleteCampaign(campaignId);
    }
    return deleteCampaign(campaignId);
}

async function createCouponRuntime(payload: {
    title: string;
    amount: number;
    couponCode?: string;
    currencyCode?: string;
    baseCurrencyCode?: string;
    exchangeRate?: number;
    rateDate?: string;
    originalAmountBase?: number;
    remainingAmountBase?: number;
    customerType?: 'cash' | 'customer';
    customerId?: string;
    customerName?: string;
    customerAccountCode?: string;
    paymentMethod?: 'cash' | 'check' | 'credit';
    settlementAccountCode?: string;
    settlementAccountName?: string;
    liabilityAccountCode?: string;
    liabilityAccountName?: string;
    expiryDate?: string;
    notes?: string;
    createdBy?: string;
}) {
    if (isPostgresProviderEnabled()) {
        return await pgCreateCoupon(payload);
    }
    return addCoupon(payload);
}

async function getDailyExchangeRatesRuntime() {
    if (isPostgresProviderEnabled()) {
        const result = await pgGetDailyExchangeRates({ page: 1, pageSize: 10000 });
        return (result.items || []) as Array<Record<string, any>>;
    }

    return getDailyExchangeRates() as Array<Record<string, any>>;
}

function normalizeRateDay(value?: string): string {
    if (!value) return format(new Date(), 'yyyy-MM-dd');
    const parsed = new Date(value);
    if (Number.isNaN(parsed.getTime())) return format(new Date(), 'yyyy-MM-dd');
    return format(parsed, 'yyyy-MM-dd');
}

async function resolveCouponExchangeRate(params: { currencyCode: string; baseCurrencyCode: string; rateDate: string; }): Promise<number> {
    const currencyCode = String(params.currencyCode || '').trim().toUpperCase();
    const baseCurrencyCode = String(params.baseCurrencyCode || '').trim().toUpperCase();
    if (!currencyCode || !baseCurrencyCode || currencyCode === baseCurrencyCode) return 1;

    const targetDay = normalizeRateDay(params.rateDate);
    const dailyRates = await getDailyExchangeRatesRuntime();
    const historical = (dailyRates || []).find((entry) => {
        const base = String(entry?.baseCurrency || '').trim().toUpperCase();
        const currency = String(entry?.currency || '').trim().toUpperCase();
        const day = normalizeRateDay(String(entry?.date || ''));
        return base === baseCurrencyCode && currency === currencyCode && day === targetDay;
    });

    const historicalRate = Number(historical?.rate || 0);
    if (Number.isFinite(historicalRate) && historicalRate > 0) {
        return historicalRate;
    }

    const liveRate = Number(getExchangeRate(currencyCode, baseCurrencyCode) || 0);
    if (Number.isFinite(liveRate) && liveRate > 0) {
        return liveRate;
    }

    return 1;
}

async function addIncomingCheckRuntime(payload: {
    checkNumber: string;
    bankId: string;
    bankName: string;
    checkDate: string;
    amount: number;
    currency: string;
    convertedAmount?: number;
    exchangeRate?: number;
    customerId: string;
    customerName: string;
    reference?: string;
    status: 'pending' | 'cleared' | 'rejected' | 'returned';
    notes?: string;
    createdBy: string;
}) {
    if (isPostgresProviderEnabled()) {
        const pgPayload: Parameters<typeof pgAddIncomingCheck>[0] = {
            checkNumber: payload.checkNumber,
            bankId: payload.bankId,
            bankName: payload.bankName,
            checkDate: payload.checkDate,
            amount: payload.amount,
            currency: payload.currency,
            convertedAmount: Number(payload.convertedAmount ?? payload.amount ?? 0),
            exchangeRate: Number(payload.exchangeRate ?? 1),
            customerId: payload.customerId,
            customerName: payload.customerName,
            reference: String(payload.reference ?? ''),
            status: payload.status,
            notes: String(payload.notes ?? ''),
            createdBy: payload.createdBy,
        };
        return await pgAddIncomingCheck(pgPayload);
    }

    const { addIncomingCheck } = await import('./data');
    return addIncomingCheck(payload);
}

async function updateCouponStatusRuntime(couponId: string, status: 'active' | 'used' | 'expired' | 'cancelled', notes?: string) {
    if (isPostgresProviderEnabled()) {
        return await pgUpdateCouponStatus(couponId, status, notes);
    }
    return updateCouponStatus(couponId, status, notes);
}

async function redeemCouponsRuntime(payload: {
    lines: Array<{ couponCode: string; amount: number }>;
    referenceId?: string;
    redeemedBy?: string;
}): Promise<{ success: boolean; error?: string; applied?: Array<{ couponId: string; couponCode: string; amount: number; amountBase?: number }> }> {
    if (isPostgresProviderEnabled()) {
        return await pgRedeemCouponsBatch(payload);
    }
    return redeemCouponsBatch(payload);
}

async function applyCouponFxDifferenceRuntime(couponId: string, deltaBase: number, referenceId?: string) {
    if (isPostgresProviderEnabled()) {
        return await pgApplyCouponFxDifference(couponId, deltaBase, referenceId);
    }
    return applyCouponFxDifference(couponId, deltaBase, referenceId);
}

async function getPurchaseOrdersRuntime() {
    if (isPostgresProviderEnabled()) {
        const { items } = await pgGetPurchaseOrders({ page: 1, pageSize: 10000 });
        return items as any[];
    }

    return getInvoicesPurchase() as any[];
}

async function getInvoicesRuntime() {
    if (isPostgresProviderEnabled()) {
        const { items } = await pgGetInvoices({ page: 1, pageSize: 10000 });
        return items as any[];
    }

    return getInvoices() as any[];
}

async function getPurchaseReturnsRuntime() {
    if (isPostgresProviderEnabled()) {
        const { items } = await pgGetPurchaseReturns({ page: 1, pageSize: 10000 });
        return items as any[];
    }

    return getPurchaseReturns() as any[];
}

async function getInternalTransfersRuntime() {
    if (isPostgresProviderEnabled()) {
        const { items } = await pgGetInternalTransfers({ page: 1, pageSize: 10000 });
        return items as any[];
    }

    return getInternalTransfers() as any[];
}

async function getInternalTransferDocumentByIdRuntime(id: string) {
    const normalizedId = String(id || '').trim();
    if (!normalizedId) return undefined;

    if (isPostgresProviderEnabled()) {
        const docs = await getInternalTransfersRuntime();
        return docs.find((doc: any) => String(doc?.id || '').trim() === normalizedId);
    }

    return getInternalTransferDocumentById(normalizedId);
}

function ensureInternalTransferLegacyMirror(doc: any) {
    if (!isPostgresProviderEnabled()) return;
    const normalizedId = String(doc?.id || '').trim();
    if (!normalizedId) return;

    const legacyDocs = getInternalTransferDocuments() || [];
    const nextDocs = legacyDocs.map((entry: any) => {
        const entryId = String(entry?.id || '').trim();
        return entryId === normalizedId ? doc : entry;
    });
    const hasMatch = legacyDocs.some((entry: any) => String(entry?.id || '').trim() === normalizedId);
    if (!hasMatch) {
        nextDocs.push(doc);
    }

    writeData('internal_transfer_docs.json', nextDocs);
}

async function getItemUnitsRuntime() {
    if (isPostgresProviderEnabled()) {
        const { items } = await pgGetItemUnits({ page: 1, pageSize: 10000 });
        return items as any[];
    }

    return getItemUnits() as any[];
}

async function getIncomingChecksRuntime() {
    if (isPostgresProviderEnabled()) {
        const { items } = await pgGetChecksReceived({ page: 1, pageSize: 5000 });
        return items as any[];
    }

    return getIncomingChecks() as any[];
}

/**
 * Reserve checks for a PO (when creating/updating in any state)
 * Marks checks as reserved so they don't appear in other PO pickers
 */
async function reserveChecksForPurchaseOrder(
    purchaseOrderId: string,
    purchaseOrderNumber: string,
    incomingCheckIds: string[],
    supplierId?: string,
    supplierName?: string,
    createdBy?: string
) {
    if (!Array.isArray(incomingCheckIds) || incomingCheckIds.length === 0) return;

    const allChecks = await getIncomingChecksRuntime();
    const checksToUpdate = allChecks
        .filter((c: any) => incomingCheckIds.includes(c.id))
        .map((c: any) => ({
            ...c,
            reservationStatus: 'reserved' as const,
            reservedAt: new Date().toISOString(),
            reservedByPurchaseOrderId: purchaseOrderId,
            updatedAt: new Date().toISOString(),
        }));

    if (checksToUpdate.length > 0) {
        if (isPostgresProviderEnabled()) {
            const { pgSaveChecksReceived } = await import('./postgres/data-access');
            await pgSaveChecksReceived(checksToUpdate);
        } else {
            const { saveIncomingChecks } = await import('./data');
            saveIncomingChecks(checksToUpdate);
        }
    }
}

/**
 * Release reserved checks (when cancelling draft, changing selection, or deleting PO)
 * Returns checks to available state if they were reserved by this PO
 */
async function releaseReservedChecks(purchaseOrderId: string) {
    const allChecks = await getIncomingChecksRuntime();
    const checksToRelease = allChecks
        .filter((c: any) => c.reservedByPurchaseOrderId === purchaseOrderId && c.reservationStatus === 'reserved')
        .map((c: any) => ({
            ...c,
            reservationStatus: 'available' as const,
            reservedAt: undefined,
            reservedByPurchaseOrderId: undefined,
            updatedAt: new Date().toISOString(),
        }));

    if (checksToRelease.length > 0) {
        if (isPostgresProviderEnabled()) {
            const { pgSaveChecksReceived } = await import('./postgres/data-access');
            await pgSaveChecksReceived(checksToRelease);
        } else {
            const { saveIncomingChecks } = await import('./data');
            saveIncomingChecks(checksToRelease);
        }
    }
}

/**
 * Endorse reserved checks (when posting/approving PO)
 * Converts reserved → endorsed state to record permanent financial commitment
 */
async function endorseReservedChecks(
    purchaseOrderId: string,
    purchaseOrderNumber: string,
    supplierId: string,
    supplierName: string,
    createdBy?: string
) {
    const allChecks = await getIncomingChecksRuntime();
    const checksToEndorse = allChecks
        .filter((c: any) => c.reservedByPurchaseOrderId === purchaseOrderId && c.reservationStatus === 'reserved')
        .map((c: any) => ({
            ...c,
            reservationStatus: 'endorsed' as const,
            endorsementStatus: 'endorsed-to-party' as const,
            endorsedToId: supplierId,
            endorsedToName: supplierName,
            endorsedToType: 'supplier' as const,
            endorsedAt: new Date().toISOString(),
            endorsementReference: purchaseOrderNumber,
            endorsementType: 'payment',
            updatedAt: new Date().toISOString(),
        }));

    if (checksToEndorse.length > 0) {
        if (isPostgresProviderEnabled()) {
            const { pgSaveChecksReceived } = await import('./postgres/data-access');
            await pgSaveChecksReceived(checksToEndorse);
        } else {
            const { saveIncomingChecks } = await import('./data');
            saveIncomingChecks(checksToEndorse);
        }
    }
}

/**
 * Validate that selected incoming checks can be used in this PO
 * Prevents using: endorsed checks, checks reserved by other POs, returned/rejected checks
 */
async function validateIncomingCheckSelection(
    purchaseOrderId: string,
    incomingCheckIds: string[]
): Promise<{ valid: true } | { valid: false; error: string }> {
    if (!Array.isArray(incomingCheckIds) || incomingCheckIds.length === 0) {
        return { valid: true };
    }

    const allChecks = await getIncomingChecksRuntime();
    const selectedChecks = allChecks.filter((c: any) => incomingCheckIds.includes(c.id));

    for (const check of selectedChecks) {
        // Prevent using already-endorsed checks
        if (check.reservationStatus === 'endorsed') {
            return {
                valid: false,
                error: `الشيك ${check.checkNumber} مجيّر مسبقاً للمورد ${check.endorsedToName} ولا يمكن استخدامه.`,
            };
        }

        // Prevent using checks reserved by OTHER POs
        if (
            check.reservationStatus === 'reserved' &&
            check.reservedByPurchaseOrderId &&
            check.reservedByPurchaseOrderId !== purchaseOrderId
        ) {
            return {
                valid: false,
                error: `الشيك ${check.checkNumber} محجوز في فاتورة أخرى.`,
            };
        }

        // Prevent returned checks
        if (check.status === 'returned') {
            return {
                valid: false,
                error: `الشيك ${check.checkNumber} مرتجع ولا يمكن استخدامه.`,
            };
        }

        // Prevent rejected checks
        if (check.status === 'rejected') {
            return {
                valid: false,
                error: `الشيك ${check.checkNumber} مرفوض ولا يمكن استخدامه.`,
            };
        }
    }

    return { valid: true };
}

async function saveSuppliersRuntime(suppliers: any[]) {
    if (isPostgresProviderEnabled()) {
        await pgSaveSuppliers(suppliers);
        return;
    }

    writeData('suppliers.json', suppliers);
}

async function getEmployeesRuntime() {
    if (isPostgresProviderEnabled()) {
        const { items } = await pgGetEmployees({ page: 1, pageSize: 10000 });
        return items as any[];
    }

    return getEmployees() as any[];
}

async function saveEmployeesRuntime(employees: any[]) {
    if (isPostgresProviderEnabled()) {
        await pgSaveEmployees(employees);
        return;
    }

    writeData('employees.json', employees);
}

async function getEmployeeByIdRuntime(employeeId: string): Promise<Employee | undefined> {
    if (isPostgresProviderEnabled()) {
        const employees = (await getEmployeesRuntime()) as Employee[];
        return employees.find((employee) => employee.id === employeeId && !(employee as any)._deleted);
    }

    return getEmployeeById(employeeId) as Employee | undefined;
}

async function updatePasswordRuntime(employeeId: string, newPassword: string): Promise<boolean> {
    if (!isPostgresProviderEnabled()) {
        return updatePasswordData(employeeId, newPassword);
    }

    const employees = (await getEmployeesRuntime()) as Employee[];
    const employee = employees.find((entry) => entry.id === employeeId && !(entry as any)._deleted);
    if (!employee) return false;

    employee.password = newPassword;
    await saveEmployeesRuntime([employee]);
    return true;
}

async function recordAttendanceRuntime(employeeId: string, checkInTime: string): Promise<boolean> {
    if (!isPostgresProviderEnabled()) {
        return recordAttendance(employeeId, checkInTime);
    }

    const employees = (await getEmployeesRuntime()) as Employee[];
    const employee = employees.find((entry) => entry.id === employeeId && !(entry as any)._deleted);
    if (!employee) return false;

    const dateString = new Date(checkInTime).toISOString().split('T')[0];
    const alreadyCheckedIn = (employee.attendance || []).some((attendance) => attendance.date === dateString);
    if (alreadyCheckedIn) return false;

    employee.attendance = employee.attendance || [];
    employee.attendance.push({
        date: dateString,
        checkIn: checkInTime,
        checkOut: null,
    });

    await saveEmployeesRuntime([employee]);
    return true;
}

async function recordCheckOutRuntime(employeeId: string, checkOutTime: string): Promise<boolean> {
    if (!isPostgresProviderEnabled()) {
        return recordCheckOut(employeeId, checkOutTime);
    }

    const employees = (await getEmployeesRuntime()) as Employee[];
    const employee = employees.find((entry) => entry.id === employeeId && !(entry as any)._deleted);
    if (!employee) return false;

    const dateString = new Date(checkOutTime).toISOString().split('T')[0];
    const attendanceRecord = (employee.attendance || []).find((attendance) => attendance.date === dateString && attendance.checkOut === null);
    if (!attendanceRecord) return false;

    attendanceRecord.checkOut = checkOutTime;
    await saveEmployeesRuntime([employee]);
    return true;
}

type RuntimeLeaveRequestData =
    | { requestType: 'leave'; dateRange: { from: Date; to: Date }; reason: string }
    | { requestType: 'advance'; from: Date; amount: number; reason: string }
    | { requestType: 'shift-swap'; shiftDate: Date; toEmployeeId: string; reason: string };

async function addLeaveRequestRuntime(employeeId: string, requestData: RuntimeLeaveRequestData): Promise<boolean> {
    if (!isPostgresProviderEnabled()) {
        return addLeaveRequest(employeeId, requestData as any);
    }

    const employees = (await getEmployeesRuntime()) as Employee[];
    const employee = employees.find((entry) => entry.id === employeeId && !(entry as any)._deleted);
    if (!employee) return false;

    const requestId = await nextPrefixedIdRuntime('req');
    let newRequest: any;

    if (requestData.requestType === 'leave') {
        newRequest = {
            id: requestId,
            status: 'pending',
            requestType: 'leave',
            from: requestData.dateRange.from,
            to: requestData.dateRange.to,
            reason: requestData.reason,
        };
    } else if (requestData.requestType === 'advance') {
        newRequest = {
            id: requestId,
            status: 'pending',
            requestType: 'advance',
            from: new Date(),
            amount: requestData.amount,
            reason: requestData.reason,
        };
    } else {
        newRequest = {
            id: requestId,
            status: 'pending',
            requestType: 'shift-swap',
            shiftDate: requestData.shiftDate,
            toEmployeeId: requestData.toEmployeeId,
            reason: requestData.reason,
        };
    }

    employee.leaveRequests = employee.leaveRequests || [];
    employee.leaveRequests.push(newRequest);
    await saveEmployeesRuntime([employee]);
    return true;
}

async function updateLeaveRequestStatusRuntime(employeeId: string, requestId: string, status: 'approved' | 'rejected'): Promise<boolean> {
    if (!isPostgresProviderEnabled()) {
        return updateLeaveRequestStatus(employeeId, requestId, status);
    }

    const employees = (await getEmployeesRuntime()) as Employee[];
    const employee = employees.find((entry) => entry.id === employeeId && !(entry as any)._deleted);
    const request = employee?.leaveRequests?.find((entry) => entry.id === requestId);
    if (!employee || !request) return false;

    request.status = status;
    await saveEmployeesRuntime([employee]);
    return true;
}

async function swapShiftsRuntime(date: Date, employee1Id: string, employee2Id: string): Promise<boolean> {
    if (!isPostgresProviderEnabled()) {
        return dbSwapShifts(date, employee1Id, employee2Id);
    }

    const employees = (await getEmployeesRuntime()) as Employee[];
    const employee1 = employees.find((entry) => entry.id === employee1Id && !(entry as any)._deleted);
    const employee2 = employees.find((entry) => entry.id === employee2Id && !(entry as any)._deleted);
    if (!employee1 || !employee2) return false;

    const shiftOverrides = getShiftOverrides();
    const dateString = format(date, 'yyyy-MM-dd');
    const shift1 = getShiftForEmployee(employee1, date);
    const shift2 = getShiftForEmployee(employee2, date);

    if (!shiftOverrides[dateString]) {
        shiftOverrides[dateString] = {};
    }

    shiftOverrides[dateString][employee1.id] = shift2;
    shiftOverrides[dateString][employee2.id] = shift1;
    writeData('shiftOverrides.json', shiftOverrides);
    return true;
}

async function updateShiftSwapStatusRuntime(requestId: string, approverId: string, status: 'approved' | 'rejected'): Promise<boolean> {
    if (!isPostgresProviderEnabled()) {
        return updateShiftSwapStatus(requestId, approverId, status);
    }

    const employees = (await getEmployeesRuntime()) as Employee[];
    let requester: Employee | undefined;
    let request: any;

    for (const employee of employees) {
        if ((employee as any)._deleted) continue;
        const foundRequest = (employee.leaveRequests || []).find((entry) => entry.id === requestId);
        if (foundRequest) {
            requester = employee;
            request = foundRequest;
            break;
        }
    }

    const coverer = employees.find((employee) => employee.id === approverId && !(employee as any)._deleted);
    if (!requester || !request || !coverer || request.requestType !== 'shift-swap' || request.toEmployeeId !== approverId) {
        return false;
    }

    request.status = status;

    if (status === 'approved' && request.shiftDate) {
        const requestShiftDate = new Date(request.shiftDate);
        if (coverer.status === 'temporary') {
            let dailyRate = 0;
            if (requester.salaryType === 'monthly') {
                dailyRate = requester.salary / getDaysInMonth(requestShiftDate);
            } else {
                dailyRate = requester.salary;
            }
            dailyRate = parseFloat(dailyRate.toFixed(2));

            const deductionRecord: FinancialRecord = {
                id: await nextPrefixedIdRuntime('rec-ded'),
                description: `Covered by ${coverer.name} on ${format(requestShiftDate, 'MMM d')}`,
                totalAmount: dailyRate,
                installments: [{ date: requestShiftDate, amount: dailyRate }],
            };
            requester.financialRecords.push(deductionRecord);

            const bonusRecord: FinancialRecord = {
                id: await nextPrefixedIdRuntime('rec-bon'),
                description: `Covering for ${requester.name} on ${format(requestShiftDate, 'MMM d')}`,
                totalAmount: -dailyRate,
                installments: [{ date: requestShiftDate, amount: -dailyRate }],
            };
            coverer.financialRecords.push(bonusRecord);

            const shiftOverrides = getShiftOverrides();
            const dateString = format(requestShiftDate, 'yyyy-MM-dd');
            if (!shiftOverrides[dateString]) {
                shiftOverrides[dateString] = {};
            }
            const requesterOriginalShift = getShiftForEmployee(requester, requestShiftDate);
            shiftOverrides[dateString][coverer.id] = requesterOriginalShift;
            shiftOverrides[dateString][requester.id] = 'none';
            writeData('shiftOverrides.json', shiftOverrides);
        } else {
            await swapShiftsRuntime(requestShiftDate, requester.id, approverId);
        }
    }

    await saveEmployeesRuntime([requester, coverer]);
    return true;
}

async function updateFinancialRecordRuntime(employeeId: string, data: Omit<FinancialRecord, 'id'>): Promise<boolean> {
    if (!isPostgresProviderEnabled()) {
        return dbUpdateFinancialRecord(employeeId, data);
    }

    const employees = (await getEmployeesRuntime()) as Employee[];
    const employee = employees.find((entry) => entry.id === employeeId && !(entry as any)._deleted);
    if (!employee) return false;

    const recordTypePrefix = data.totalAmount > 0 ? 'rec-ded' : 'rec-bon';
    const newRecord: FinancialRecord = {
        id: await nextPrefixedIdRuntime(recordTypePrefix),
        ...data,
    };

    employee.financialRecords = employee.financialRecords || [];
    employee.financialRecords.push(newRecord);
    await saveEmployeesRuntime([employee]);
    return true;
}

async function deleteFinancialRecordRuntime(employeeId: string, recordId: string): Promise<boolean> {
    if (!isPostgresProviderEnabled()) {
        return deleteFinancialRecord(employeeId, recordId);
    }

    const employees = (await getEmployeesRuntime()) as Employee[];
    const employee = employees.find((entry) => entry.id === employeeId && !(entry as any)._deleted);
    if (!employee) return false;

    const records = employee.financialRecords || [];
    const recordIndex = records.findIndex((record) => record.id === recordId);
    if (recordIndex === -1) return false;

    records.splice(recordIndex, 1);
    employee.financialRecords = records;
    await saveEmployeesRuntime([employee]);
    return true;
}

async function editAdvanceScheduleRuntime(employeeId: string, data: { recordId: string; installments: { month: string; year: string; amount: number }[] }): Promise<boolean> {
    if (!isPostgresProviderEnabled()) {
        return dbEditAdvanceSchedule(employeeId, data);
    }

    const employees = (await getEmployeesRuntime()) as Employee[];
    const employee = employees.find((entry) => entry.id === employeeId && !(entry as any)._deleted);
    if (!employee) return false;

    const record = (employee.financialRecords || []).find((entry) => entry.id === data.recordId);
    if (!record || record.description !== 'Salary Advance Repayment') {
        return false;
    }

    const totalInstallmentAmount = data.installments.reduce((sum, installment) => sum + installment.amount, 0);
    if (Math.abs(record.totalAmount - totalInstallmentAmount) > 0.01) {
        return false;
    }

    record.installments = data.installments.map((installment) => ({
        date: new Date(parseInt(installment.year), parseInt(installment.month)),
        amount: installment.amount,
    }));

    await saveEmployeesRuntime([employee]);
    return true;
}

async function getSettingsRuntime() {
    if (isPostgresProviderEnabled()) {
        return (await pgGetSettings()) as any;
    }

    return getSettings() as any;
}

async function findWarehouseOrShelfUsageRuntime(params: { warehouseId: string; shelfId?: string }): Promise<string | null> {
    const warehouseId = String(params.warehouseId || '').trim();
    const shelfId = String(params.shelfId || '').trim();
    if (!warehouseId) return null;

    const settings = await getSettingsRuntime();
    const settingMatches = [
        ['defaultSalesWarehouseId', warehouseId],
        ['defaultPurchaseWarehouseId', warehouseId],
        ['defaultSalesShelfId', shelfId],
        ['defaultPurchaseShelfId', shelfId],
    ].filter(([key, value]) => value && String(settings?.[key] || '').trim() === value);
    if (settingMatches.length > 0) {
        return shelfId ? 'الرف مستخدم كقيمة افتراضية في الإعدادات.' : 'المستودع مستخدم كقيمة افتراضية في الإعدادات.';
    }

    const [invoices, purchaseOrders, purchaseReturns, transfers, inventoryMovements, itemUnits] = await Promise.all([
        getInvoicesRuntime(),
        getPurchaseOrdersRuntime(),
        getPurchaseReturnsRuntime(),
        getInternalTransfersRuntime(),
        getInventoryMovementsRuntime(),
        getItemUnitsRuntime(),
    ]);

    const warehouseMatches = (entry: any, warehouseKeys: string[], shelfKeys: string[] = []) => {
        const warehouseHit = warehouseKeys.some((key) => String(entry?.[key] || '').trim() === warehouseId);
        if (!warehouseHit) return false;
        if (!shelfId) return true;
        return shelfKeys.some((key) => String(entry?.[key] || '').trim() === shelfId);
    };

    if ((invoices || []).some((invoice: any) => Array.isArray(invoice?.items) && invoice.items.some((item: any) => warehouseMatches(item, ['warehouseId'], ['shelfId'])))) {
        return shelfId ? 'الرف مستخدم في فواتير المبيعات.' : 'المستودع مستخدم في فواتير المبيعات.';
    }

    if ((purchaseOrders || []).some((order: any) => Array.isArray(order?.items) && order.items.some((item: any) => warehouseMatches(item, ['warehouseId'], ['shelfId'])))) {
        return shelfId ? 'الرف مستخدم في أوامر الشراء.' : 'المستودع مستخدم في أوامر الشراء.';
    }

    if ((purchaseReturns || []).some((doc: any) => Array.isArray(doc?.items) && doc.items.some((item: any) => warehouseMatches(item, ['warehouseId'], ['shelfId'])))) {
        return shelfId ? 'الرف مستخدم في مرتجعات الشراء.' : 'المستودع مستخدم في مرتجعات الشراء.';
    }

    if ((transfers || []).some((transfer: any) => warehouseMatches(transfer, ['fromWarehouseId', 'toWarehouseId'], ['fromShelfId', 'toShelfId']))) {
        return shelfId ? 'الرف مستخدم في التحويلات الداخلية.' : 'المستودع مستخدم في التحويلات الداخلية.';
    }

    if ((getInternalTransferDocuments() || []).some((doc: any) => Array.isArray(doc?.items) && doc.items.some((item: any) => warehouseMatches(item, ['fromWarehouseId', 'toWarehouseId'], ['fromShelfId', 'toShelfId', 'overageSourceShelfId'])))) {
        return shelfId ? 'الرف مستخدم في مستندات التحويل الداخلي.' : 'المستودع مستخدم في مستندات التحويل الداخلي.';
    }

    if ((inventoryMovements || []).some((movement: any) => warehouseMatches(movement, ['warehouseId'], ['shelfId']))) {
        return shelfId ? 'الرف مستخدم في حركات المخزون.' : 'المستودع مستخدم في حركات المخزون.';
    }

    if ((itemUnits || []).some((unit: any) => warehouseMatches(unit, ['warehouseId'], ['shelfId']))) {
        return shelfId ? 'الرف مرتبط بوحدات أصناف.' : 'المستودع مرتبط بوحدات أصناف.';
    }

    return null;
}

async function saveSettingsRuntime(settings: Record<string, unknown>) {
    if (isPostgresProviderEnabled()) {
        await pgSaveSettings(settings);
        return;
    }

    writeData('settings.json', settings);
}

function getDisassemblyRecordsFromSettings(settings: Record<string, unknown> | null | undefined): DisassemblyRecord[] {
    return Array.isArray((settings as any)?.disassemblyRecords)
        ? (((settings as any).disassemblyRecords as DisassemblyRecord[])
            .filter((entry) => entry && typeof entry === 'object'))
        : [];
}

async function getDisassemblyRecordsRuntime(): Promise<DisassemblyRecord[]> {
    const settings = await getSettingsRuntime();
    return getDisassemblyRecordsFromSettings(settings);
}

async function saveDisassemblyRecordsRuntime(records: DisassemblyRecord[]) {
    const settings = await getSettingsRuntime();
    await saveSettingsRuntime({
        ...settings,
        disassemblyRecords: records,
    });
}

function getRealEstateProjectsFromSettings(settings: Record<string, unknown> | null | undefined): RealEstateProject[] {
    return Array.isArray((settings as any)?.realEstateProjects)
        ? (((settings as any).realEstateProjects as RealEstateProject[])
            .filter((entry) => entry && typeof entry === 'object'))
        : [];
}

async function getRealEstateProjectsRuntime(): Promise<RealEstateProject[]> {
    const settings = await getSettingsRuntime();
    return getRealEstateProjectsFromSettings(settings);
}

async function saveRealEstateProjectsRuntime(projects: RealEstateProject[]) {
    const settings = await getSettingsRuntime();
    await saveSettingsRuntime({
        ...settings,
        realEstateProjects: projects,
    });
}

// --- Sequences ---
async function nextPrefixedIdRuntime(prefix: string): Promise<string> {
    if (isPostgresProviderEnabled()) {
        const next = await pgNextNamedSequence(prefix);
        return `${prefix}-${next}`;
    }
    return nextPrefixedId(prefix);
}

// --- Shipments ---
async function getShipmentsRuntime(): Promise<any[]> {
    if (isPostgresProviderEnabled()) {
        const { items } = await pgGetShipments({ page: 1, pageSize: 50000 });
        return items as any[];
    }
    return getShipments();
}

async function createShipmentRuntime(
    shipment: Omit<Shipment, 'id' | 'shipmentNumber' | 'sequenceNumber' | 'fiscalYear' | 'status'> & { status?: Shipment['status'] }
): Promise<Shipment> {
    if (isPostgresProviderEnabled()) {
        const { getYear: dfGetYear } = await import('date-fns');
        const fiscalYear = dfGetYear(new Date(shipment.date || Date.now()));
        // Allocate shipment sequence number from postgres
        const { items: seqItems } = await pgGetShipmentSequences({ page: 1, pageSize: 5000 });
        const matchSeq = (seqItems as any[]).find(
            (s: any) => s.shipmentType === shipment.shipmentType && s.fiscalYear === fiscalYear
        );
        const lastNum = matchSeq ? Number(matchSeq.lastNumber || 0) : 0;
        const nextNum = lastNum + 1;
        const prefixMap: Record<string, string> = { internal: 'ITD', adjustment: 'ADJ', reverse: 'REV', inventory_count: 'INV' };
        const prefix = prefixMap[shipment.shipmentType] || 'SHP';
        const shipmentNumber = `${prefix}-${fiscalYear}-${String(nextNum).padStart(6, '0')}`;
        const seqId = matchSeq?.id || await nextPrefixedIdRuntime('SHSEQ');
        await pgSaveShipmentSequences([{ id: seqId, shipmentType: shipment.shipmentType, fiscalYear, lastNumber: nextNum }]);
        // Create shipment
        const id = await nextPrefixedIdRuntime('SHP');
        assertNotLockedByPeriod(shipment.date, shipment.periodCloseDate, shipment.inventoryCloseDate);
        const record: Shipment = {
            ...shipment,
            id,
            shipmentNumber,
            sequenceNumber: nextNum,
            fiscalYear,
            status: shipment.status || 'pending',
        };
        await pgSaveShipments([record]);
        return record;
    }
    return createShipment(shipment);
}

// --- Inventory Movements ---
async function getInventoryMovementsRuntime(): Promise<any[]> {
    if (isPostgresProviderEnabled()) {
        const { items } = await pgGetInventoryMovements({ page: 1, pageSize: 100000 });
        return items as any[];
    }
    return getInventoryMovements();
}

function allocateAvailableAccountCode(accounts: Array<Record<string, any>>, preferredCode: string): string {
    const normalizedPreferredCode = String(preferredCode || '').trim() || `ACC-${Date.now()}`;
    const usedCodes = new Set(accounts.map((account) => String(account.code || '').trim()).filter(Boolean));
    if (!usedCodes.has(normalizedPreferredCode)) {
        return normalizedPreferredCode;
    }

    const numericCode = Number(normalizedPreferredCode);
    if (Number.isFinite(numericCode)) {
        let nextNumber = numericCode + 1;
        while (usedCodes.has(String(nextNumber))) {
            nextNumber += 1;
        }
        return String(nextNumber);
    }

    let suffix = 1;
    let nextCode = `${normalizedPreferredCode}-${suffix}`;
    while (usedCodes.has(nextCode)) {
        suffix += 1;
        nextCode = `${normalizedPreferredCode}-${suffix}`;
    }
    return nextCode;
}

function allocateRealEstateChildCode(accounts: Array<Record<string, any>>, parentCode: string): string {
    const normalizedParentCode = String(parentCode || '').trim() || '1191';
    const usedCodes = new Set(accounts.map((account) => String(account.code || '').trim()).filter(Boolean));
    let sequence = 1;
    let nextCode = `${normalizedParentCode}${String(sequence).padStart(2, '0')}`;
    while (usedCodes.has(nextCode)) {
        sequence += 1;
        nextCode = `${normalizedParentCode}${String(sequence).padStart(2, '0')}`;
    }
    return nextCode;
}

function ensureChartAccountInCollection(
    accounts: Array<Record<string, any>>,
    params: {
        preferredCode: string;
        nameAr: string;
        nameEn: string;
        parentCode: string;
        nature?: 'debit' | 'credit';
        type?: 'account' | 'header';
    },
): { account: Record<string, any>; changed: boolean } {
    const { preferredCode, nameAr, nameEn, parentCode, nature, type = 'account' } = params;
    const normalizedNameAr = String(nameAr || '').trim();
    const normalizedNameEn = String(nameEn || '').trim();

    const byName = accounts.find((account) =>
        String(account.nameAr || '').trim() === normalizedNameAr
        || String(account.nameEn || '').trim().toLowerCase() === normalizedNameEn.toLowerCase(),
    );
    if (byName) {
        return { account: byName, changed: false };
    }

    let parent = accounts.find((account) => String(account.code || '').trim() === String(parentCode || '').trim());
    let changed = false;
    if (!parent) {
        parent = {
            id: parentCode,
            code: parentCode,
            nameAr: parentCode,
            nameEn: parentCode,
            type: 'header',
            parentId: null,
        };
        accounts.push(parent);
        changed = true;
    }

    const resolvedCode = allocateAvailableAccountCode(accounts, preferredCode);
    const newAccount = {
        id: resolvedCode,
        code: resolvedCode,
        nameAr: normalizedNameAr,
        nameEn: normalizedNameEn,
        type,
        parentId: parent.id,
        nature: type === 'account' ? (nature || 'debit') : undefined,
    };
    accounts.push(newAccount);
    return { account: newAccount, changed: true || changed };
}

function allocateChildAccountCode(accounts: Array<Record<string, any>>, parentCode: string): string {
    const normalizedParentCode = String(parentCode || '').trim() || '2111';
    const pattern = new RegExp(`^${normalizedParentCode.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}-([0-9]+)$`);
    let maxSequence = 0;

    accounts.forEach((account) => {
        const code = String(account?.code || '').trim();
        const match = code.match(pattern);
        if (!match) return;
        const sequence = Number.parseInt(match[1], 10);
        if (Number.isFinite(sequence) && sequence > maxSequence) {
            maxSequence = sequence;
        }
    });

    return `${normalizedParentCode}-${String(maxSequence + 1).padStart(3, '0')}`;
}

async function ensureEntitySubAccountCodeRuntime(params: {
    explicitAccountCode?: string;
    reservedParentCodes?: string[];
    entityName: string;
    parentCode: string;
    parentNameAr: string;
    parentNameEn: string;
    parentParentCode: string;
    nature: 'debit' | 'credit';
    sequenceKey: string;
}): Promise<string> {
    const explicitCode = String(params.explicitAccountCode || '').trim();
    const reservedCodes = new Set((params.reservedParentCodes || []).map((entry) => String(entry || '').trim()));
    if (explicitCode && !reservedCodes.has(explicitCode)) {
        return explicitCode;
    }

    const accounts = await getChartOfAccountsRuntime();
    let changed = false;

    let parent = accounts.find((acc: any) => String(acc?.code || '').trim() === params.parentCode);
    if (!parent) {
        parent = {
            id: params.parentCode,
            code: params.parentCode,
            nameAr: params.parentNameAr,
            nameEn: params.parentNameEn,
            type: 'account',
            parentId: params.parentParentCode,
            nature: params.nature,
        };
        accounts.push(parent);
        changed = true;
    }

    const normalizedName = String(params.entityName || '').trim() || params.parentNameAr;
    const existingByName = accounts.find((acc: any) =>
        String(acc?.type || '') === 'account'
        && String(acc?.parentId || '').trim() === String(parent?.id || '').trim()
        && String(acc?.nameAr || '').trim() === normalizedName,
    );
    if (existingByName) {
        if (changed) {
            await saveChartOfAccountsRuntime(accounts);
        }
        return String(existingByName.code || '').trim();
    }

    const usedCodes = new Set(accounts.map((acc: any) => String(acc?.code || '').trim()).filter(Boolean));
    let candidate = '';
    for (let attempt = 0; attempt < 40; attempt += 1) {
        const nextSequence = isPostgresProviderEnabled()
            ? await pgNextNamedSequence(params.sequenceKey)
            : nextNamedSequence(params.sequenceKey);
        const nextCandidate = `${params.parentCode}-${String(nextSequence).padStart(3, '0')}`;
        if (!usedCodes.has(nextCandidate)) {
            candidate = nextCandidate;
            break;
        }
    }
    if (!candidate) {
        candidate = allocateChildAccountCode(accounts, params.parentCode);
    }

    const ensured = ensureChartAccountInCollection(accounts, {
        preferredCode: candidate,
        nameAr: normalizedName,
        nameEn: normalizedName,
        parentCode: params.parentCode,
        nature: params.nature,
    });

    if (changed || ensured.changed) {
        await saveChartOfAccountsRuntime(accounts);
    }

    return String(ensured.account?.code || '').trim() || candidate;
}

async function ensureEmployeeCashboxAccountRuntime(params: {
    employeeId: string;
    employeeName: string;
    employees: Array<Record<string, any>>;
    accounts?: Array<Record<string, any>>;
}): Promise<{ employee: Record<string, any> | null; account: Record<string, any> | null }> {
    const { employeeId, employeeName, employees } = params;
    const accounts = params.accounts || await getChartOfAccountsRuntime();
    const employeeIndex = employees.findIndex((entry) => String(entry?.id || '').trim() === String(employeeId || '').trim());
    const employee = employeeIndex >= 0 ? employees[employeeIndex] : null;
    if (!employee) return { employee: null, account: null };

    const configuredCode = String(employee.employeeCashAccountCode || '').trim();
    const configuredAccount = configuredCode
        ? accounts.find((acc) => String(acc?.code || '').trim() === configuredCode && String(acc?.type || '') === 'account')
        : null;
    if (configuredAccount) {
        return { employee, account: configuredAccount };
    }

    let changed = false;
    let parent = accounts.find((acc) => String(acc?.code || '').trim() === '1111');
    if (!parent) {
        parent = {
            id: '1111',
            code: '1111',
            nameAr: 'صناديق الموظفين',
            nameEn: 'Employee Cashboxes',
            type: 'header',
            parentId: '1100',
        };
        accounts.push(parent);
        changed = true;
    }

    const normalizedName = String(employee.name || employeeName || '').trim() || `موظف ${employeeId}`;
    let cashboxAccount = accounts.find((acc) =>
        String(acc?.parentId || '').trim() === String(parent?.id || '').trim()
        && String(acc?.type || '') === 'account'
        && String(acc?.nameAr || '').trim() === `صندوق ${normalizedName}`,
    );

    if (!cashboxAccount) {
        const nextCode = allocateChildAccountCode(accounts, '1111');
        cashboxAccount = {
            id: nextCode,
            code: nextCode,
            nameAr: `صندوق ${normalizedName}`,
            nameEn: `Cashbox ${normalizedName}`,
            type: 'account',
            parentId: parent.id,
            nature: 'debit',
        };
        accounts.push(cashboxAccount);
        changed = true;
    }

    const nextEmployee = {
        ...employee,
        employeeCashAccountId: String(cashboxAccount.id || ''),
        employeeCashAccountCode: String(cashboxAccount.code || ''),
    };
    employees[employeeIndex] = nextEmployee;

    if (changed) {
        await saveChartOfAccountsRuntime(accounts);
    }
    if (isPostgresProviderEnabled()) {
        await pgSaveEmployees(employees);
    } else {
        writeData('employees.json', employees);
    }

    return { employee: nextEmployee, account: cashboxAccount };
}

async function ensureEmployeeChecksAccountRuntime(params: {
    employeeId: string;
    employeeName: string;
    employees: Array<Record<string, any>>;
    accounts?: Array<Record<string, any>>;
}): Promise<{ employee: Record<string, any> | null; account: Record<string, any> | null }> {
    const { employeeId, employeeName, employees } = params;
    const accounts = params.accounts || await getChartOfAccountsRuntime();
    const employeeIndex = employees.findIndex((entry) => String(entry?.id || '').trim() === String(employeeId || '').trim());
    const employee = employeeIndex >= 0 ? employees[employeeIndex] : null;
    if (!employee) return { employee: null, account: null };

    const configuredCode = String(employee.employeeChecksAccountCode || '').trim();
    const configuredAccount = configuredCode
        ? accounts.find((acc) => String(acc?.code || '').trim() === configuredCode && String(acc?.type || '') === 'account')
        : null;
    if (configuredAccount) {
        return { employee, account: configuredAccount };
    }

    let changed = false;
    let parent = accounts.find((acc) => String(acc?.code || '').trim() === '1141');
    if (!parent) {
        parent = {
            id: '1141',
            code: '1141',
            nameAr: 'شيكات الموظفين',
            nameEn: 'Employee Checks',
            type: 'header',
            parentId: '1140',
        };
        accounts.push(parent);
        changed = true;
    }

    const normalizedName = String(employee.name || employeeName || '').trim() || `موظف ${employeeId}`;
    let checksAccount = accounts.find((acc) =>
        String(acc?.parentId || '').trim() === String(parent?.id || '').trim()
        && String(acc?.type || '') === 'account'
        && String(acc?.nameAr || '').trim() === `شيكات ${normalizedName}`,
    );

    if (!checksAccount) {
        const nextCode = allocateChildAccountCode(accounts, '1141');
        checksAccount = {
            id: nextCode,
            code: nextCode,
            nameAr: `شيكات ${normalizedName}`,
            nameEn: `Checks ${normalizedName}`,
            type: 'account',
            parentId: parent.id,
            nature: 'debit',
        };
        accounts.push(checksAccount);
        changed = true;
    }

    const nextEmployee = {
        ...employee,
        employeeChecksAccountId: String(checksAccount.id || ''),
        employeeChecksAccountCode: String(checksAccount.code || ''),
    };
    employees[employeeIndex] = nextEmployee;

    if (changed) {
        await saveChartOfAccountsRuntime(accounts);
    }
    if (isPostgresProviderEnabled()) {
        await pgSaveEmployees(employees);
    } else {
        writeData('employees.json', employees);
    }

    return { employee: nextEmployee, account: checksAccount };
}

async function ensureSupplierPostingAccountRuntime(params: {
    supplierId: string;
    supplierName: string;
    suppliers: Array<Record<string, any>>;
    accounts: Array<Record<string, any>>;
}): Promise<{ supplier: Record<string, any> | null; account: Record<string, any> | null }> {
    const { supplierId, supplierName, suppliers, accounts } = params;
    const supplierIndex = suppliers.findIndex((entry) => String(entry?.id || '') === String(supplierId || ''));
    const supplier = supplierIndex >= 0 ? suppliers[supplierIndex] : null;
    if (!supplier) {
        return { supplier: null, account: null };
    }

    const configuredCode = String(supplier.accountCode || '').trim();
    const configuredAccount = configuredCode
        ? accounts.find((acc) => String(acc?.code || '').trim() === configuredCode && String(acc?.type || '') === 'account')
        : null;

    if (configuredAccount && configuredCode !== '2110' && configuredCode !== '2111') {
        return { supplier, account: configuredAccount };
    }

    let accountsChanged = false;
    let supplierPayablesParent = accounts.find((acc) => String(acc?.code || '').trim() === '2111');

    if (!supplierPayablesParent) {
        supplierPayablesParent = {
            id: '2111',
            code: '2111',
            nameAr: 'الموردون',
            nameEn: 'Suppliers',
            type: 'account',
            parentId: '2100',
            nature: 'credit',
        };
        accounts.push(supplierPayablesParent);
        accountsChanged = true;
    }

    const normalizedSupplierName = String(supplier.name || supplierName || '').trim();
    let payableAccount = accounts.find((acc) =>
        String(acc?.parentId || '') === String(supplierPayablesParent?.id || '')
        && String(acc?.type || '') === 'account'
        && String(acc?.nameAr || '').trim() === normalizedSupplierName,
    );

    if (!payableAccount) {
        const preferredCode = allocateChildAccountCode(accounts, String(supplierPayablesParent.code || '2111'));
        payableAccount = {
            id: preferredCode,
            code: preferredCode,
            nameAr: normalizedSupplierName || `مورد ${supplierId}`,
            nameEn: normalizedSupplierName || `Supplier ${supplierId}`,
            type: 'account',
            parentId: supplierPayablesParent.id,
            nature: 'credit',
        };
        accounts.push(payableAccount);
        accountsChanged = true;
    }

    const nextSupplier = {
        ...supplier,
        accountId: payableAccount.id,
        accountCode: payableAccount.code,
    };
    suppliers[supplierIndex] = nextSupplier;

    if (accountsChanged) {
        await saveChartOfAccountsRuntime(accounts);
    }
    await saveSuppliersRuntime(suppliers);

    return { supplier: nextSupplier, account: payableAccount };
}

async function ensureCouponAccountingSetup(): Promise<{
    couponLiabilityAccountCode: string;
    couponLiabilityAccountName: string;
    fxGainAccountCode: string;
    fxGainAccountName: string;
    fxLossAccountCode: string;
    fxLossAccountName: string;
}> {
    const accounts = (await getChartOfAccountsRuntime()) as Array<Record<string, any>>;
    let changed = false;

    const currentLiabilities = ensureChartAccountInCollection(accounts, {
        preferredCode: '2100',
        nameAr: 'الخصوم المتداولة',
        nameEn: 'Current Liabilities',
        parentCode: '',
        type: 'header',
    });
    changed = changed || currentLiabilities.changed;

    const deferredRevenue = ensureChartAccountInCollection(accounts, {
        preferredCode: '2130',
        nameAr: 'إيرادات مؤجلة',
        nameEn: 'Deferred Revenue',
        parentCode: String(currentLiabilities.account?.code || '2100'),
        type: 'header',
    });
    changed = changed || deferredRevenue.changed;

    const couponLiability = ensureChartAccountInCollection(accounts, {
        preferredCode: '2135',
        nameAr: 'التزامات الكوبونات المدفوعة مسبقاً',
        nameEn: 'Prepaid Coupon Liability',
        parentCode: String(deferredRevenue.account?.code || '2130'),
        nature: 'credit',
    });
    changed = changed || couponLiability.changed;

    const operatingRevenue = ensureChartAccountInCollection(accounts, {
        preferredCode: '4100',
        nameAr: 'إيرادات التشغيل',
        nameEn: 'Operating Revenue',
        parentCode: '',
        type: 'header',
    });
    changed = changed || operatingRevenue.changed;

    const operatingExpenses = ensureChartAccountInCollection(accounts, {
        preferredCode: '5100',
        nameAr: 'مصاريف التشغيل',
        nameEn: 'Operating Expenses',
        parentCode: '',
        type: 'header',
    });
    changed = changed || operatingExpenses.changed;

    const fxGainAccount = ensureChartAccountInCollection(accounts, {
        preferredCode: '4195',
        nameAr: 'أرباح فروقات العملة - الكوبونات',
        nameEn: 'FX Gain - Coupons',
        parentCode: String(operatingRevenue.account?.code || '4100'),
        nature: 'credit',
    });
    changed = changed || fxGainAccount.changed;

    const fxLossAccount = ensureChartAccountInCollection(accounts, {
        preferredCode: '5195',
        nameAr: 'خسائر فروقات العملة - الكوبونات',
        nameEn: 'FX Loss - Coupons',
        parentCode: String(operatingExpenses.account?.code || '5100'),
        nature: 'debit',
    });
    changed = changed || fxLossAccount.changed;

    if (changed) {
        await saveChartOfAccountsRuntime(accounts);
    }

    return {
        couponLiabilityAccountCode: String(couponLiability.account?.code || '2135'),
        couponLiabilityAccountName: String(
            couponLiability.account?.nameAr
            || couponLiability.account?.nameEn
            || 'التزامات الكوبونات المدفوعة مسبقاً'
        ),
        fxGainAccountCode: String(fxGainAccount.account?.code || '4195'),
        fxGainAccountName: String(fxGainAccount.account?.nameAr || fxGainAccount.account?.nameEn || 'أرباح فروقات العملة - الكوبونات'),
        fxLossAccountCode: String(fxLossAccount.account?.code || '5195'),
        fxLossAccountName: String(fxLossAccount.account?.nameAr || fxLossAccount.account?.nameEn || 'خسائر فروقات العملة - الكوبونات'),
    };
}

async function ensureSalesDiscountAccountingSetup(): Promise<{
    salesDiscountAccountCode: string;
    salesDiscountAccountName: string;
    campaignDiscountAccountCode: string;
    campaignDiscountAccountName: string;
    bonusDiscountAccountCode: string;
    bonusDiscountAccountName: string;
    salesReturnAccountCode: string;
    salesReturnAccountName: string;
}> {
    const accounts = (await getChartOfAccountsRuntime()) as Array<Record<string, any>>;
    let changed = false;

    const operatingRevenue = ensureChartAccountInCollection(accounts, {
        preferredCode: '4100',
        nameAr: 'إيرادات تشغيلية',
        nameEn: 'Operating Revenues',
        parentCode: '4000',
        type: 'header',
    });
    changed = changed || operatingRevenue.changed;

    const salesDiscount = ensureChartAccountInCollection(accounts, {
        preferredCode: '4120',
        nameAr: 'خصم مسموح به',
        nameEn: 'Sales Discounts',
        parentCode: String(operatingRevenue.account?.code || '4100'),
        nature: 'debit',
    });
    changed = changed || salesDiscount.changed;

    const campaignDiscount = ensureChartAccountInCollection(accounts, {
        preferredCode: '4121',
        nameAr: 'خصم حملات تسويقية',
        nameEn: 'Marketing Campaign Discounts',
        parentCode: String(salesDiscount.account?.code || '4120'),
        nature: 'debit',
    });
    changed = changed || campaignDiscount.changed;

    const bonusDiscount = ensureChartAccountInCollection(accounts, {
        preferredCode: '4122',
        nameAr: 'خصم بونص ترويجي',
        nameEn: 'Promotional Bonus Discounts',
        parentCode: String(salesDiscount.account?.code || '4120'),
        nature: 'debit',
    });
    changed = changed || bonusDiscount.changed;

    const salesReturn = ensureChartAccountInCollection(accounts, {
        preferredCode: '4130',
        nameAr: 'مردودات مبيعات',
        nameEn: 'Sales Returns',
        parentCode: String(operatingRevenue.account?.code || '4100'),
        nature: 'debit',
    });
    changed = changed || salesReturn.changed;

    if (changed) {
        await saveChartOfAccountsRuntime(accounts);
    }

    return {
        salesDiscountAccountCode: String(salesDiscount.account?.code || '4120'),
        salesDiscountAccountName: String(salesDiscount.account?.nameAr || salesDiscount.account?.nameEn || 'خصم مسموح به'),
        campaignDiscountAccountCode: String(campaignDiscount.account?.code || '4121'),
        campaignDiscountAccountName: String(campaignDiscount.account?.nameAr || campaignDiscount.account?.nameEn || 'خصم حملات تسويقية'),
        bonusDiscountAccountCode: String(bonusDiscount.account?.code || '4122'),
        bonusDiscountAccountName: String(bonusDiscount.account?.nameAr || bonusDiscount.account?.nameEn || 'خصم بونص ترويجي'),
        salesReturnAccountCode: String(salesReturn.account?.code || '4130'),
        salesReturnAccountName: String(salesReturn.account?.nameAr || salesReturn.account?.nameEn || 'مردودات مبيعات'),
    };
}

async function ensureRealEstateAccountingSetup(project?: { id?: string; name?: string; code?: string }) {
    const accounts = (await getChartOfAccountsRuntime()) as Array<Record<string, any>>;
    let changed = false;

    const projectsRoot = ensureChartAccountInCollection(accounts, {
        preferredCode: '1191',
        nameAr: 'مشاريع عقارية تحت التطوير',
        nameEn: 'Real Estate Projects In Progress',
        parentCode: '1100',
        type: 'header',
    });
    changed = changed || projectsRoot.changed;

    const directCostAccount = ensureChartAccountInCollection(accounts, {
        preferredCode: '1192',
        nameAr: 'تكاليف مباشرة للمشاريع العقارية',
        nameEn: 'Real Estate Direct Costs',
        parentCode: String(projectsRoot.account.code || '1191'),
        nature: 'debit',
    });
    changed = changed || directCostAccount.changed;

    const sharedCostAccount = ensureChartAccountInCollection(accounts, {
        preferredCode: '1193',
        nameAr: 'تكاليف مشتركة للمشاريع العقارية',
        nameEn: 'Real Estate Shared Costs',
        parentCode: String(projectsRoot.account.code || '1191'),
        nature: 'debit',
    });
    changed = changed || sharedCostAccount.changed;

    const salesRevenueAccount = ensureChartAccountInCollection(accounts, {
        preferredCode: '4114',
        nameAr: 'إيرادات بيع الوحدات العقارية',
        nameEn: 'Real Estate Unit Sales Revenue',
        parentCode: '4110',
        nature: 'credit',
    });
    changed = changed || salesRevenueAccount.changed;

    const costOfSalesAccount = ensureChartAccountInCollection(accounts, {
        preferredCode: '5171',
        nameAr: 'تكلفة الوحدات العقارية المباعة',
        nameEn: 'Cost of Real Estate Units Sold',
        parentCode: '5100',
        nature: 'debit',
    });
    changed = changed || costOfSalesAccount.changed;

    let projectAccount: Record<string, any> | undefined;
    const normalizedProjectName = String(project?.name || '').trim();
    const normalizedProjectCode = String(project?.code || project?.id || '').trim();
    if (normalizedProjectName) {
        const projectLabelAr = normalizedProjectCode
            ? `مشروع ${normalizedProjectName} (${normalizedProjectCode})`
            : `مشروع ${normalizedProjectName}`;
        const projectLabelEn = normalizedProjectCode
            ? `Project ${normalizedProjectName} (${normalizedProjectCode})`
            : `Project ${normalizedProjectName}`;
        const projectEntry = ensureChartAccountInCollection(accounts, {
            preferredCode: allocateRealEstateChildCode(accounts, String(projectsRoot.account.code || '1191')),
            nameAr: projectLabelAr,
            nameEn: projectLabelEn,
            parentCode: String(projectsRoot.account.code || '1191'),
            nature: 'debit',
        });
        changed = changed || projectEntry.changed;
        projectAccount = projectEntry.account;
    }

    if (changed) {
        await saveChartOfAccountsRuntime(accounts);
    }

    return {
        projectsRootAccountId: String(projectsRoot.account.id || ''),
        projectsRootAccountCode: String(projectsRoot.account.code || ''),
        directCostAccountId: String(directCostAccount.account.id || ''),
        directCostAccountCode: String(directCostAccount.account.code || ''),
        sharedCostAccountId: String(sharedCostAccount.account.id || ''),
        sharedCostAccountCode: String(sharedCostAccount.account.code || ''),
        salesRevenueAccountId: String(salesRevenueAccount.account.id || ''),
        salesRevenueAccountCode: String(salesRevenueAccount.account.code || ''),
        costOfSalesAccountId: String(costOfSalesAccount.account.id || ''),
        costOfSalesAccountCode: String(costOfSalesAccount.account.code || ''),
        projectAccountId: String(projectAccount?.id || ''),
        projectAccountCode: String(projectAccount?.code || ''),
    };
}

export async function buildSalesInvoiceJournalEntryRecord(params: {
    entryId: string;
    invoiceId: string;
    customerName: string;
    customerAccountCode?: string;
    customerAccountName?: string;
    cashAccountCode?: string;
    cashAccountName?: string;
    grandTotal: number;
    discountAmount: number;
    campaignDiscountAmount?: number;
    bonusAmount: number;
    amountPaid: number;
    createdBy: string;
    isReturn: boolean;
    paymentBreakdown?: Array<{ method: 'cash' | 'visa' | 'receivables' | 'coupon'; amount: number }>;
    couponLiabilityAccountCode?: string;
    couponLiabilityAccountName?: string;
    revenueBreakdown?: Array<{ accountCode: string; accountName?: string; amount: number }>;
    salesDiscountAccountCode?: string;
    salesDiscountAccountName?: string;
    campaignDiscountAccountCode?: string;
    campaignDiscountAccountName?: string;
    bonusDiscountAccountCode?: string;
    bonusDiscountAccountName?: string;
    salesReturnAccountCode?: string;
    salesReturnAccountName?: string;
}) {
    const {
        entryId,
        invoiceId,
        customerName,
        customerAccountCode,
        customerAccountName,
        cashAccountCode,
        cashAccountName,
        grandTotal,
        discountAmount,
        campaignDiscountAmount,
        bonusAmount,
        amountPaid,
        createdBy,
        isReturn,
        paymentBreakdown,
        couponLiabilityAccountCode,
        couponLiabilityAccountName,
        revenueBreakdown,
        salesDiscountAccountCode,
        salesDiscountAccountName,
        campaignDiscountAccountCode,
        campaignDiscountAccountName,
        bonusDiscountAccountCode,
        bonusDiscountAccountName,
        salesReturnAccountCode,
        salesReturnAccountName,
    } = params;

    const lines: JournalEntryLine[] = [];
    const total = Math.abs(grandTotal);
    const discount = Math.min(Math.max(Number(discountAmount || 0), 0), total);
    const campaignDiscount = Math.max(0, Number(campaignDiscountAmount || 0));
    const bonus = Math.min(Math.max(Number(bonusAmount || 0), 0), total + discount);
    const grossTotal = total + discount + campaignDiscount + bonus;
    const paid = Math.abs(amountPaid);
    const customerArCode = String(customerAccountCode || '').trim() || '1150';
    const customerArName = String(customerAccountName || '').trim() || 'العملاء';
    const activeCashCode = String(cashAccountCode || '').trim() || '1110';
    const activeCashName = String(cashAccountName || '').trim() || 'الصندوق';

    if (!isReturn) {
        const hasPaymentBreakdown = Array.isArray(paymentBreakdown) && paymentBreakdown.length > 0;
        if (hasPaymentBreakdown) {
            const cashAmount = paymentBreakdown
                .filter((payment) => payment.method === 'cash')
                .reduce((sum, payment) => sum + Math.max(0, Number(payment.amount || 0)), 0);
            const bankAmount = paymentBreakdown
                .filter((payment) => payment.method === 'visa')
                .reduce((sum, payment) => sum + Math.max(0, Number(payment.amount || 0)), 0);
            const receivablesAmount = paymentBreakdown
                .filter((payment) => payment.method === 'receivables')
                .reduce((sum, payment) => sum + Math.max(0, Number(payment.amount || 0)), 0);
            const couponAmount = paymentBreakdown
                .filter((payment) => payment.method === 'coupon')
                .reduce((sum, payment) => sum + Math.max(0, Number(payment.amount || 0)), 0);

            if (cashAmount > 0) {
                lines.push({
                    accountId: activeCashCode,
                    accountCode: activeCashCode,
                    accountName: activeCashName,
                    debit: cashAmount,
                    credit: 0,
                    description: `تحصيل نقدي من فاتورة ${invoiceId} - ${customerName}`,
                });
            }

            if (bankAmount > 0) {
                lines.push({
                    accountId: '1120',
                    accountCode: '1120',
                    accountName: 'البنك',
                    debit: bankAmount,
                    credit: 0,
                    description: `تحصيل بنكي من فاتورة ${invoiceId} - ${customerName}`,
                });
            }

            if (receivablesAmount > 0) {
                lines.push({
                    accountId: customerArCode,
                    accountCode: customerArCode,
                    accountName: customerArName,
                    debit: receivablesAmount,
                    credit: 0,
                    description: `ذمم فاتورة ${invoiceId} - ${customerName}`,
                });
            }

            if (couponAmount > 0) {
                const couponCode = String(couponLiabilityAccountCode || '').trim() || '2135';
                const couponName = String(couponLiabilityAccountName || '').trim() || 'التزامات الكوبونات المدفوعة مقدماً';
                lines.push({
                    accountId: couponCode,
                    accountCode: couponCode,
                    accountName: couponName,
                    debit: couponAmount,
                    credit: 0,
                    description: `تحصيل بواسطة كوبون من فاتورة ${invoiceId} - ${customerName}`,
                });
            }

            const methodDebitTotal = cashAmount + bankAmount + receivablesAmount + couponAmount;
            if (Math.abs(methodDebitTotal - total) > 0.01) {
                const adjustment = total - methodDebitTotal;
                if (adjustment > 0) {
                    lines.push({
                        accountId: customerArCode,
                        accountCode: customerArCode,
                        accountName: customerArName,
                        debit: adjustment,
                        credit: 0,
                        description: `تسوية ذمم لفاتورة ${invoiceId} - ${customerName}`,
                    });
                }
            }
        } else {
            lines.push({
                accountId: customerArCode,
                accountCode: customerArCode,
                accountName: customerArName,
                debit: total,
                credit: 0,
                description: `فاتورة مبيعات رقم ${invoiceId} - ${customerName}`,
            });
        }

        if (discount > 0) {
            lines.push({
                accountId: String(salesDiscountAccountCode || '4120'),
                accountCode: String(salesDiscountAccountCode || '4120'),
                accountName: String(salesDiscountAccountName || 'خصم مسموح به'),
                debit: discount,
                credit: 0,
                description: `خصم مسموح به لفاتورة ${invoiceId} - ${customerName}`,
            });
        }

        if (campaignDiscount > 0) {
            lines.push({
                accountId: String(campaignDiscountAccountCode || '4121'),
                accountCode: String(campaignDiscountAccountCode || '4121'),
                accountName: String(campaignDiscountAccountName || 'خصم حملات تسويقية'),
                debit: campaignDiscount,
                credit: 0,
                description: `خصم حملة تسويقية لفاتورة ${invoiceId} - ${customerName}`,
            });
        }

        if (bonus > 0) {
            lines.push({
                accountId: String(bonusDiscountAccountCode || '4122'),
                accountCode: String(bonusDiscountAccountCode || '4122'),
                accountName: String(bonusDiscountAccountName || 'خصم بونص ترويجي'),
                debit: bonus,
                credit: 0,
                description: `بونص لفاتورة ${invoiceId} - ${customerName}`,
            });
        }

        const normalizedRevenueBreakdown = (revenueBreakdown || [])
            .map((entry) => ({
                accountCode: String(entry?.accountCode || '').trim(),
                accountName: String(entry?.accountName || '').trim(),
                amount: Number(entry?.amount || 0),
            }))
            .filter((entry) => entry.accountCode && Number.isFinite(entry.amount) && entry.amount > 0.0001);

        if (normalizedRevenueBreakdown.length > 0) {
            normalizedRevenueBreakdown.forEach((entry) => {
                lines.push({
                    accountId: entry.accountCode,
                    accountCode: entry.accountCode,
                    accountName: entry.accountName || `إيرادات (${entry.accountCode})`,
                    debit: 0,
                    credit: entry.amount,
                    description: `فاتورة مبيعات رقم ${invoiceId} - ${customerName}`,
                });
            });
        } else {
            lines.push({
                accountId: '4110',
                accountCode: '4110',
                accountName: 'إيرادات المبيعات',
                debit: 0,
                credit: grossTotal,
                description: `فاتورة مبيعات رقم ${invoiceId} - ${customerName}`,
            });
        }
    } else {
        lines.push({
            accountId: String(salesReturnAccountCode || '4130'),
            accountCode: String(salesReturnAccountCode || '4130'),
            accountName: String(salesReturnAccountName || 'مردودات المبيعات'),
            debit: total,
            credit: 0,
            description: `مردود مبيعات رقم ${invoiceId} - ${customerName}`,
        });

        lines.push({
            accountId: customerArCode,
            accountCode: customerArCode,
            accountName: customerArName,
            debit: 0,
            credit: total,
            description: `مردود مبيعات رقم ${invoiceId} - ${customerName}`,
        });
    }

    if (paid > 0 && (!paymentBreakdown || paymentBreakdown.length === 0)) {
        if (!isReturn) {
            lines.push({
                accountId: activeCashCode,
                accountCode: activeCashCode,
                accountName: activeCashName,
                debit: paid,
                credit: 0,
                description: `تحصيل نقدي من فاتورة ${invoiceId} - ${customerName}`,
            });
            lines.push({
                accountId: customerArCode,
                accountCode: customerArCode,
                accountName: customerArName,
                debit: 0,
                credit: paid,
                description: `تحصيل نقدي من فاتورة ${invoiceId} - ${customerName}`,
            });
        } else {
            lines.push({
                accountId: activeCashCode,
                accountCode: activeCashCode,
                accountName: activeCashName,
                debit: 0,
                credit: paid,
                description: `رد نقدي لمردود ${invoiceId} - ${customerName}`,
            });
            lines.push({
                accountId: customerArCode,
                accountCode: customerArCode,
                accountName: customerArName,
                debit: paid,
                credit: 0,
                description: `رد نقدي لمردود ${invoiceId} - ${customerName}`,
            });
        }
    }

    return {
        id: entryId,
        date: new Date().toISOString(),
        description: isReturn
            ? `قيد مردود مبيعات رقم ${invoiceId} - ${customerName}`
            : `قيد فاتورة مبيعات رقم ${invoiceId} - ${customerName}`,
        referenceType: 'sales_invoice' as const,
        referenceId: invoiceId,
        lines,
        createdBy,
        createdAt: new Date().toISOString(),
    };
}

export async function buildCouponIssuanceJournalEntryRecord(params: {
    entryId: string;
    couponId: string;
    couponNumber: string;
    amount: number;
    amountBase?: number;
    currencyCode?: string;
    baseCurrencyCode?: string;
    exchangeRate?: number;
    rateDate?: string;
    paymentMethod: 'cash' | 'check' | 'credit';
    settlementAccountCode?: string;
    settlementAccountName?: string;
    couponLiabilityAccountCode: string;
    couponLiabilityAccountName: string;
    customerName?: string;
    createdBy: string;
    createdAt?: string;
}): Promise<JournalEntry> {
    const now = String(params.createdAt || '').trim() || new Date().toISOString();
    const isCheck = params.paymentMethod === 'check';
    const isCredit = params.paymentMethod === 'credit';
    const sourceAccountCode = String(params.settlementAccountCode || '').trim() || (isCredit ? '1130' : isCheck ? '1140' : '1110');
    const sourceAccountName = String(params.settlementAccountName || '').trim() || (isCredit ? 'العملاء' : isCheck ? 'أوراق القبض' : 'الصندوق');
    const couponLiabilityCode = String(params.couponLiabilityAccountCode || '').trim() || '2135';
    const couponLiabilityName = String(params.couponLiabilityAccountName || '').trim() || 'التزامات الكوبونات المدفوعة مقدماً';
    const enteredAmount = Math.max(0, Number(params.amount || 0));
    const amount = Math.max(0, Number(params.amountBase || enteredAmount));
    const currencyCode = String(params.currencyCode || '').trim().toUpperCase();
    const baseCurrencyCode = String(params.baseCurrencyCode || '').trim().toUpperCase();
    const exchangeRate = Number(params.exchangeRate || 0);
    const usesFx = Boolean(currencyCode && baseCurrencyCode && currencyCode !== baseCurrencyCode && exchangeRate > 0);
    const fxHint = usesFx ? ` (الأصل ${enteredAmount.toFixed(2)} ${currencyCode} @ ${exchangeRate.toFixed(6)} ${baseCurrencyCode}/${currencyCode})` : '';
    const debitDescription = isCredit
        ? `إثبات كوبون على ذمة العميل ${String(params.customerName || '').trim() || params.couponNumber}${fxHint}`
        : isCheck
            ? `قبض شيكات مقابل كوبون ${params.couponNumber}${fxHint}`
            : `تحصيل نقدي مقابل كوبون ${params.couponNumber}${fxHint}`;

    return {
        id: params.entryId,
        date: now,
        createdAt: now,
        description: `إصدار كوبون مدفوع مسبقاً ${params.couponNumber}${fxHint}`,
        referenceType: 'manual',
        referenceId: params.couponId,
        createdBy: params.createdBy,
        lines: [
            {
                accountId: sourceAccountCode,
                accountCode: sourceAccountCode,
                accountName: sourceAccountName,
                debit: amount,
                credit: 0,
                description: debitDescription,
            },
            {
                accountId: couponLiabilityCode,
                accountCode: couponLiabilityCode,
                accountName: couponLiabilityName,
                debit: 0,
                credit: amount,
                description: `إثبات التزام كوبون ${params.couponNumber}${fxHint}`,
            },
        ],
    };
}

function buildRevenueBreakdownForSalesInvoice(params: {
    items: SalesInvoiceItem[];
    materials: Array<Record<string, any>>;
    accounts: Array<Record<string, any>>;
    grossTotal: number;
}): Array<{ accountCode: string; accountName: string; amount: number }> {
    const { items, materials, accounts, grossTotal } = params;
    const amountByCode = new Map<string, number>();

    items.forEach((line) => {
        const material = materials.find((entry) => String(entry?.id || '') === String(line.materialId || ''));
        const configuredCode = String(material?.revenueAccountCode || '').trim();
        const category = String(material?.itemCategory || '').trim();
        const fallbackCode = category === 'service' ? '4140' : '4110';
        const accountCode = configuredCode || fallbackCode;
        const lineNet = Math.max(0, Math.abs(Number(line.total || 0)));
        const lineBonusValue = Math.max(0, Number(line.bonus || 0) * Math.max(0, Number(line.unitPrice || 0)));
        const lineGross = lineNet + lineBonusValue;
        if (!accountCode || lineGross <= 0) return;
        amountByCode.set(accountCode, (amountByCode.get(accountCode) || 0) + lineGross);
    });

    const accountNameByCode = new Map<string, string>(
        (accounts || [])
            .filter((entry) => String(entry?.type || '').trim() === 'account')
            .map((entry): [string, string] => [
                String(entry?.code || '').trim(),
                String(entry?.nameAr || entry?.nameEn || `حساب ${String(entry?.code || '').trim()}`),
            ])
            .filter(([code]) => !!code)
    );

    let breakdown = Array.from(amountByCode.entries()).map(([accountCode, amount]) => ({
        accountCode,
        accountName: accountNameByCode.get(accountCode) || `إيرادات (${accountCode})`,
        amount,
    }));

    if (breakdown.length === 0 && grossTotal > 0) {
        breakdown = [{
            accountCode: '4110',
            accountName: accountNameByCode.get('4110') || 'إيرادات المبيعات',
            amount: grossTotal,
        }];
    }

    const sum = breakdown.reduce((acc, entry) => acc + entry.amount, 0);
    const delta = grossTotal - sum;
    if (Math.abs(delta) > 0.01 && breakdown.length > 0) {
        let largestIndex = 0;
        for (let i = 1; i < breakdown.length; i += 1) {
            if (breakdown[i].amount > breakdown[largestIndex].amount) largestIndex = i;
        }
        breakdown[largestIndex].amount = Math.max(0, breakdown[largestIndex].amount + delta);
    }

    return breakdown
        .map((entry) => ({ ...entry, amount: Math.round(entry.amount * 100) / 100 }))
        .filter((entry) => entry.amount > 0.0001);
}

function applyMultiBuyCampaigns(params: {
    items: SalesInvoiceItem[];
    activeCampaigns: Array<Record<string, any>>;
    materials: Array<Record<string, any>>;
}) {
    const items = params.items.map((item) => ({ ...item }));
    const logs: string[] = [];
    let totalCampaignDiscount = 0;

    const lineByMaterialId = new Map<string, SalesInvoiceItem>();
    items.forEach((line) => {
        const materialId = String(line.materialId || '').trim();
        if (!materialId) return;
        lineByMaterialId.set(materialId, line);
    });

    params.activeCampaigns.forEach((campaign) => {
        if (String(campaign?.type || 'multi_buy') !== 'multi_buy') return;
        const campaignName = String(campaign?.name || '').trim() || 'حملة';
        const campaignItems = Array.isArray(campaign?.items) ? campaign.items : [];
        const maxPerInvoice = Number(campaign?.maxApplicationsPerInvoice || 0);
        const allowRepeats = campaign?.allowRepeats !== false;
        const allowStacking = campaign?.allowStacking === true;
        let usedPerInvoice = 0;

        campaignItems.forEach((campaignItem: any) => {
            const productId = String(campaignItem?.productId || '').trim();
            if (!productId) return;

            const line = lineByMaterialId.get(productId);
            if (!line) return;

            const qty = Math.max(0, Number(line.quantity || 0));
            const minQty = Math.max(1, Number(campaignItem?.minQty || 0));
            const bundlePrice = Math.max(0, Number(campaignItem?.bundlePrice || 0));
            if (qty < minQty || bundlePrice <= 0) return;

            const maxApplicationsLine = Math.max(0, Number(campaignItem?.maxApplications || 0));
            let bundlesCount = Math.floor(qty / minQty);
            if (maxApplicationsLine > 0) {
                bundlesCount = Math.min(bundlesCount, maxApplicationsLine);
            }
            if (maxPerInvoice > 0) {
                bundlesCount = Math.min(bundlesCount, Math.max(0, maxPerInvoice - usedPerInvoice));
            }
            if (!allowRepeats) {
                bundlesCount = Math.min(1, bundlesCount);
            }
            if (bundlesCount <= 0) return;

            const regularUnitPrice = Number.isFinite(Number(campaignItem?.regularUnitPrice))
                ? Number(campaignItem.regularUnitPrice)
                : Math.max(0, Number(line.unitPrice || 0));
            const regularBundleTotal = regularUnitPrice * minQty;
            const discountPerBundle = Math.max(0, regularBundleTotal - bundlePrice);
            if (discountPerBundle <= 0) return;

            const lineSubtotal = Math.max(0, Number(line.quantity || 0) * Number(line.unitPrice || 0));
            const currentDiscount = Math.max(0, Number(line.discount || 0));
            if (!allowStacking && currentDiscount > 0) return;
            const requestedDiscount = bundlesCount * discountPerBundle;
            const nextDiscount = Math.min(lineSubtotal, currentDiscount + requestedDiscount);
            const actualAppliedDiscount = Math.max(0, nextDiscount - currentDiscount);
            if (actualAppliedDiscount <= 0.0001) return;

            line.discount = nextDiscount;
            totalCampaignDiscount += actualAppliedDiscount;
            usedPerInvoice += bundlesCount;

            const material = params.materials.find((entry) => String(entry?.id || '').trim() === productId);
            const itemName = String(material?.name || line.name || productId).trim();
            logs.push(`✔ تم تطبيق عرض ${campaignName}: ${itemName} (${minQty} مقابل ${bundlePrice.toFixed(2)}) × ${bundlesCount}`);
        });
    });

    return {
        items,
        totalCampaignDiscount,
        logs,
    };
}

// Login Action
const loginSchema = z.object({
  username: z.string(),
  password: z.string(),
  rememberMe: z.boolean().default(false).optional(),
});

async function fetchBasePerCurrencyRate(baseCode: string, currencyCode: string): Promise<{ rate: number; source: string } | null> {
    const base = String(baseCode || '').trim().toUpperCase();
    const target = String(currencyCode || '').trim().toUpperCase();
    if (!base || !target || base === target) return { rate: 1, source: 'local-config' };

    // Stored exchangeRate means: how many units of target currency per 1 unit of base currency.
    // First try direct pair (base -> target). If unavailable, fallback to inverse pair and invert.
    const providers = [
        {
            source: 'https://api.frankfurter.app',
            buildDirectUrl: () => `https://api.frankfurter.app/latest?from=${encodeURIComponent(base)}&to=${encodeURIComponent(target)}`,
            readDirect: (data: any) => Number(data?.rates?.[target]),
            buildInverseUrl: () => `https://api.frankfurter.app/latest?from=${encodeURIComponent(target)}&to=${encodeURIComponent(base)}`,
            readInverse: (data: any) => Number(data?.rates?.[base]),
        },
        {
            source: 'https://open.er-api.com',
            buildDirectUrl: () => `https://open.er-api.com/v6/latest/${encodeURIComponent(base)}`,
            readDirect: (data: any) => Number(data?.rates?.[target]),
            buildInverseUrl: () => `https://open.er-api.com/v6/latest/${encodeURIComponent(target)}`,
            readInverse: (data: any) => Number(data?.rates?.[base]),
        },
        {
            source: 'https://api.exchangerate.host',
            buildDirectUrl: () => `https://api.exchangerate.host/latest?base=${encodeURIComponent(base)}&symbols=${encodeURIComponent(target)}`,
            readDirect: (data: any) => Number(data?.rates?.[target]),
            buildInverseUrl: () => `https://api.exchangerate.host/latest?base=${encodeURIComponent(target)}&symbols=${encodeURIComponent(base)}`,
            readInverse: (data: any) => Number(data?.rates?.[base]),
        },
    ];

    for (const provider of providers) {
        try {
            const directResponse = await fetch(provider.buildDirectUrl(), { cache: 'no-store' });
            if (directResponse.ok) {
                const directData = await directResponse.json();
                const directRate = provider.readDirect(directData);
                if (Number.isFinite(directRate) && directRate > 0) {
                    return { rate: directRate, source: provider.source };
                }
            }
        } catch {
            // Continue to inverse fallback.
        }

        try {
            const inverseResponse = await fetch(provider.buildInverseUrl(), { cache: 'no-store' });
            if (!inverseResponse.ok) continue;
            const inverseData = await inverseResponse.json();
            const inverseRate = provider.readInverse(inverseData);
            if (Number.isFinite(inverseRate) && inverseRate > 0) {
                return { rate: 1 / inverseRate, source: provider.source };
            }
        } catch {
            // Try next provider.
        }
    }

    return null;
}

async function refreshCurrenciesOnLogin(): Promise<void> {
    const currencies = await getCurrenciesRuntime();
    if (!Array.isArray(currencies) || currencies.length === 0) return;

    const defaultCurrency = currencies.find((currency) => currency.isDefault) || currencies[0];
    if (!defaultCurrency?.code) return;
    const baseCode = String(defaultCurrency.code).trim().toUpperCase();
    const nowIso = new Date().toISOString();

    let hasChanges = false;
    for (const currency of currencies) {
        const code = String(currency.code || '').trim().toUpperCase();
        if (!code) continue;
        let changed = false;

        if (code === baseCode) {
            if (Number(currency.exchangeRate) !== 1) {
                currency.exchangeRate = 1;
                changed = true;
            }
            if (changed) {
                currency.lastUpdatedAt = nowIso;
                hasChanges = true;
            }
            continue;
        }

        const resolved = await fetchBasePerCurrencyRate(baseCode, code);
        if (!resolved) continue;

        if (Math.abs(Number(currency.exchangeRate || 0) - resolved.rate) > 0.0000001) {
            currency.exchangeRate = resolved.rate;
            changed = true;
        }
        if (resolved.source && String(currency.source || '') !== resolved.source) {
            currency.source = resolved.source;
            changed = true;
        }
        if (changed) {
            currency.lastUpdatedAt = nowIso;
            hasChanges = true;
        }
    }

    if (hasChanges) {
        await saveCurrenciesRuntime(currencies);
    }
}

const recentMutationRequests = new Map<string, number>();

function acquireMutationWindow(key: string, windowMs = 1200): boolean {
    const now = Date.now();
    const lastAt = recentMutationRequests.get(key) || 0;
    if (now - lastAt < windowMs) {
        return false;
    }
    recentMutationRequests.set(key, now);
    return true;
}

export async function handleRefreshCurrencyRatesNow() {
    try {
        const currencies = await getCurrenciesRuntime();
        if (!Array.isArray(currencies) || currencies.length === 0) {
            return { success: false, error: 'No currencies configured.' };
        }

        const defaultCurrency = currencies.find((currency) => currency.isDefault) || currencies[0];
        if (!defaultCurrency?.code) {
            return { success: false, error: 'Default currency is missing.' };
        }

        const baseCode = String(defaultCurrency.code).trim().toUpperCase();
        let updatedCount = 0;
        const nowIso = new Date().toISOString();

        for (const currency of currencies) {
            const code = String(currency.code || '').trim().toUpperCase();
            if (!code) continue;

            if (code === baseCode) {
                if (Number(currency.exchangeRate) !== 1) {
                    currency.exchangeRate = 1;
                    currency.lastUpdatedAt = nowIso;
                    updatedCount += 1;
                }
                continue;
            }

            const resolved = await fetchBasePerCurrencyRate(baseCode, code);
            if (!resolved) continue;

            let changed = false;
            if (Math.abs(Number(currency.exchangeRate || 0) - resolved.rate) > 0.0000001) {
                currency.exchangeRate = resolved.rate;
                changed = true;
            }
            if (resolved.source && String(currency.source || '') !== resolved.source) {
                currency.source = resolved.source;
                changed = true;
            }

            if (changed) {
                currency.lastUpdatedAt = nowIso;
                updatedCount += 1;
            }
        }

        await saveCurrenciesRuntime(currencies);
        revalidatePath('/admin/general-settings');

        return {
            success: true,
            updatedCount,
            currencies,
        };
    } catch (error) {
        console.error('Manual currency refresh failed:', error);
        return { success: false, error: 'Failed to refresh currency rates.' };
    }
}

export async function handleLogin(values: z.infer<typeof loginSchema>) {
  const parsed = loginSchema.safeParse(values);
  if (!parsed.success) {
    return { error: 'Invalid input.' };
  }

  const { username, password, rememberMe } = parsed.data;
  
    const employees = await getEmployeesRuntime();
  const user = employees.find(
    (e) => e.username === username && e.password === password
  );

  if (!user) {
    return { error: 'Invalid username or password.' };
  }

    try {
        await refreshCurrenciesOnLogin();
    } catch {
        // Never block login if providers are unavailable.
    }

  await createSession(user.id, rememberMe);
    if (user.role === 'admin') {
        redirect('/admin');
    } else {
        redirect('/employee/dashboard');
    }

    return {
        success: true,
        invoiceId: String(invoice.id || ''),
        invoiceNumber: String(invoice.invoiceNumber || ''),
    };
}

const updateSupplierPaymentMetadataSchema = z.object({
    paymentId: z.string().min(1, 'Payment ID is required.'),
    reference: z.string().optional(),
    notes: z.string().optional(),
    rateDate: z.string().optional(),
});

const updateSupplierPaymentFullSchema = z.object({
    paymentId: z.string().min(1, 'Payment ID is required.'),
    amount: z.coerce.number().positive(),
    currencyCode: z.string().min(1),
    exchangeRate: z.coerce.number().positive(),
    rateDate: z.string().optional(),
    isAdvance: z.coerce.boolean().optional().default(false),
    postingStatus: z.enum(['draft', 'saved', 'posted']).optional().default('posted'),
    reference: z.string().optional(),
    notes: z.string().optional(),
    allocations: z.array(z.object({
        purchaseOrderId: z.string().min(1),
        amount: z.coerce.number().positive(),
    })).optional().default([]),
});

const cancelSupplierPaymentSchema = z.object({
    paymentId: z.string().min(1, 'Payment ID is required.'),
    reason: z.string().optional(),
});

export async function handleUpdateSupplierPaymentMetadata(values: z.infer<typeof updateSupplierPaymentMetadataSchema>) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const parsed = updateSupplierPaymentMetadataSchema.safeParse(values);
    if (!parsed.success) return { error: 'Invalid data submitted.' };

    const success = updateSupplierPaymentMetadata(parsed.data.paymentId, {
        reference: parsed.data.reference,
        notes: parsed.data.notes,
        rateDate: parsed.data.rateDate,
    });

    if (!success) return { error: 'Payment voucher not found.' };

    revalidatePath('/admin/purchases/payment');
    revalidatePath('/admin/purchases/view');
    return { success: true };
}

export async function handleUpdateSupplierPaymentFull(values: z.infer<typeof updateSupplierPaymentFullSchema>) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const parsed = updateSupplierPaymentFullSchema.safeParse(values);
    if (!parsed.success) return { error: 'Invalid data submitted.' };

    const normalizedAllocations = (parsed.data.allocations || []).map((entry) => ({
        purchaseOrderId: String(entry.purchaseOrderId || '').trim(),
        amount: Number(entry.amount || 0),
    })).filter((entry) => entry.purchaseOrderId && Number.isFinite(entry.amount) && entry.amount > 0);

    const result = updateSupplierPaymentFull(parsed.data.paymentId, {
        amount: parsed.data.amount,
        currencyCode: parsed.data.currencyCode,
        exchangeRate: parsed.data.exchangeRate,
        rateDate: parsed.data.rateDate,
        isAdvance: parsed.data.isAdvance,
        postingStatus: parsed.data.postingStatus,
        reference: parsed.data.reference,
        notes: parsed.data.notes,
        allocations: normalizedAllocations,
    });

    if (!result.success) {
        return { error: result.error || 'Failed to update payment voucher.' };
    }

    const updatedPayment = result.payment;
    if (updatedPayment) {
        try {
            const journalEntries = await getJournalEntriesRuntime();
            const filteredEntries = journalEntries.filter((entry) => !(entry.referenceType === 'supplier_payment' && entry.referenceId === updatedPayment.id));
            if (filteredEntries.length !== journalEntries.length) {
                await saveJournalEntriesRuntime(filteredEntries);
            }

            const suppliers = await getSuppliersRuntime();
            const supplier = suppliers.find((entry) => entry.id === updatedPayment.supplierId);
            const supplierName = supplier?.name || updatedPayment.supplierId;

            const allocationRows = Array.isArray(updatedPayment.allocations) ? updatedPayment.allocations : [];
            const liabilityBaseAmount = allocationRows.length > 0
                ? allocationRows.reduce((sum, row) => sum + (Number(row.amount || 0) * Number(row.invoiceExchangeRate || 1)), 0)
                : Number(updatedPayment.amountBase ?? (Number(updatedPayment.amount || 0) * Number(updatedPayment.exchangeRate || 1)));

            const cashBaseAmount = Number(updatedPayment.amountBase ?? (Number(updatedPayment.amount || 0) * Number(updatedPayment.exchangeRate || 1)));
            const fxDifferenceBase = allocationRows.length > 0
                ? allocationRows.reduce((sum, row) => sum + Number(row.fxDifferenceBase || 0), 0)
                : 0;

            if ((updatedPayment.postingStatus || 'posted') === 'posted') {
                createSupplierPaymentJournalEntry(
                    updatedPayment.id,
                    updatedPayment.supplierId,
                    supplierName,
                    liabilityBaseAmount,
                    cashBaseAmount,
                    fxDifferenceBase,
                    session.user.name || 'admin'
                );
            }
        } catch (error) {
            console.error('Failed to rebuild supplier payment journal entry:', error);
        }
    }

    revalidatePath('/admin/purchases/payment');
    revalidatePath('/admin/purchases');
    revalidatePath('/admin/purchases/history');
    revalidatePath('/admin/data/suppliers');
    return { success: true, payment: result.payment };
}

export async function handleCancelSupplierPayment(values: z.infer<typeof cancelSupplierPaymentSchema>) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const parsed = cancelSupplierPaymentSchema.safeParse(values);
    if (!parsed.success) return { error: 'Invalid data submitted.' };

    const result = cancelSupplierPayment(parsed.data.paymentId, {
        cancelledBy: session.user.name || 'admin',
        reason: parsed.data.reason,
    });

    if (!result.success) {
        return { error: result.error || 'Failed to cancel payment voucher.' };
    }

    revalidatePath('/admin/purchases/payment');
    revalidatePath('/admin/purchases');
    revalidatePath('/admin/purchases/history');
    revalidatePath('/admin/data/suppliers');
    revalidatePath('/admin/purchases/view');
    return { success: true, payment: result.payment };
}

export async function handleLogout() {
    await destroySession();
    redirect('/login');
}

export async function handleCheckIn() {
    const session = await getSession();
    if (!session?.user) return { success: false, message: 'Unauthorized' };

    const ip = await getIpAddress();
    const settings = await getSettingsRuntime();
    const approvedIpsString = String(settings?.approvedIpAddress || '');

    if (approvedIpsString && approvedIpsString.trim().length > 0) {
        const allowedIps = approvedIpsString
            .split(/[\n,]+/)
            .map((addr) => addr.trim())
            .filter((addr) => addr.length > 0);

        if (!allowedIps.includes(ip)) {
            return { success: false, message: `Check-in failed. Your IP (${ip}) is not on the list of approved addresses.` };
        }
    }

    const recorded = await recordAttendanceRuntime(session.user.id, new Date().toISOString());

    if (recorded) {
        revalidatePath('/employee/dashboard');
        revalidatePath('/admin/dashboard');
        return { success: true, message: 'Check-in successful! Welcome.' };
    }

    return { success: false, message: 'You have already checked in today.' };
}

export async function handleCheckOut() {
    const session = await getSession();
    if (!session?.user) return { success: false, message: 'Unauthorized' };

    const recorded = await recordCheckOutRuntime(session.user.id, new Date().toISOString());

    if (recorded) {
        revalidatePath('/employee/dashboard');
        revalidatePath('/admin/dashboard');
        return { success: true, message: 'Check-out successful! Goodbye.' };
    }

    return { success: false, message: 'Could not check out. Have you checked in today?' };
}


// Add Employee Action
const addEmployeeSchema = z.object({
    name: z.string().min(2, "Name must be at least 2 characters."),
    employeeCode: z.string().trim().optional(),
    nationalId: z.string().trim().optional(),
    workEmail: z.string().email('Invalid email format.').optional().or(z.literal('')),
    birthDate: z.string().optional(),
    gender: z.enum(['male', 'female', 'other']).optional(),
    hireDate: z.string().optional(),
    department: z.string().trim().optional(),
    managerName: z.string().trim().optional(),
    workLocation: z.string().trim().optional(),
    emergencyContactName: z.string().trim().optional(),
    emergencyContactPhone: z.string().trim().optional(),
    employeeCashAccountCode: z.string().trim().optional(),
    payrollExpenseAccountCode: z.string().trim().optional(),
    payrollLiabilityAccountCode: z.string().trim().optional(),
    employeeAdvanceAccountCode: z.string().trim().optional(),
    businessRole: z.string().min(1, "Business role is required."),
    username: z.string().min(3, "Username must be at least 3 characters.").refine(val => !val.includes(' '), 'Username cannot contain spaces.'),
    password: z.string().min(6, "Password must be at least 6 characters."),
    phone: z.string().optional(),
    region: z.string().optional(),
    commissionRate: z.coerce.number().min(0).max(100).optional(),
    salaryType: z.enum(['monthly', 'daily']),
    salary: z.coerce.number().min(0, "Salary must be a positive number."),
    allowedPto: z.coerce.number().int().min(0, "PTO days must be a positive number."),
    status: z.enum(['permanent', 'temporary']),
    defaultShift: z.enum(['first', 'second', 'none']),
    role: z.enum(['admin', 'employee', 'pos']).optional().default('employee'),
    warehouseIds: z.array(z.string()).optional(),
});

export async function handleAddEmployee(values: z.infer<typeof addEmployeeSchema>) {
    const session = await getSession();
    const user = session?.user;
    if(!user || user.role !== 'admin') {
        return { error: 'Unauthorized' };
    }

    const parsed = addEmployeeSchema.safeParse(values);
    if (!parsed.success) {
        return { error: 'Invalid data provided.', details: parsed.error.flatten() };
    }

    const usePostgres = isPostgresProviderEnabled();

    if (usePostgres) {
        const { items } = await pgGetEmployees({ page: 1, pageSize: 10000 });
        const existingEmployees = (items || []) as Employee[];
        const normalizedUsername = parsed.data.username.trim().toLowerCase();
        const usernameExists = existingEmployees.some((employee) => String(employee.username || '').trim().toLowerCase() === normalizedUsername);
        if (usernameExists) {
            return { error: 'Username is already taken.' };
        }
    }

    const createdEmployee = addEmployeeData(parsed.data as Omit<Employee, 'id' | 'financialRecords' | 'attendance' | 'leaveRequests'> & { role?: 'admin' | 'employee' | 'pos' });

    const employeesRuntime = isPostgresProviderEnabled()
        ? (((await pgGetEmployees({ page: 1, pageSize: 10000 })).items || []) as Array<Record<string, any>>)
        : (getEmployees() as Array<Record<string, any>>);
    const employeeList = employeesRuntime.some((entry) => String(entry?.id || '') === String(createdEmployee.id || ''))
        ? employeesRuntime
        : [createdEmployee as unknown as Record<string, any>, ...employeesRuntime];
    const cashboxSetup = await ensureEmployeeCashboxAccountRuntime({
        employeeId: String(createdEmployee.id || ''),
        employeeName: String(createdEmployee.name || ''),
        employees: employeeList,
    });
    const employeeAfterCashbox = cashboxSetup.employee || createdEmployee;
    // Always refresh list after cashbox update (it may have persisted already)
    const employeeListAfterCashbox = isPostgresProviderEnabled()
        ? (((await pgGetEmployees({ page: 1, pageSize: 10000 })).items || []) as Array<Record<string, any>>)
        : (getEmployees() as Array<Record<string, any>>);
    const checksSetup = await ensureEmployeeChecksAccountRuntime({
        employeeId: String(createdEmployee.id || ''),
        employeeName: String(createdEmployee.name || ''),
        employees: employeeListAfterCashbox,
    });
    const createdEmployeeWithCashbox = (checksSetup.employee || employeeAfterCashbox || createdEmployee) as Employee;

    if (usePostgres) {
        await pgSaveEmployees([createdEmployeeWithCashbox]);
    }

    const normalizedBusinessRole = String(parsed.data.businessRole || '').trim().toLowerCase();
    const isSalesRepRole = normalizedBusinessRole === 'مندوب مبيعات' || normalizedBusinessRole === 'sales rep' || normalizedBusinessRole === 'sales-rep';
    if (isSalesRepRole) {
        const salesRepPayload = {
            name: String(createdEmployeeWithCashbox.name || '').trim(),
            phone: String((createdEmployeeWithCashbox as any).phone || '').trim(),
            region: String((createdEmployeeWithCashbox as any).region || '').trim(),
            commissionRate: Number.isFinite((createdEmployeeWithCashbox as any).commissionRate)
                ? Number((createdEmployeeWithCashbox as any).commissionRate)
                : 0,
        };

        if (usePostgres) {
            const { items } = await pgGetSalesReps({ page: 1, pageSize: 10000 });
            const existing = ((items || []) as any[]).find((entry) => String(entry.id || '') === String(createdEmployeeWithCashbox.id || ''));
            if (existing) {
                await pgUpdateSalesRep(String(existing.id), salesRepPayload);
            } else {
                await pgCreateSalesRep({ id: String(createdEmployeeWithCashbox.id || ''), ...salesRepPayload });
            }
        } else {
            const existing = getSalesReps().find((entry) => String(entry.name || '').trim().toLowerCase() === salesRepPayload.name.toLowerCase());
            if (existing) {
                updateSalesRep(existing.id, salesRepPayload);
            } else {
                addSalesRep(salesRepPayload);
            }
        }
    }

    revalidatePath('/admin/dashboard');
    revalidatePath('/admin/employees');
    revalidatePath('/admin/data/sales-reps');
    revalidatePath('/admin/shifts');
    revalidatePath('/employee/shift-swap');
    return { success: true, message: 'Employee added successfully.', employee: createdEmployeeWithCashbox };
}

// Update Employee Action
const updateEmployeeSchema = z.object({
    name: z.string().min(2, "Name must be at least 2 characters."),
    employeeCode: z.string().trim().optional(),
    nationalId: z.string().trim().optional(),
    workEmail: z.string().email('Invalid email format.').optional().or(z.literal('')),
    birthDate: z.string().optional(),
    gender: z.enum(['male', 'female', 'other']).optional(),
    hireDate: z.string().optional(),
    department: z.string().trim().optional(),
    managerName: z.string().trim().optional(),
    workLocation: z.string().trim().optional(),
    emergencyContactName: z.string().trim().optional(),
    emergencyContactPhone: z.string().trim().optional(),
    employeeCashAccountCode: z.string().trim().optional(),
    payrollExpenseAccountCode: z.string().trim().optional(),
    payrollLiabilityAccountCode: z.string().trim().optional(),
    employeeAdvanceAccountCode: z.string().trim().optional(),
    businessRole: z.string().min(1, "Business role is required."),
    phone: z.string().optional(),
    region: z.string().optional(),
    commissionRate: z.coerce.number().min(0).max(100).optional(),
    salaryType: z.enum(['monthly', 'daily']),
    salary: z.coerce.number().min(0, "Salary must be a positive number."),
    allowedPto: z.coerce.number().int().min(0, "PTO days must be a positive number."),
    status: z.enum(['permanent', 'temporary']),
    defaultShift: z.enum(['first', 'second', 'none']),
    password: z.string().min(6, "Password must be at least 6 characters.").optional().or(z.literal('')),
    role: z.enum(['admin', 'employee', 'pos']).optional(),
    warehouseIds: z.array(z.string()).optional(),
});

export async function handleUpdateEmployee(employeeId: string, values: z.infer<typeof updateEmployeeSchema>) {
    const session = await getSession();
    const user = session?.user;
    if (!user || user.role !== 'admin') {
        return { error: 'Unauthorized' };
    }

    const parsed = updateEmployeeSchema.safeParse(values);
    if (!parsed.success) {
        return { error: 'Invalid data provided.', details: parsed.error.flatten() };
    }

    const usePostgres = isPostgresProviderEnabled();
    const success = usePostgres ? true : updateEmployee(employeeId, parsed.data);
    if (!success) {
        return { error: 'Employee not found.' };
    }

    const employeeRuntimeList = usePostgres
        ? (((await pgGetEmployees({ page: 1, pageSize: 10000 })).items || []) as Array<Record<string, any>>)
        : (getEmployees() as Array<Record<string, any>>);
    const cashboxSetup = await ensureEmployeeCashboxAccountRuntime({
        employeeId,
        employeeName: String(parsed.data.name || ''),
        employees: employeeRuntimeList,
    });

    // Also ensure checks account exists (reload list after cashbox update)
    const employeeListAfterCashbox2 = isPostgresProviderEnabled()
        ? (((await pgGetEmployees({ page: 1, pageSize: 10000 })).items || []) as Array<Record<string, any>>)
        : (getEmployees() as Array<Record<string, any>>);
    const checksSetup2 = await ensureEmployeeChecksAccountRuntime({
        employeeId,
        employeeName: String(parsed.data.name || ''),
        employees: employeeListAfterCashbox2,
    });

    if (usePostgres) {
        const { items } = await pgGetEmployees({ page: 1, pageSize: 10000 });
        const existingEmployees = (items || []) as Employee[];
        const existing = existingEmployees.find(
            (employee) => String(employee?.id || '').trim() === String(employeeId || '').trim(),
        );
        if (!existing) {
            return { error: 'Employee not found.' };
        }

        const updated: Employee = {
            ...existing,
            ...parsed.data,
            ...(cashboxSetup.employee || {}),
            ...(checksSetup2.employee || {}),
            salaryType: parsed.data.status === 'temporary' ? 'daily' : parsed.data.salaryType,
            salary: parsed.data.status === 'temporary' ? 0 : parsed.data.salary,
            password: parsed.data.password === '' || parsed.data.password === undefined
                ? existing.password
                : parsed.data.password,
        };
        await pgSaveEmployees([updated]);
    }

    const normalizedBusinessRole = String(parsed.data.businessRole || '').trim().toLowerCase();
    const isSalesRepRole = normalizedBusinessRole === 'مندوب مبيعات' || normalizedBusinessRole === 'sales rep' || normalizedBusinessRole === 'sales-rep';
    if (isSalesRepRole) {
        const salesRepPayload = {
            name: String(parsed.data.name || '').trim(),
            phone: String(parsed.data.phone || '').trim(),
            region: String(parsed.data.region || '').trim(),
            commissionRate: typeof parsed.data.commissionRate === 'number' ? parsed.data.commissionRate : 0,
        };

        if (usePostgres) {
            const { items } = await pgGetSalesReps({ page: 1, pageSize: 10000 });
            const existing = ((items || []) as any[]).find((entry) => String(entry.id || '') === String(employeeId));
            if (existing) {
                await pgUpdateSalesRep(String(existing.id), salesRepPayload);
            } else {
                await pgCreateSalesRep({ id: String(employeeId), ...salesRepPayload });
            }
        } else {
            const existing = getSalesReps().find((entry) => String(entry.name || '').trim().toLowerCase() === salesRepPayload.name.toLowerCase());
            if (existing) {
                updateSalesRep(existing.id, salesRepPayload);
            } else {
                addSalesRep(salesRepPayload);
            }
        }
    }

    revalidatePath('/admin/dashboard');
    revalidatePath('/admin/employees');
    revalidatePath('/admin/data/sales-reps');
    revalidatePath('/admin/shifts');
    revalidatePath('/admin/leave-requests');
    revalidatePath('/employee/dashboard');
    revalidatePath('/employee/shift-swap');
    return { success: true, message: 'Employee updated successfully.' };
}

export async function handleBuildEmployeeCashbox(employeeId: string) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const employees = isPostgresProviderEnabled()
        ? (((await pgGetEmployees({ page: 1, pageSize: 10000 })).items || []) as Array<Record<string, any>>)
        : (getEmployees() as Array<Record<string, any>>);
    const employee = employees.find((entry) => String(entry?.id || '').trim() === String(employeeId || '').trim());
    if (!employee) return { error: 'Employee not found.' };

    const result = await ensureEmployeeCashboxAccountRuntime({
        employeeId: String(employee.id || ''),
        employeeName: String(employee.name || ''),
        employees,
    });

    revalidatePath('/admin/employees');
    return { success: true, employee: result.employee, account: result.account };
}

export async function handleTransferEmployeeCashboxToMain(
    employeeId: string,
    options?: {
        source?: 'dashboard' | 'employee-table' | 'other';
        selectedMonth?: number;
        selectedYear?: number;
        differenceDecision?: 'post_cash_difference' | 'charge_cashier' | 'transfer_without_difference_entry' | 'abort_transfer' | 'transfer_actual' | 'transfer_shift_net_only';
    }
) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const employees = isPostgresProviderEnabled()
        ? (((await pgGetEmployees({ page: 1, pageSize: 10000 })).items || []) as Array<Record<string, any>>)
        : (getEmployees() as Array<Record<string, any>>);
    const employee = employees.find((entry) => String(entry?.id || '').trim() === String(employeeId || '').trim());
    if (!employee) return { error: 'Employee not found.' };

    const shiftSessions = await getPosShiftSessionsRuntime();
    const hasActiveShift = shiftSessions.some(
        (shift) => String(shift.userId || '').trim() === String(employee.id || '').trim() && shift.status === 'active'
    );
    if (hasActiveShift) {
        return { error: 'POS_SHIFT_MUST_BE_CLOSED' };
    }

    const employeeCashCode = String(employee.employeeCashAccountCode || '').trim();
    if (!employeeCashCode) return { error: 'Employee cashbox is not configured.' };

    const accounts = await getChartOfAccountsRuntime();
    const employeeCashAccount = accounts.find((entry) => String(entry?.code || '').trim() === employeeCashCode);
    const mainCashAccount = accounts.find((entry) => String(entry?.code || '').trim() === '1110');
    if (!employeeCashAccount || !mainCashAccount) return { error: 'Required cash accounts not found.' };

    const journalEntries = await getJournalEntriesRuntime();
    let balance = 0;
    journalEntries.forEach((entry: any) => {
        (entry?.lines || []).forEach((line: any) => {
            if (String(line?.accountCode || '').trim() !== employeeCashCode) return;
            balance += Number(line?.debit || 0) - Number(line?.credit || 0);
        });
    });

    const transferAmount = Math.round(balance * 100) / 100;
    if (!Number.isFinite(transferAmount) || transferAmount <= 0) {
        return { error: 'No positive balance available for transfer.' };
    }

    const selectedMonth = Number(options?.selectedMonth || 0);
    const selectedYear = Number(options?.selectedYear || 0);
    const isValidMonthYear = Number.isInteger(selectedMonth) && selectedMonth >= 1 && selectedMonth <= 12 && Number.isInteger(selectedYear) && selectedYear > 1970;
    const relevantClosedShifts = isValidMonthYear
        ? shiftSessions.filter((shift) => {
            const shiftUserId = String((shift as any)?.userId || '').trim();
            if (shiftUserId !== String(employee.id || '').trim()) return false;
            if (String((shift as any)?.status || '').trim() !== 'closed') return false;
            if ((shift as any)?.cashVarianceHandled === true) return false;
            const startedAt = new Date(String((shift as any)?.startedAt || '').trim());
            if (Number.isNaN(startedAt.getTime())) return false;
            return startedAt.getMonth() + 1 === selectedMonth && startedAt.getFullYear() === selectedYear;
        })
        : [];
    const pendingCashVariance = Math.round(
        relevantClosedShifts.reduce((sum, shift) => sum + Number((shift as any)?.cashVariance || 0), 0) * 100,
    ) / 100;
    const hasDifference = Math.abs(pendingCashVariance) > 0.0001;

    const source = String(options?.source || 'other').trim();
    const differenceDecision = String(options?.differenceDecision || '').trim();
    const normalizedDecision = differenceDecision === 'transfer_actual'
        ? 'transfer_without_difference_entry'
        : differenceDecision === 'transfer_shift_net_only'
            ? 'transfer_without_difference_entry'
            : differenceDecision;

    if (hasDifference && source !== 'dashboard') {
        return { error: 'CASHBOX_TRANSFER_REQUIRES_DASHBOARD_REVIEW', differenceAmount: pendingCashVariance, transferAmount };
    }

    if (hasDifference && !normalizedDecision) {
        return { error: 'CASHBOX_TRANSFER_DIFFERENCE_DECISION_REQUIRED', differenceAmount: pendingCashVariance, transferAmount };
    }

    if (normalizedDecision === 'abort_transfer') {
        return { error: 'CASHBOX_TRANSFER_ABORTED_BY_MANAGER', differenceAmount: pendingCashVariance, transferAmount };
    }

    let finalTransferAmount = transferAmount;
    let differencePolicyApplied: 'post_cash_difference' | 'charge_cashier' | 'transfer_without_difference_entry' | undefined;
    let varianceSettlementEntry: JournalEntry | null = null;
    let cashDifferenceAccountAutoCreated = false;

    const resolveCashDifferenceAccount = (list: Array<Record<string, any>>) => {
        const byName = list.find((entry) => {
            const ar = String(entry?.nameAr || '').trim().toLowerCase();
            const en = String(entry?.nameEn || '').trim().toLowerCase();
            return ar.includes('فروقات الصندوق')
                || (ar.includes('عجز') && ar.includes('زيادة'))
                || en.includes('cash over')
                || en.includes('over / short')
                || en.includes('cash over / short');
        });
        return byName || null;
    };

    const ensureCashDifferenceAccountRuntime = async (list: Array<Record<string, any>>) => {
        const existing = resolveCashDifferenceAccount(list);
        if (existing) {
            return { account: existing, autoCreated: false };
        }

        let changed = false;

        const expensesHeader = ensureChartAccountInCollection(list, {
            preferredCode: '5000',
            nameAr: 'المصروفات',
            nameEn: 'Expenses',
            parentCode: '',
            type: 'header',
        });
        changed = changed || expensesHeader.changed;

        const adminExpensesHeader = ensureChartAccountInCollection(list, {
            preferredCode: '5300',
            nameAr: 'مصاريف إدارية',
            nameEn: 'Administrative Expenses',
            parentCode: '5000',
            type: 'header',
        });
        changed = changed || adminExpensesHeader.changed;

        const cashDifferenceAccount = ensureChartAccountInCollection(list, {
            preferredCode: '5351',
            nameAr: 'فروقات الصندوق',
            nameEn: 'Cash Over / Short',
            parentCode: String(adminExpensesHeader.account?.code || '5300'),
            nature: 'debit',
            type: 'account',
        });
        changed = changed || cashDifferenceAccount.changed;

        if (changed) {
            await saveChartOfAccountsRuntime(list);
        }

        return {
            account: cashDifferenceAccount.account || null,
            autoCreated: changed,
        };
    };

    const resolveEmployeeReceivableAccount = (list: Array<Record<string, any>>) => {
        const byCode = list.find((entry) => String(entry?.code || '').trim() === '1340');
        if (byCode) return byCode;
        return list.find((entry) => {
            const ar = String(entry?.nameAr || '').trim().toLowerCase();
            const en = String(entry?.nameEn || '').trim().toLowerCase();
            return (ar.includes('ذمم') && ar.includes('موظ')) || en.includes('employee receivable');
        }) || null;
    };

    const entry: JournalEntry = {
        id: nextPrefixedId('je-empcash'),
        date: new Date().toISOString(),
        description: `ترحيل رصيد صندوق الموظف ${String(employee.name || '').trim()} إلى الصندوق الرئيسي`
            + (hasDifference
                ? ` (سياسة الفارق: ${differencePolicyApplied === 'transfer_shift_net_only' ? 'ترحيل صافي الورديات فقط' : 'ترحيل الرصيد الفعلي'})`
                : ''),
        referenceType: 'manual',
        referenceId: String(employee.id || ''),
        lines: [
            {
                accountId: String(mainCashAccount.id || '1110'),
                accountCode: String(mainCashAccount.code || '1110'),
                accountName: String(mainCashAccount.nameAr || 'الصندوق'),
                debit: finalTransferAmount,
                credit: 0,
                description: `استلام من صندوق الموظف ${String(employee.name || '').trim()}`,
            },
            {
                accountId: String(employeeCashAccount.id || employeeCashCode),
                accountCode: employeeCashCode,
                accountName: String(employeeCashAccount.nameAr || `صندوق ${String(employee.name || '').trim()}`),
                debit: 0,
                credit: finalTransferAmount,
                description: `ترحيل إلى الصندوق الرئيسي - ${String(employee.name || '').trim()}`,
            },
        ],
        createdBy: session.user.name || 'admin',
        createdAt: new Date().toISOString(),
    };

    journalEntries.unshift(entry);

    if (hasDifference && ['post_cash_difference', 'charge_cashier', 'transfer_without_difference_entry'].includes(normalizedDecision)) {
        differencePolicyApplied = normalizedDecision as 'post_cash_difference' | 'charge_cashier' | 'transfer_without_difference_entry';
        const varianceAbs = Math.abs(pendingCashVariance);

        if (normalizedDecision === 'post_cash_difference') {
            const ensuredCashDifferenceAccount = await ensureCashDifferenceAccountRuntime(accounts as Array<Record<string, any>>);
            const cashDifferenceAccount = ensuredCashDifferenceAccount.account;
            cashDifferenceAccountAutoCreated = cashDifferenceAccountAutoCreated || ensuredCashDifferenceAccount.autoCreated;
            if (!cashDifferenceAccount) {
                return { error: 'CASH_DIFFERENCE_ACCOUNT_NOT_CONFIGURED', differenceAmount: pendingCashVariance };
            }

            varianceSettlementEntry = {
                id: nextPrefixedId('je-cashvar'),
                date: new Date().toISOString(),
                description: `تسوية فروقات جرد الكاشير ${String(employee.name || '').trim()} خلال الترحيل`,
                referenceType: 'manual',
                referenceId: String(employee.id || ''),
                lines: pendingCashVariance > 0
                    ? [
                        {
                            accountId: String(mainCashAccount.id || '1110'),
                            accountCode: String(mainCashAccount.code || '1110'),
                            accountName: String(mainCashAccount.nameAr || 'الصندوق'),
                            debit: varianceAbs,
                            credit: 0,
                            description: 'إثبات زيادة جرد الكاشير',
                        },
                        {
                            accountId: String(cashDifferenceAccount.id || cashDifferenceAccount.code || ''),
                            accountCode: String(cashDifferenceAccount.code || ''),
                            accountName: String(cashDifferenceAccount.nameAr || cashDifferenceAccount.nameEn || 'فروقات الصندوق'),
                            debit: 0,
                            credit: varianceAbs,
                            description: 'زيادة صندوق (Cash Over)',
                        },
                    ]
                    : [
                        {
                            accountId: String(cashDifferenceAccount.id || cashDifferenceAccount.code || ''),
                            accountCode: String(cashDifferenceAccount.code || ''),
                            accountName: String(cashDifferenceAccount.nameAr || cashDifferenceAccount.nameEn || 'فروقات الصندوق'),
                            debit: varianceAbs,
                            credit: 0,
                            description: 'نقص صندوق (Cash Short)',
                        },
                        {
                            accountId: String(mainCashAccount.id || '1110'),
                            accountCode: String(mainCashAccount.code || '1110'),
                            accountName: String(mainCashAccount.nameAr || 'الصندوق'),
                            debit: 0,
                            credit: varianceAbs,
                            description: 'إثبات نقص جرد الكاشير',
                        },
                    ],
                createdBy: session.user.name || 'admin',
                createdAt: new Date().toISOString(),
            };
            journalEntries.unshift(varianceSettlementEntry);
        }

        if (normalizedDecision === 'charge_cashier') {
            if (pendingCashVariance >= 0) {
                return { error: 'CASHBOX_TRANSFER_CHARGE_CASHIER_ONLY_FOR_SHORTAGE', differenceAmount: pendingCashVariance };
            }

            const ensuredCashDifferenceAccount = await ensureCashDifferenceAccountRuntime(accounts as Array<Record<string, any>>);
            const cashDifferenceAccount = ensuredCashDifferenceAccount.account;
            cashDifferenceAccountAutoCreated = cashDifferenceAccountAutoCreated || ensuredCashDifferenceAccount.autoCreated;
            if (!cashDifferenceAccount) {
                return { error: 'CASH_DIFFERENCE_ACCOUNT_NOT_CONFIGURED', differenceAmount: pendingCashVariance };
            }
            const employeeReceivableAccount = resolveEmployeeReceivableAccount(accounts as Array<Record<string, any>>);
            if (!employeeReceivableAccount) {
                return { error: 'EMPLOYEE_RECEIVABLE_ACCOUNT_NOT_CONFIGURED', differenceAmount: pendingCashVariance };
            }

            varianceSettlementEntry = {
                id: nextPrefixedId('je-cashvar'),
                date: new Date().toISOString(),
                description: `تحميل نقص جرد الكاشير ${String(employee.name || '').trim()} على ذمم الموظف`,
                referenceType: 'manual',
                referenceId: String(employee.id || ''),
                lines: [
                    {
                        accountId: String(employeeReceivableAccount.id || employeeReceivableAccount.code || ''),
                        accountCode: String(employeeReceivableAccount.code || ''),
                        accountName: String(employeeReceivableAccount.nameAr || employeeReceivableAccount.nameEn || 'ذمم موظفين'),
                        debit: varianceAbs,
                        credit: 0,
                        description: `تحميل نقص الكاشير ${String(employee.name || '').trim()}`,
                    },
                    {
                        accountId: String(cashDifferenceAccount.id || cashDifferenceAccount.code || ''),
                        accountCode: String(cashDifferenceAccount.code || ''),
                        accountName: String(cashDifferenceAccount.nameAr || cashDifferenceAccount.nameEn || 'فروقات الصندوق'),
                        debit: 0,
                        credit: varianceAbs,
                        description: 'تسوية فرق الجرد على حساب فروقات الصندوق',
                    },
                ],
                createdBy: session.user.name || 'admin',
                createdAt: new Date().toISOString(),
            };
            journalEntries.unshift(varianceSettlementEntry);
        }
    }

    await saveJournalEntriesRuntime(journalEntries);

    if (hasDifference && differencePolicyApplied) {
        const varianceEntryId = varianceSettlementEntry?.id;
        const settledAt = new Date().toISOString();
        const updatedSessions = shiftSessions.map((shift) => {
            const shiftUserId = String((shift as any)?.userId || '').trim();
            if (shiftUserId !== String(employee.id || '').trim()) return shift;
            if (String((shift as any)?.status || '').trim() !== 'closed') return shift;
            if ((shift as any)?.cashVarianceHandled === true) return shift;
            const startedAt = new Date(String((shift as any)?.startedAt || '').trim());
            if (Number.isNaN(startedAt.getTime())) return shift;
            if (!(startedAt.getMonth() + 1 === selectedMonth && startedAt.getFullYear() === selectedYear)) return shift;
            return {
                ...shift,
                cashVarianceHandled: true,
                cashVarianceHandledAt: settledAt,
                cashVarianceHandlingMethod: differencePolicyApplied,
                cashVarianceHandlingEntryId: varianceEntryId,
            };
        });
        await savePosShiftSessionsRuntime(updatedSessions as PosShiftSession[]);
    }

    revalidatePath('/admin/employees');
    revalidatePath('/admin/dashboard');
    revalidatePath('/admin/accounting/entries');
    return {
        success: true,
        amount: finalTransferAmount,
        entry,
        differenceAmount: pendingCashVariance,
        shiftNetForMonth: undefined,
        differencePolicyApplied,
        varianceEntry: varianceSettlementEntry,
        cashDifferenceAccountAutoCreated,
    };
}

// ─── Bulk add product shapes ─────────────────────────────────────────────────
export async function handleBulkAddProductShapes(
    names: string[]
): Promise<{ added: Array<Record<string, unknown>>; skipped: string[]; error?: string }> {
    'use server';
    if (!Array.isArray(names) || names.length === 0) {
        return { added: [], skipped: [], error: 'لا توجد أسماء للإضافة' };
    }

    const unique = Array.from(new Set(names.map((n) => String(n || '').trim()).filter(Boolean)));

    try {
        if (isPostgresProviderEnabled()) {
            const added: Record<string, unknown>[] = [];
            const skipped: string[] = [];
            for (const name of unique) {
                try {
                    const seqNum = await pgNextNamedSequence('shape-ref');
                    const shapeNumber = `PSH-${String(seqNum).padStart(4, '0')}`;
                    const result = await pgCreateProductShapeDefinition({
                        id: shapeNumber,
                        itemNumber: shapeNumber,
                        name,
                        salePrice: 0,
                        categoryPrices: {},
                    });
                    added.push(result as Record<string, unknown>);
                } catch (e: any) {
                    const msg = String(e?.message || '');
                    const isdup = e?.code === '23505' || msg.includes('already exists') || msg.includes('unique');
                    if (isdup) { skipped.push(name); } else { skipped.push(name); }
                }
            }
            revalidatePath('/admin/data/product-shapes');
            return { added, skipped };
        } else {
            const { added, skipped } = addProductShapeDefinitions(unique);
            revalidatePath('/admin/data/product-shapes');
            return { added: added as unknown as Record<string, unknown>[], skipped };
        }
    } catch (e: any) {
        return { added: [], skipped: [], error: String(e?.message || 'حدث خطأ') };
    }
}

export async function handleBuildEmployeeChecksAccount(employeeId: string) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const employees = isPostgresProviderEnabled()
        ? (((await pgGetEmployees({ page: 1, pageSize: 10000 })).items || []) as Array<Record<string, any>>)
        : (getEmployees() as Array<Record<string, any>>);
    const employee = employees.find((entry) => String(entry?.id || '').trim() === String(employeeId || '').trim());
    if (!employee) return { error: 'Employee not found.' };

    const result = await ensureEmployeeChecksAccountRuntime({
        employeeId: String(employee.id || ''),
        employeeName: String(employee.name || ''),
        employees,
    });

    revalidatePath('/admin/employees');
    return { success: true, employee: result.employee, account: result.account };
}

export async function handleTransferEmployeeChecksToMain(employeeId: string) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const employees = isPostgresProviderEnabled()
        ? (((await pgGetEmployees({ page: 1, pageSize: 10000 })).items || []) as Array<Record<string, any>>)
        : (getEmployees() as Array<Record<string, any>>);
    const employee = employees.find((entry) => String(entry?.id || '').trim() === String(employeeId || '').trim());
    if (!employee) return { error: 'Employee not found.' };

    const employeeChecksCode = String(employee.employeeChecksAccountCode || '').trim();
    if (!employeeChecksCode) return { error: 'Employee checks account is not configured.' };

    const accounts = await getChartOfAccountsRuntime();
    const employeeChecksAccount = accounts.find((entry) => String(entry?.code || '').trim() === employeeChecksCode);
    const mainChecksAccount = accounts.find((entry) => String(entry?.code || '').trim() === '1140');
    if (!employeeChecksAccount || !mainChecksAccount) return { error: 'Required accounts not found.' };

    const journalEntries = await getJournalEntriesRuntime();
    let balance = 0;
    journalEntries.forEach((entry: any) => {
        (entry?.lines || []).forEach((line: any) => {
            if (String(line?.accountCode || '').trim() !== employeeChecksCode) return;
            balance += Number(line?.debit || 0) - Number(line?.credit || 0);
        });
    });

    const transferAmount = Math.round(balance * 100) / 100;
    if (!Number.isFinite(transferAmount) || transferAmount <= 0) {
        return { error: 'No positive balance available for transfer.' };
    }

    const entry: JournalEntry = {
        id: nextPrefixedId('je-empchk'),
        date: new Date().toISOString(),
        description: `ترحيل شيكات الموظف ${String(employee.name || '').trim()} إلى حساب أوراق القبض الرئيسي`,
        referenceType: 'manual',
        referenceId: String(employee.id || ''),
        lines: [
            {
                accountId: String(mainChecksAccount.id || '1140'),
                accountCode: String(mainChecksAccount.code || '1140'),
                accountName: String(mainChecksAccount.nameAr || 'أوراق القبض'),
                debit: transferAmount,
                credit: 0,
                description: `استلام شيكات من الموظف ${String(employee.name || '').trim()}`,
            },
            {
                accountId: String(employeeChecksAccount.id || employeeChecksCode),
                accountCode: employeeChecksCode,
                accountName: String(employeeChecksAccount.nameAr || `شيكات ${String(employee.name || '').trim()}`),
                debit: 0,
                credit: transferAmount,
                description: `ترحيل إلى أوراق القبض - ${String(employee.name || '').trim()}`,
            },
        ],
        createdBy: session.user.name || 'admin',
        createdAt: new Date().toISOString(),
    };

    journalEntries.unshift(entry);
    await saveJournalEntriesRuntime(journalEntries);
    revalidatePath('/admin/employees');
    revalidatePath('/admin/accounting/entries');
    return { success: true, amount: transferAmount, entry };
}


// Delete Employee Action
export async function handleDeleteEmployee(employeeId: string) {
    const session = await getSession();
    const user = session?.user;
    if(!user || user.role !== 'admin') {
        return { error: 'Unauthorized' };
    }

    if (user.id === employeeId) {
        return { error: 'You cannot delete your own account.' };
    }

    const success = deleteEmployeeData(employeeId);

    const usePostgres = isPostgresProviderEnabled();
    if (usePostgres) {
        const { items } = await pgGetEmployees({ page: 1, pageSize: 10000 });
        const existingEmployees = (items || []) as Employee[];
        const target = existingEmployees.find((employee) => employee.id === employeeId);
        if (target) {
            const deletedMarker = {
                ...target,
                _deleted: true,
                deletedAt: new Date().toISOString(),
            } as Record<string, unknown>;
            await pgSaveEmployees([deletedMarker]);
        }
    }

    if (success) {
        revalidatePath('/admin/dashboard');
        revalidatePath('/admin/employees');
        revalidatePath('/admin/shifts');
        revalidatePath('/employee/shift-swap');
        return { success: true, message: 'Employee deleted successfully.' };
    }

    return { error: 'Failed to delete employee.' };
}


// Change Password Action
const changePasswordSchema = z.object({
  currentPassword: z.string(),
  newPassword: z.string().min(6, "New password must be at least 6 characters."),
});

const updateOwnCredentialsSchema = z.object({
    newPassword: z.string().min(6, "New password must be at least 6 characters.").optional().or(z.literal('')),
});

export async function handleChangePassword(values: z.infer<typeof changePasswordSchema>) {
  const session = await getSession();
  const user = session?.user;
  if (!user) return { error: 'Unauthorized' };

    const employee = await getEmployeeByIdRuntime(user.id);
  if (employee?.password !== values.currentPassword) {
      return { error: 'Incorrect current password.' };
  }

    const success = await updatePasswordRuntime(user.id, values.newPassword);
  if (success) {
      return { success: true };
  } else {
      return { error: 'Failed to update password.' };
  }
}

export async function handleUpdateOwnCredentials(values: z.infer<typeof updateOwnCredentialsSchema>) {
    const session = await getSession();
    const user = session?.user;
    if (!user) return { error: 'Unauthorized' };

    const parsed = updateOwnCredentialsSchema.safeParse(values);
    if (!parsed.success) {
        return { error: 'Invalid data provided.' };
    }

    const nextPassword = String(parsed.data.newPassword || '').trim();
    if (!nextPassword) {
        return { success: true };
    }

    const success = await updatePasswordRuntime(user.id, nextPassword);
    if (!success) {
        return { error: 'Failed to update password.' };
    }

    return { success: true };
}

// Update Settings Action
const updateSettingsSchema = z.object({
  approvedIpAddress: z.string().optional(),
});

export async function handleUpdateSettings(values: z.infer<typeof updateSettingsSchema>) {
    const session = await getSession();
    const user = session?.user;
    if (!user || user.role !== 'admin') {
        return { error: 'Unauthorized.' };
    }

    const parsed = updateSettingsSchema.safeParse(values);
    if (!parsed.success) {
        return { error: "Invalid data submitted." };
    }

    if (parsed.data.approvedIpAddress || parsed.data.approvedIpAddress === '') {
      updateSetting('approvedIpAddress', parsed.data.approvedIpAddress);
    }
    
    revalidatePath('/settings');
    return { success: true, message: "Settings updated successfully." };
}

// Financial Records Actions
const advanceScheduleSchema = z.object({
  description: z.string().min(2, "Description is required.").default("Salary Advance"),
  totalAmount: z.coerce.number().min(1, "Total amount must be greater than zero."),
  installments: z.array(z.object({
      month: z.string(),
      year: z.string(),
      amount: z.coerce.number().min(0.01, "Amount must be positive.")
  })).min(1, "At least one installment is required."),
  requestId: z.string().nullable(),
}).refine(data => {
    const totalInstallments = data.installments.reduce((sum, inst) => sum + inst.amount, 0);
    return Math.abs(data.totalAmount - totalInstallments) < 0.01;
}, {
    message: "The sum of installments must equal the total advance amount.",
    path: ["installments"],
});

const oneTimeRecordSchema = z.object({
  description: z.string().min(2, "Description is required."),
  amount: z.coerce.number().min(0.01, "Amount must be positive."),
  month: z.string(),
  year: z.string(),
  recordType: z.enum(['deduction', 'bonus']),
});


export async function handleUpdateFinancialRecord(employeeId: string, formType: 'advance' | 'oneTime', values: any) {
    const session = await getSession();
    const user = session?.user;
    if (!user || user.role !== 'admin') return { error: 'Unauthorized' };

    let success = false;
    
    if (formType === 'advance') {
        const parsed = advanceScheduleSchema.safeParse(values);
        if (!parsed.success) return { error: 'Invalid data for advance.', details: parsed.error.flatten() };
        
        const { description, totalAmount, installments: formInstallments, requestId } = parsed.data;

        const totalInstallmentAmount = formInstallments.reduce((sum, inst) => sum + inst.amount, 0);
        if (Math.abs(totalAmount - totalInstallmentAmount) > 0.01) {
            return { error: 'The sum of installment amounts does not match the total advance amount.' };
        }
        
        const disbursementRecord: Omit<FinancialRecord, 'id'> = {
            requestId: requestId ?? undefined,
            description: `Manual Advance: ${description}`,
            totalAmount: -totalAmount,
            installments: [{ date: new Date(), amount: -totalAmount }]
        };
        await updateFinancialRecordRuntime(employeeId, disbursementRecord);

         const installments: Installment[] = formInstallments.map(inst => ({
            date: new Date(parseInt(inst.year), parseInt(inst.month)),
            amount: inst.amount
        }));

        const repaymentRecord: Omit<FinancialRecord, 'id'> = {
            requestId: requestId ?? undefined,
            description: "Salary Advance Repayment",
            totalAmount: totalAmount,
            installments: installments
        };
        success = await updateFinancialRecordRuntime(employeeId, repaymentRecord);
        
        if (requestId) {
            await updateLeaveRequestStatusRuntime(employeeId, requestId, 'approved');
        }

    } else { // oneTime
        const parsed = oneTimeRecordSchema.safeParse(values);
        if (!parsed.success) return { error: 'Invalid data for one-time record.', details: parsed.error.flatten() };

        const amount = parsed.data.recordType === 'deduction' ? parsed.data.amount : -parsed.data.amount;
        const record = {
            description: parsed.data.description,
            totalAmount: amount,
            installments: [{ date: new Date(parseInt(values.year), parseInt(values.month)), amount: amount }]
        }
        success = await updateFinancialRecordRuntime(employeeId, record);
    }
    
    if(success) {
        revalidatePath('/admin/dashboard');
        revalidatePath(`/admin/employee/${employeeId}/financials`);
        revalidatePath('/employee/dashboard');
        revalidatePath('/employee/statement');
        revalidatePath(`/admin/employee/${employeeId}/statement`);
        return { success: true };
    } else {
        return { error: 'Failed to update record.' };
    }
}

const editAdvanceScheduleSchema = z.object({
  recordId: z.string(),
  installments: z.array(z.object({
      month: z.string(),
      year: z.string(),
      amount: z.coerce.number().min(0.01, "Amount must be positive.")
  })).min(1, "At least one installment is required."),
});

export async function handleEditAdvanceSchedule(employeeId: string, values: z.infer<typeof editAdvanceScheduleSchema>) {
    const session = await getSession();
    const user = session?.user;
    if (!user || user.role !== 'admin') return { error: 'Unauthorized' };

    const parsed = editAdvanceScheduleSchema.safeParse(values);
    if (!parsed.success) return { error: 'Invalid data provided.' };
    
    const { recordId, installments: formInstallments } = parsed.data;

    const success = await editAdvanceScheduleRuntime(employeeId, {
        recordId,
        installments: formInstallments as Array<{ month: string; year: string; amount: number }>,
    });
    if(success) {
        revalidatePath(`/admin/employee/${employeeId}/financials`);
        revalidatePath('/admin/dashboard');
        revalidatePath('/admin/employees');
        revalidatePath('/employee/dashboard');
        revalidatePath('/employee/statement');
        revalidatePath(`/admin/employee/${employeeId}/statement`);
        return { success: true, message: 'Repayment schedule updated successfully.' };
    }

    return { error: 'Failed to update repayment schedule.' };
}

// Leave Request Action
const leaveRequestSchema = z.object({
    dateRange: z.object({
        from: z.date({ required_error: "Please select a start date." }),
        to: z.date({ required_error: "Please select an end date." }),
    }),
    reason: z.string().min(10, 'Reason must be at least 10 characters.'),
});

export async function handleLeaveRequest(values: z.infer<typeof leaveRequestSchema>) {
    const session = await getSession();
    const user = session?.user;
    if (!user) return { error: 'Unauthorized' };

    const parsed = leaveRequestSchema.safeParse(values);
    if (!parsed.success) {
        const firstError = parsed.error.flatten().fieldErrors;
        const mainError = Object.values(firstError)[0];
        return { error: mainError ? mainError[0] : 'Invalid data.' };
    }
    
    const requestData = {
        requestType: 'leave' as const,
        dateRange: {
            from: parsed.data.dateRange.from,
            to: parsed.data.dateRange.to,
        },
        reason: parsed.data.reason
    };

    const success = await addLeaveRequestRuntime(user.id, requestData);
    
    if (success) {
        revalidatePath('/employee/leave');
        revalidatePath('/admin/leave-requests');
        return { success: true };
    }
    return { error: 'Failed to submit request.' };
}

export async function handleApproveLeaveRequest(employeeId: string, requestId: string) {
    const session = await getSession();
    const user = session?.user;
    if (!user || user.role !== 'admin') return { error: 'Unauthorized' };

    const success = await updateLeaveRequestStatusRuntime(employeeId, requestId, 'approved');
    if (success) {
        revalidatePath('/admin/leave-requests');
        return { success: true, message: 'Request approved.' };
    }
    return { error: 'Failed to approve request.' };
}

// Advance Request Action
const advanceRequestSchema = z.object({
  amount: z.coerce.number().min(1, 'Amount must be greater than zero.'),
  reason: z.string().optional(),
});

export async function handleAdvanceRequest(values: z.infer<typeof advanceRequestSchema>) {
    const session = await getSession();
    const user = session?.user;
    if (!user) return { error: 'Unauthorized' };

    const parsed = advanceRequestSchema.safeParse(values);
    if (!parsed.success) {
        return { error: 'Invalid data.' };
    }

    const requestData = {
        requestType: 'advance' as const,
        amount: parsed.data.amount,
        reason: parsed.data.reason || 'Salary Advance',
        from: new Date(),
    };

    const success = await addLeaveRequestRuntime(user.id, requestData);
    
    if (success) {
        revalidatePath('/employee/advance');
        revalidatePath('/admin/leave-requests');
        revalidatePath('/admin/advance-requests');
        return { success: true };
    }

    return { error: 'Failed to submit advance request.' };
}

const scheduleAdvanceDialogSchema = z.object({
  requestId: z.string(),
  monthlyRepayment: z.coerce.number().min(1, "Monthly repayment must be greater than 1."),
  startMonth: z.string(),
  startYear: z.string(),
});

export async function handleApproveAndScheduleAdvance(values: z.infer<typeof scheduleAdvanceDialogSchema>) {
    const session = await getSession();
    const user = session?.user;
    if (!user || user.role !== 'admin') return { error: 'Unauthorized' };

    const parsed = scheduleAdvanceDialogSchema.safeParse(values);
    if (!parsed.success) return { error: 'Invalid data provided.' };
    
    const { requestId, monthlyRepayment, startMonth, startYear } = parsed.data;

    const allEmployees = await getEmployeesRuntime();
    let targetEmployee: Employee | undefined;
    let targetRequest: Omit<LeaveRequest, 'employeeId' | 'employeeName' | 'toEmployeeName'> | undefined;

    for (const emp of allEmployees) {
        const req = emp.leaveRequests.find(r => r.id === requestId);
        if (req) {
            targetEmployee = emp;
            targetRequest = req;
            break;
        }
    }

    if (!targetEmployee || !targetRequest || targetRequest.requestType !== 'advance' || !targetRequest.amount) {
        return { error: 'Request not found or is not a valid advance request.' };
    }

    // 1. Update request status
    targetRequest.status = 'approved';
    
    const advanceAmount = targetRequest.amount;

    // 2. Create disbursement record (shows up as a "bonus" but is semantically an advance)
    const disbursementRecord: FinancialRecord = {
        id: nextPrefixedId('rec-adv'),
        requestId: requestId,
        description: `Approved Advance: ${targetRequest.reason || 'Salary Advance'}`,
        totalAmount: -advanceAmount, // Negative amount to increase net pay
        installments: [{ date: new Date(), amount: -advanceAmount }]
    };
    targetEmployee.financialRecords.push(disbursementRecord);

    // 3. Create repayment schedule as a deduction
    const startDate = new Date(parseInt(startYear), parseInt(startMonth));
    
    const installmentsCount = Math.ceil(advanceAmount / monthlyRepayment);
    const installments: Installment[] = [];
    let remainingAmount = advanceAmount;

    for (let i = 0; i < installmentsCount; i++) {
        let paymentAmount = Math.min(remainingAmount, monthlyRepayment);
        // Ensure the last payment covers the exact remaining amount
        if (i === installmentsCount - 1) {
            paymentAmount = remainingAmount;
        }
        installments.push({
            date: addMonths(startDate, i),
            amount: parseFloat(paymentAmount.toFixed(2)),
        });
        remainingAmount -= paymentAmount;
    }


    const repaymentRecord: FinancialRecord = {
        id: nextPrefixedId('rec-ded'),
        requestId: requestId,
        description: `Salary Advance Repayment`,
        totalAmount: advanceAmount,
        installments,
    };
    targetEmployee.financialRecords.push(repaymentRecord);
    
    // Save all changes to the database file at once
    await saveEmployeesRuntime(allEmployees);

    // Revalidate paths to update UI
    revalidatePath('/admin/advance-requests');
    revalidatePath('/admin/dashboard');
    revalidatePath('/admin/employees');
    revalidatePath('/employee/dashboard');
    revalidatePath('/employee/statement');
    revalidatePath(`/admin/employee/${targetEmployee.id}/statement`);
    revalidatePath(`/admin/employee/${targetEmployee.id}/financials`);

    return { success: true, message: 'Advance approved and scheduled successfully.' };
}


export async function handleRejectLeaveRequest(employeeId: string, requestId: string) {
    const session = await getSession();
    const user = session?.user;
    if (!user || user.role !== 'admin') return { error: 'Unauthorized' };

    const success = await updateLeaveRequestStatusRuntime(employeeId, requestId, 'rejected');
    if (success) {
        revalidatePath('/admin/leave-requests');
        revalidatePath('/admin/advance-requests');
        return { success: true, message: 'Request rejected.' };
    }
    return { error: 'Failed to reject request.' };
}

export async function handleSetLocale(locale: 'en' | 'ar') {
    const cookieStore = await cookies();
    cookieStore.set('NEXT_LOCALE', locale);
  revalidatePath('/');
}

const adminSwapShiftsSchema = z.object({
  date: z.string().min(1, "Date is required"),
  employee1Id: z.string().min(1, "First employee is required"),
  employee2Id: z.string().min(1, "Second employee is required"),
});

export async function handleSwapShifts(values: z.infer<typeof adminSwapShiftsSchema>) {
    const session = await getSession();
    const user = session?.user;
    if (!user || user.role !== 'admin') {
        return { error: 'Unauthorized' };
    }
    
    const parsed = adminSwapShiftsSchema.safeParse(values);
    if (!parsed.success) {
        return { error: 'Invalid data provided.' };
    }

    if (parsed.data.employee1Id === parsed.data.employee2Id) {
        return { error: "Cannot swap an employee with themselves." };
    }

    const success = await swapShiftsRuntime(parseISO(parsed.data.date), parsed.data.employee1Id, parsed.data.employee2Id);
    if (success) {
        revalidatePath('/admin/shifts');
        return { success: true, message: "Shifts swapped successfully." };
    }
    
    return { error: "Failed to swap shifts." };
}

const employeeShiftSwapSchema = z.object({
  shiftDate: z.date(),
  toEmployeeId: z.string().min(1, "Please select an employee to cover your shift."),
  reason: z.string().optional(),
});

export async function handleShiftSwapRequest(values: z.infer<typeof employeeShiftSwapSchema>) {
    const session = await getSession();
    const user = session?.user;
    if (!user) return { error: 'Unauthorized' };

    const parsed = employeeShiftSwapSchema.safeParse(values);
    if (!parsed.success) {
        return { error: 'Invalid data provided.' };
    }
    
    const data = {
        ...parsed.data,
        requestType: 'shift-swap' as const,
        shiftDate: parsed.data.shiftDate,
        toEmployeeId: parsed.data.toEmployeeId,
        reason: parsed.data.reason || 'Shift Cover Request'
    };

    const success = await addLeaveRequestRuntime(user.id, data as RuntimeLeaveRequestData);
    
    if (success) {
        revalidatePath('/employee/shift-swap');
        revalidatePath('/employee/my-tasks');
        revalidatePath('/admin/leave-requests');
        return { success: true };
    }
    return { error: 'Failed to submit shift swap request.' };
}

export async function handleShiftSwapResponse(requestId: string, approved: boolean) {
    const session = await getSession();
    const user = session?.user;
    if (!user) return { error: 'Unauthorized' };
    
    const status = approved ? 'approved' : 'rejected';
    const success = await updateShiftSwapStatusRuntime(requestId, user.id, status);

    if (success) {
        revalidatePath('/employee/my-tasks');
        revalidatePath('/admin/shifts');
        revalidatePath('/admin/leave-requests');
        revalidatePath('/employee/dashboard');
        revalidatePath('/employee/statement');
        revalidatePath('/admin/dashboard');
        revalidatePath('/admin/employees');
        return { success: true, message: `Request ${status}.` };
    }

    return { error: "Failed to process request. You may not be authorized." };
}

export async function handleDeleteFinancialRecord(employeeId: string, recordId: string) {
    const session = await getSession();
    const user = session?.user;
    if (!user || user.role !== 'admin') return { error: 'Unauthorized' };

    const success = await deleteFinancialRecordRuntime(employeeId, recordId);

    if (success) {
        revalidatePath(`/admin/employee/${employeeId}/financials`);
        revalidatePath('/admin/dashboard');
        revalidatePath('/admin/employees');
        revalidatePath('/employee/dashboard');
        revalidatePath('/employee/statement');
        revalidatePath(`/admin/employee/${employeeId}/statement`);
    }

    return success ? { success: true } : { error: 'Failed to delete record.' };
}


export async function handleAutomaticCheckIn() {
    const session = await getSession();
    if (!session?.user) return { success: false, message: 'Unauthorized' };
    
    const employee = await getEmployeeByIdRuntime(session.user.id);
    if (!employee) return { success: false, message: 'Employee not found.' };

    // 1. Check if already checked in
    const today = new Date();
    const dateString = today.toISOString().split('T')[0];
    const alreadyCheckedIn = employee.attendance.some(a => a.date === dateString);
    if (alreadyCheckedIn) {
        return { success: false, message: 'Already checked in for today.' };
    }

    // 2. Check IP Address
    const ip = await getIpAddress();
    const settings = await getSettingsRuntime();
    const approvedIpsString = String(settings?.approvedIpAddress || '');
    if (approvedIpsString && approvedIpsString.trim().length > 0) {
        const allowedIps = approvedIpsString.split(/[\n,]+/).map(ipAddr => ipAddr.trim()).filter(Boolean);
        if (!allowedIps.includes(ip)) {
            return { success: false, message: `Your IP (${ip}) is not approved.` };
        }
    }

    // 3. Check Shift Time
    const currentShift = getShiftForEmployee(employee, today);
    if (currentShift === 'none') {
        return { success: false, message: 'No shift assigned for today.' };
    }

    const shiftStartTime = SHIFT_TIMES[currentShift].start;
    const shiftStartToday = new Date();
    shiftStartToday.setHours(shiftStartTime.hour, shiftStartTime.minute, 0, 0);

    if (today < shiftStartToday) {
        return { success: false, message: 'Your shift has not started yet.' };
    }

    // 4. All checks passed, perform check-in
    const recorded = await recordAttendanceRuntime(session.user.id, new Date().toISOString());

    if (recorded) {
        revalidatePath('/employee/dashboard');
        return { success: true, message: 'You have been automatically checked in.' };
    }

    // This case should not be reached if the "alreadyCheckedIn" check is correct
    return { success: false, message: 'Automatic check-in failed for an unknown reason.' };
}

// Production Report Action
const productionFormSchema = z.object({
    date: z.string(),
    dailySales: z.coerce.number().optional().default(0),
    newDebts: z.array(z.object({ customerName: z.string().min(1), amount: z.coerce.number().min(0.01) })).optional(),
    debtPayments: z.array(z.object({ customerId: z.string(), amount: z.coerce.number().min(0.01) })).optional(),
    consumedMaterials: z.array(z.object({ materialId: z.string(), value: z.coerce.number().min(0.01) })).optional(),
    expenses: z.array(z.object({ expenseId: z.string(), value: z.coerce.number().min(0.01) })).optional(),
    cashboxInventory: z.coerce.number().min(0),
});

export async function handleProductionReportSubmit(values: z.infer<typeof productionFormSchema>) {
    const session = await getSession();
    const user = session?.user;
    if (!user || user.role !== 'admin') return { error: 'Unauthorized' };

    const parsed = productionFormSchema.safeParse(values);
    if (!parsed.success) {
        console.error(parsed.error.flatten());
        return { error: 'Invalid data provided.' };
    }

    const { date, ...data } = parsed.data;

    // --- Update Customer Balances ---
    const customers = await getCustomersRuntime();
    const customerMap = new Map(customers.map(c => [c.id, c]));

    // Handle new debts
    if (data.newDebts) {
        for (const debt of data.newDebts) {
            let customer = customers.find(c => c.name === debt.customerName);
            if (customer) {
                customer.balance += debt.amount;
            } else {
                // Create a new customer if they don't exist
                const numericIds = customers
                    .map((existingCustomer) => Number.parseInt(String(existingCustomer.id || ''), 10))
                    .filter((id) => Number.isFinite(id));
                const newId = String((numericIds.length > 0 ? Math.max(...numericIds) : 0) + 1);
                const newCustomer = {
                    id: newId,
                    customerNumber: newId,
                    name: debt.customerName,
                    balance: debt.amount,
                    category: 'general',
                    phone: '',
                    creditLimit: 0,
                    address: '',
                };
                customers.push(newCustomer);
                customerMap.set(newId, newCustomer);
            }
        }
    }

    // Handle debt payments
    if (data.debtPayments) {
        for (const payment of data.debtPayments) {
            const customer = customerMap.get(payment.customerId);
            if (customer) {
                customer.balance -= payment.amount;
            }
        }
    }
    await saveCustomersRuntime(customers);
    
    // --- Create and Save Report ---
    const reportData: Omit<ProductionReport, 'id'> = {
        date: new Date(date).toISOString(),
        submittedBy: user.name,
        dailySales: data.dailySales,
        newDebts: (data.newDebts || []) as ProductionReport['newDebts'],
        debtPayments: (data.debtPayments || []) as ProductionReport['debtPayments'],
        consumedMaterials: (data.consumedMaterials || []) as ProductionReport['consumedMaterials'],
        expenses: (data.expenses || []) as ProductionReport['expenses'],
        cashboxInventory: data.cashboxInventory,
    };
    
    const savedReport = addProductionReport(reportData);

    try {
        await syncProductionRealEstateExpenseEntries({
            report: savedReport,
            expenses: (data.expenses || []) as Array<{ expenseId: string; value: number }>,
            createdBy: user.name || user.id,
        });
    } catch (error) {
        console.error('Failed to auto-post real-estate expenses from production report:', error);
    }
    
    revalidatePath('/admin/production');
    return { success: true };
}


// List Item Management Actions
const listItemSchema = z.object({
    name: z.string().min(2, "Name must be at least 2 characters."),
});

const expenseItemSchema = z.object({
    name: z.string().min(2, "Name must be at least 2 characters."),
    realEstateProjectId: z.string().optional().default(''),
    realEstateUnitId: z.string().optional().default(''),
    realEstateCostType: z.enum(['general', 'direct-unit', 'shared-project']).optional().default('general'),
    realEstateAllocationMethod: z.enum(['area', 'sale-value', 'manual-share']).optional().default('area'),
});

const itemGroupSchema = z.object({
    name: z.string().min(2, "Name must be at least 2 characters."),
    isPosEnabled: z.coerce.boolean().default(false),
    usesDefaultTax: z.coerce.boolean().optional().default(true),
    taxRate: z.coerce.number().min(0).max(100).optional(),
});

const materialItemSchema = z.object({
    itemNumber: z.string().optional(),
        name: z.string().min(2, "Name must be at least 2 characters."),
    itemCategory: z.enum(['inventory', 'service', 'non_stock', 'bundle']).optional().default('inventory'),
    revenueAccountCode: z.string().optional(),
    inventoryAccountCode: z.string().optional(),
    cogsAccountCode: z.string().optional(),
    purchaseAccountCode: z.string().optional(),
    reorderMinimumQty: z.coerce.number().min(0).optional(),
    itemSymbolName: z.string().optional(),
    globalReferenceNumber: z.string().optional(),
        barcode: z.string().optional(),
    secondaryBarcode: z.string().optional(),
    additionalBarcodes: z.array(z.string().min(1)).optional(),
    groupId: z.string().optional(),
    additionalDetails: z.string().optional(),
    imageUrl: z.string().optional(),
    primaryUnit: z.string().optional(),
        primaryUnitQuantity: z.coerce.number().min(0).optional(),
    secondaryUnit: z.string().optional(),
    secondaryUnitQuantity: z.coerce.number().min(0).optional(),
    secondaryUnitPrice: z.coerce.number().min(0).optional(),
    secondaryUnits: z.array(z.object({
        unit: z.string().optional(),
        barcode: z.string().optional(),
        quantity: z.coerce.number().min(0).optional(),
        price: z.coerce.number().min(0).optional(),
    })).optional(),
    isManufactured: z.coerce.boolean().optional(),
    productionOutputQuantity: z.coerce.number().min(0.0001).optional(),
    productionFormula: z.array(z.object({
        materialId: z.string().min(1),
        quantity: z.coerce.number().min(0.0001),
        unit: z.string().optional(),
        notes: z.string().optional(),
        wastePercent: z.coerce.number().min(0).max(100).optional(),
    })).optional(),
    isDisassemblable: z.coerce.boolean().optional().default(false),
    disassemblyTemplate: z.array(z.object({
        partItemId: z.string().optional(),
        quantity: z.coerce.number().min(0.0001).optional(),
        expectedSalePrice: z.coerce.number().min(0).optional(),
        notes: z.string().optional(),
    })).optional(),
    shelfLifeYears: z.coerce.number().min(0).optional(),
    shelfLifeMonths: z.coerce.number().min(0).optional(),
    shelfLifeDays: z.coerce.number().min(0).optional(),
    storeSectionId: z.string().optional(),
    storeBranchId: z.string().optional(),
    printSectionId: z.string().optional(),
    excludeFromPrepTicket: z.coerce.boolean().optional().default(false),
    printLabelOverride: z.string().optional(),
    realEstateProjectId: z.string().optional().default(''),
    realEstateUnitId: z.string().optional().default(''),
    realEstateCostType: z.enum(['general', 'direct-unit', 'shared-project']).optional().default('general'),
    realEstateAllocationMethod: z.enum(['area', 'sale-value', 'manual-share']).optional().default('area'),
    alternativeItemIds: z.array(z.string()).optional(),
    isWeighed: z.coerce.boolean().optional(),
    isSized: z.coerce.boolean().optional(),
        purchasePrice: z.coerce.number().min(0).optional(),
        salePrice: z.preprocess(
            (value) => {
                if (value === '' || value === null || value === undefined) return undefined;
                const parsed = Number(value);
                return Number.isFinite(parsed) ? parsed : undefined;
            },
                z.number().min(0).optional(),
        ),
    categoryPrices: z.record(z.coerce.number().min(0)).optional(),
    allowDescriptionEdit: z.coerce.boolean().optional(),
    hasSerialNumber: z.coerce.boolean().optional().default(false),
    hasRfid: z.coerce.boolean().optional().default(false),
    usesDefaultTax: z.coerce.boolean().optional().default(true),
    taxRate: z.coerce.number().min(0).max(100).optional(),
    enableProfitMargin: z.coerce.boolean().optional().default(false),
    profitMargin: z.coerce.number().min(0).max(1000).optional(),
    usesProductShapes: z.coerce.boolean().optional().default(false),
    productShapeType: z.string().optional(),
    productShapes: z.array(z.object({
        id: z.string().optional(),
        name: z.string().optional(),
        salePrice: z.coerce.number().min(0),
        costPrice: z.coerce.number().min(0).optional(),
        type: z.string().optional(),
        isActive: z.coerce.boolean().optional(),
    })).optional(),
}).refine((data) => {
    const primaryQty = Number.isFinite(data.primaryUnitQuantity as number) ? (data.primaryUnitQuantity as number) : undefined;

    const candidateSecondaryUnits = (Array.isArray(data.secondaryUnits) && data.secondaryUnits.length > 0)
        ? data.secondaryUnits
        : [{ unit: data.secondaryUnit, quantity: data.secondaryUnitQuantity }];

    for (const entry of candidateSecondaryUnits) {
        const unit = String(entry?.unit || '').trim();
        if (!unit) continue;
        if (data.primaryUnit && unit === data.primaryUnit) return false;

        const secondaryQty = Number.isFinite(entry?.quantity as number) ? (entry?.quantity as number) : undefined;
        if (typeof primaryQty === 'number' && primaryQty > 0 && typeof secondaryQty === 'number' && secondaryQty > 0) {
            if (secondaryQty <= primaryQty) return false;
        }
    }

    return true;
}, { message: 'Invalid unit quantities or duplicate units.' }).superRefine((data, ctx) => {
    const purchasePrice = typeof data.purchasePrice === 'number' && Number.isFinite(data.purchasePrice)
        ? data.purchasePrice
        : undefined;

    const normalizeCode = (value: unknown) => String(value || '').trim();
    const seenCodes = new Set<string>();
    const addLocalCode = (code: string, path: (string | number)[]) => {
        if (!code) return;
        if (seenCodes.has(code)) {
            ctx.addIssue({
                code: z.ZodIssueCode.custom,
                message: 'Barcode value must be unique within the same item.',
                path,
            });
            return;
        }
        seenCodes.add(code);
    };

    addLocalCode(normalizeCode(data.barcode), ['barcode']);
    addLocalCode(normalizeCode(data.secondaryBarcode), ['secondaryBarcode']);

    (Array.isArray(data.additionalBarcodes) ? data.additionalBarcodes : []).forEach((code, index) => {
        addLocalCode(normalizeCode(code), ['additionalBarcodes', index]);
    });

    (Array.isArray(data.secondaryUnits) ? data.secondaryUnits : []).forEach((entry, index) => {
        addLocalCode(normalizeCode(entry?.barcode), ['secondaryUnits', index, 'barcode']);
    });
});

function normalizeAlternativeMaterialIds(values: unknown, currentId?: string): string[] {
    const normalizedCurrentId = String(currentId || '').trim();
    return Array.from(new Set((Array.isArray(values) ? values : [])
        .map((entry) => String(entry || '').trim())
        .filter((entry) => entry.length > 0 && entry !== normalizedCurrentId)));
}

function normalizeMaterialUnitPayload(values: Record<string, unknown>) {
    const normalizedValues = { ...values } as Record<string, unknown>;
    const primaryUnit = String(normalizedValues.primaryUnit || '').trim();
    normalizedValues.primaryUnit = primaryUnit || undefined;

    const primaryUnitQuantityValue = normalizedValues.primaryUnitQuantity;
    const primaryUnitQuantity = primaryUnitQuantityValue === '' || primaryUnitQuantityValue === undefined || primaryUnitQuantityValue === null
        ? undefined
        : Number(primaryUnitQuantityValue);

    if (!primaryUnit) {
        delete normalizedValues.primaryUnitQuantity;
    } else if (Number.isFinite(primaryUnitQuantity) && primaryUnitQuantity > 0) {
        normalizedValues.primaryUnitQuantity = primaryUnitQuantity;
    } else {
        normalizedValues.primaryUnitQuantity = 1;
    }

    const normalizedSecondaryUnits = (Array.isArray(normalizedValues.secondaryUnits) ? normalizedValues.secondaryUnits : [])
        .map((entry: any) => {
            const unit = String(entry?.unit || '').trim();
            const barcode = String(entry?.barcode || '').trim();
            const quantity = entry?.quantity === '' || entry?.quantity === undefined || entry?.quantity === null ? undefined : Number(entry.quantity);
            const price = entry?.price === '' || entry?.price === undefined || entry?.price === null ? undefined : Number(entry.price);
            return {
                unit,
                barcode,
                quantity: Number.isFinite(quantity) ? quantity : undefined,
                price: Number.isFinite(price) ? price : undefined,
            };
        })
        .filter((entry) => entry.unit || entry.barcode || typeof entry.quantity === 'number' || typeof entry.price === 'number');

    const legacySecondaryUnit = String(normalizedValues.secondaryUnit || '').trim();
    const legacySecondaryBarcode = String(normalizedValues.secondaryBarcode || '').trim();
    const legacySecondaryQuantityValue = normalizedValues.secondaryUnitQuantity;
    const legacySecondaryQuantity = legacySecondaryQuantityValue === '' || legacySecondaryQuantityValue === undefined || legacySecondaryQuantityValue === null
        ? undefined
        : Number(legacySecondaryQuantityValue);
    const legacySecondaryPriceValue = normalizedValues.secondaryUnitPrice;
    const legacySecondaryPrice = legacySecondaryPriceValue === '' || legacySecondaryPriceValue === undefined || legacySecondaryPriceValue === null
        ? undefined
        : Number(legacySecondaryPriceValue);

    if (normalizedSecondaryUnits.length === 0 && (legacySecondaryUnit || legacySecondaryBarcode || Number.isFinite(legacySecondaryQuantity) || Number.isFinite(legacySecondaryPrice))) {
        normalizedSecondaryUnits.push({
            unit: legacySecondaryUnit,
            barcode: legacySecondaryBarcode,
            quantity: Number.isFinite(legacySecondaryQuantity) ? legacySecondaryQuantity : undefined,
            price: Number.isFinite(legacySecondaryPrice) ? legacySecondaryPrice : undefined,
        });
    }

    if (normalizedSecondaryUnits.length > 0) {
        normalizedValues.secondaryUnits = normalizedSecondaryUnits;
        normalizedValues.secondaryUnit = normalizedSecondaryUnits[0].unit || undefined;
        normalizedValues.secondaryBarcode = normalizedSecondaryUnits[0].barcode || undefined;
        normalizedValues.secondaryUnitQuantity = typeof normalizedSecondaryUnits[0].quantity === 'number' ? normalizedSecondaryUnits[0].quantity : undefined;
        normalizedValues.secondaryUnitPrice = typeof normalizedSecondaryUnits[0].price === 'number' ? normalizedSecondaryUnits[0].price : undefined;
    } else {
        delete normalizedValues.secondaryUnits;
        delete normalizedValues.secondaryUnit;
        delete normalizedValues.secondaryBarcode;
        delete normalizedValues.secondaryUnitQuantity;
        delete normalizedValues.secondaryUnitPrice;
    }

    return normalizedValues;
}

async function syncMaterialAlternativesBidirectional(params: {
    materialId: string;
    nextAlternativeIds?: unknown;
    previousAlternativeIds?: unknown;
}) {
    const materialId = String(params.materialId || '').trim();
    if (!materialId) return;

    const nextAlternativeIds = normalizeAlternativeMaterialIds(params.nextAlternativeIds, materialId);
    const previousAlternativeIds = normalizeAlternativeMaterialIds(params.previousAlternativeIds, materialId);
    const removedIds = previousAlternativeIds.filter((entry) => !nextAlternativeIds.includes(entry));
    const addedIds = nextAlternativeIds.filter((entry) => !previousAlternativeIds.includes(entry));

    if (isPostgresProviderEnabled()) {
        for (const targetId of removedIds) {
            const target = await pgGetMaterialById(targetId);
            if (!target) continue;
            const targetAlternatives = normalizeAlternativeMaterialIds((target as any).alternativeItemIds, targetId)
                .filter((entry) => entry !== materialId);
            await pgUpdateMaterial(targetId, {
                alternativeItemIds: targetAlternatives,
            });
        }

        for (const targetId of addedIds) {
            const target = await pgGetMaterialById(targetId);
            if (!target) continue;
            const targetAlternatives = normalizeAlternativeMaterialIds((target as any).alternativeItemIds, targetId);
            if (!targetAlternatives.includes(materialId)) {
                await pgUpdateMaterial(targetId, {
                    alternativeItemIds: [...targetAlternatives, materialId],
                });
            }
        }

        return;
    }

    const materials = getMaterials();
    const materialsById = new Map(materials.map((entry) => [String(entry.id || '').trim(), entry]));

    for (const targetId of removedIds) {
        const target = materialsById.get(targetId);
        if (!target) continue;
        const targetAlternatives = normalizeAlternativeMaterialIds((target as any).alternativeItemIds, targetId)
            .filter((entry) => entry !== materialId);
        updateMaterial(targetId, { alternativeItemIds: targetAlternatives });
    }

    for (const targetId of addedIds) {
        const target = materialsById.get(targetId);
        if (!target) continue;
        const targetAlternatives = normalizeAlternativeMaterialIds((target as any).alternativeItemIds, targetId);
        if (!targetAlternatives.includes(materialId)) {
            updateMaterial(targetId, { alternativeItemIds: [...targetAlternatives, materialId] });
        }
    }
}

const customerItemSchema = z.object({
    customerNumber: z.string().optional(),
    name: z.string().min(2, "Name must be at least 2 characters."),
    category: z.string().min(1, "Category is required."),
    accountCode: z.string().optional(),
    phone: z.string().optional(),
    creditLimit: z.coerce.number().min(0).optional(),
    address: z.string().optional(),
    allowedDiscount: z.coerce.number().min(0).max(100).optional(),
    salesRepId: z.string().optional(),
});

const supplierItemSchema = z.object({
    supplierNumber: z.string().optional(),
    name: z.string().min(2, "Name must be at least 2 characters."),
    accountCode: z.string().optional(),
    phone: z.string().optional(),
    address: z.string().optional(),
    paymentTerms: z.coerce.number().min(0).optional(),
    taxNumber: z.string().optional(),
});

const salesRepItemSchema = z.object({
    name: z.string().min(2, "Name must be at least 2 characters."),
    phone: z.string().optional(),
    region: z.string().optional(),
    commissionRate: z.coerce.number().min(0).max(100).optional(),
});

const unitItemSchema = z.object({
    description: z.string().min(1, 'Unit description is required.'),
    unitNumber: z.string().optional(),
    shortCode: z.string().optional(),
    notes: z.string().optional(),
});

function buildValidationFailure(error: z.ZodError) {
    const flattened = error.flatten();
    const firstIssue = error.issues[0];
    const validationSummary = firstIssue
        ? `${firstIssue.path.join('.') || 'form'}: ${firstIssue.message}`
        : undefined;

    return {
        error: 'Invalid data',
        details: flattened,
        validationErrors: flattened.fieldErrors,
        formErrors: flattened.formErrors,
        validationSummary,
    };
}

const warehouseSchema = z.object({
    name: z.string().min(2, 'Warehouse name is required.'),
    branchName: z.string().trim().optional().default(''),
    departments: z.array(z.string().trim().min(1)).optional().default([]),
    warehouseType: z.enum(['main', 'branch', 'returns', 'transit']).optional().default('branch'),
    managerEmployeeId: z.string().trim().optional().default(''),
    managerName: z.string().trim().optional().default(''),
    operatingStatus: z.enum(['active', 'stopped', 'inventory']).optional().default('active'),
    city: z.string().trim().optional().default(''),
    address: z.string().trim().optional().default(''),
    contactPhone: z.string().trim().optional().default(''),
    allowIssueWithoutStock: z.coerce.boolean().optional().default(false),
    useInPos: z.coerce.boolean().optional().default(true),
    location: z.string().trim().optional().default(''),
    notes: z.string().trim().optional().default(''),
});

async function resolveWarehouseManagerNameRuntime(managerEmployeeId: string, fallbackName?: string): Promise<string> {
    const normalizedId = String(managerEmployeeId || '').trim();
    if (!normalizedId) return String(fallbackName || '').trim();

    const employees = isPostgresProviderEnabled()
        ? (((await pgGetEmployees({ page: 1, pageSize: 10000 })).items || []) as Array<Record<string, any>>)
        : (getEmployees() as Array<Record<string, any>>);

    const matched = employees.find((employee) => String(employee?.id || '').trim() === normalizedId);
    return String(matched?.name || fallbackName || '').trim();
}

const shelfSchema = z.object({
    name: z.string().min(1, 'Shelf name is required.'),
    notes: z.string().trim().optional().default(''),
});

const shelvesSchema = z.object({
    prefix: z.string().optional(),
    separator: z.string().optional(),
    startNumber: z.coerce.number().int().min(0).optional(),
    count: z.coerce.number().int().min(1).max(500),
});

async function mutateWarehousePostgres(
    warehouseId: string,
    mutate: (warehouse: Record<string, any>) => Record<string, any> | Promise<Record<string, any>>,
): Promise<Record<string, any> | null> {
    await pgQuery('BEGIN');
    try {
        const current = await pgQuery<{ raw: Record<string, any> }>('SELECT raw FROM warehouses WHERE id = $1 FOR UPDATE', [warehouseId]);
        if (!current.rowCount) {
            await pgQuery('ROLLBACK');
            return null;
        }

        const next = await mutate(current.rows[0].raw || {});
        const shelves = Array.isArray(next.shelves) ? next.shelves : [];
        await pgQuery(
            `
            UPDATE warehouses
            SET name = $2, shelves = $3::jsonb, raw = $4::jsonb, updated_at = NOW()
            WHERE id = $1
            `,
            [
                warehouseId,
                String(next.name || ''),
                JSON.stringify(shelves),
                JSON.stringify({ ...next, id: warehouseId, shelves }),
            ]
        );
        await pgQuery('COMMIT');
        return { ...next, id: warehouseId, shelves };
    } catch (error) {
        await pgQuery('ROLLBACK');
        throw error;
    }
}

export async function handleAddBarcodeItem(itemName: string, barcode: string, salePrice: number) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    try {
        // Generate item number based on current items
        const materials = getMaterials();
        const lastItemNumber = Math.max(...materials.map(m => {
            const num = parseInt(m.itemNumber);
            return isNaN(num) ? 0 : num;
        }), 0);
        
        const itemNumber = String(lastItemNumber + 1);
        
        // Add the new material with barcode
        addMaterial({
            itemNumber,
            name: itemName,
            barcode,
            salePrice,
            purchasePrice: 0,
        });
        
        revalidatePath('/admin/data/materials');
        return { success: true, itemNumber };
    } catch (e: any) {
        return { error: e?.message || 'Failed to add item.' };
    }
}

function collectMaterialUnitDescriptions(values: any): string[] {
    const descriptions = new Set<string>();
    const primary = String(values?.primaryUnit || '').trim();
    if (primary) descriptions.add(primary);

    const legacySecondary = String(values?.secondaryUnit || '').trim();
    if (legacySecondary) descriptions.add(legacySecondary);

    const rows = Array.isArray(values?.secondaryUnits) ? values.secondaryUnits : [];
    rows.forEach((row: any) => {
        const unit = String(row?.unit || '').trim();
        if (unit) descriptions.add(unit);
    });

    return Array.from(descriptions);
}

async function getItemGroupsForTaxCalc(): Promise<Array<{ id: string; taxRate?: number; usesDefaultTax?: boolean }>> {
    if (isPostgresProviderEnabled()) {
        const result = await pgGetItemGroups({ page: 1, pageSize: 5000 });
        return (result.items || []) as Array<{ id: string; taxRate?: number; usesDefaultTax?: boolean }>;
    }
    const { getItemGroups } = await import('./data');
    return getItemGroups() as Array<{ id: string; taxRate?: number; usesDefaultTax?: boolean }>;
}

async function getCustomerPricingForCalc(): Promise<CustomerPricing[]> {
    if (isPostgresProviderEnabled()) {
        const result = await pgGetCustomerPricing({ page: 1, pageSize: 5000 });
        return (result.items || []) as CustomerPricing[];
    }
    return getCustomerPricing();
}

async function getBankByIdForCalc(id: string): Promise<any | null> {
    if (!id) return null;
    if (isPostgresProviderEnabled()) {
        const bank = await pgGetBankById(id);
        if (bank) return bank;
        return await pgGetGeneralBankById(id);
    }
    const bank = getBankById(id);
    if (bank) return bank;
    const dataModule = await import('./data');
    return dataModule.getGeneralBankById(id);
}

async function getCustomerCategoriesForCalc(): Promise<CustomerCategory[]> {
    if (isPostgresProviderEnabled()) {
        const result = await pgGetCustomerCategories({ page: 1, pageSize: 5000 });
        return (result.items || []) as CustomerCategory[];
    }
    return getCustomerCategories() as CustomerCategory[];
}

async function ensureManagedUnitRuntime(description: string) {
    const normalizedDescription = String(description || '').trim().replace(/\s+/g, ' ');
    if (!normalizedDescription) return null;

    if (isPostgresProviderEnabled()) {
        const result = await pgGetManagedUnits({ page: 1, pageSize: 5000 });
        const units = (result.items || []) as Array<Record<string, unknown>>;
        const existing = units.find(
            (unit) => String(unit.description || '').trim().replace(/\s+/g, ' ').toLowerCase() === normalizedDescription.toLowerCase()
        );
        if (existing) {
            return existing;
        }

        try {
            return await pgCreateManagedUnit({
                id: nextPrefixedId('munit'),
                unitNumber: String(await pgNextNamedSequence('managed-unit-ref')),
                description: normalizedDescription,
                shortCode: '',
                notes: '',
            });
        } catch (error: any) {
            if (error?.code === '23505') {
                const retry = await pgGetManagedUnits({ page: 1, pageSize: 5000 });
                const duplicate = (retry.items || []).find(
                    (unit) => String((unit as any).description || '').trim().replace(/\s+/g, ' ').toLowerCase() === normalizedDescription.toLowerCase()
                );
                if (duplicate) return duplicate as Record<string, unknown>;
            }
            throw error;
        }
    }

    return ensureManagedUnit(normalizedDescription);
}

export async function handleAddListItem(itemType: 'material' | 'expense' | 'product-shape' | 'customer' | 'supplier' | 'sales-rep' | 'unit', values: any) {
    const session = await getSession();
    const role = session?.user?.role;
    const canAddMaterial = itemType === 'material' && role === 'pos';
    if (!session?.user || (role !== 'admin' && !canAddMaterial)) return { error: 'Unauthorized' };

    let revalidationPath = '';
    let item = null;
    
    if (itemType === 'material') {
        const parsed = materialItemSchema.safeParse(values);
        if (!parsed.success) return buildValidationFailure(parsed.error);
        try {
            for (const unitDescription of collectMaterialUnitDescriptions(parsed.data)) {
                await ensureManagedUnitRuntime(unitDescription);
            }
            if (isPostgresProviderEnabled()) {
                const normalized = normalizeMaterialUnitPayload(parsed.data as any) as any;
                const nowId = String(normalized.id || normalized.itemNumber || nextPrefixedId('mat'));
                item = await pgCreateMaterial({
                    ...normalized,
                    id: nowId,
                    itemNumber: String(normalized.itemNumber || nowId),
                });
                await syncMaterialAlternativesBidirectional({
                    materialId: nowId,
                    nextAlternativeIds: normalized.alternativeItemIds,
                });
            } else {
                const normalized = normalizeMaterialUnitPayload(parsed.data as any) as any;
                item = addMaterial(normalized);
                const createdId = String((item as any)?.id || (parsed.data as any)?.itemNumber || '').trim();
                await syncMaterialAlternativesBidirectional({
                    materialId: createdId,
                    nextAlternativeIds: normalized.alternativeItemIds,
                });
            }
        } catch (e: any) {
            return { error: e?.message || 'Failed to add item.' };
        }
        revalidationPath = '/admin/data/materials';
    } else if (itemType === 'expense') {
        const parsed = expenseItemSchema.safeParse(values);
        if (!parsed.success) return buildValidationFailure(parsed.error);
        const expenseAccountCode = await ensureEntitySubAccountCodeRuntime({
            explicitAccountCode: String((values as any)?.accountCode || '').trim(),
            reservedParentCodes: ['5110'],
            entityName: parsed.data.name,
            parentCode: '5110',
            parentNameAr: 'مصروفات التشغيل',
            parentNameEn: 'Operating Expenses',
            parentParentCode: '5000',
            nature: 'debit',
            sequenceKey: 'coa-expense-sub',
        });
        if (isPostgresProviderEnabled()) {
            const id = String(values?.id || values?.itemNumber || nextPrefixedId('exp'));
            item = await pgCreateExpense({
                id,
                itemNumber: String(values?.itemNumber || id),
                name: parsed.data.name,
                salePrice: 0,
                categoryPrices: {},
                accountCode: expenseAccountCode,
                realEstateProjectId: parsed.data.realEstateProjectId || undefined,
                realEstateUnitId: parsed.data.realEstateUnitId || undefined,
                realEstateCostType: parsed.data.realEstateCostType || 'general',
                realEstateAllocationMethod: parsed.data.realEstateAllocationMethod || 'area',
            });
        } else {
            item = addExpense({ ...(parsed.data as any), accountCode: expenseAccountCode });
        }
        revalidationPath = '/admin/data/expenses';
    } else if (itemType === 'product-shape') {
        const parsed = listItemSchema.safeParse(values);
        if (!parsed.success) return buildValidationFailure(parsed.error);
        try {
            if (isPostgresProviderEnabled()) {
                const seqNum = await pgNextNamedSequence('shape-ref');
                const shapeNumber = `PSH-${String(seqNum).padStart(4, '0')}`;
                item = await pgCreateProductShapeDefinition({
                    id: shapeNumber,
                    itemNumber: shapeNumber,
                    name: parsed.data.name,
                    salePrice: 0,
                    categoryPrices: {},
                });
            } else {
                item = addProductShapeDefinition(parsed.data.name);
            }
        } catch (e: any) {
            const msg = String(e?.message || '');
            const isdup = e?.code === '23505' || msg.includes('موجود مسبقاً') || msg.includes('already exists') || msg.includes('unique');
            if (isdup) return { error: 'شكل/حجم بهذا الاسم موجود مسبقاً' };
            return { error: msg || 'تعذر إضافة الشكل' };
        }
        revalidationPath = '/admin/data/product-shapes';
    } else if (itemType === 'customer') {
        const parsed = customerItemSchema.safeParse(values);
        if (!parsed.success) return buildValidationFailure(parsed.error);
        const customerAccountCode = await ensureEntitySubAccountCodeRuntime({
            explicitAccountCode: parsed.data.accountCode,
            reservedParentCodes: ['1130'],
            entityName: parsed.data.name,
            parentCode: '1130',
            parentNameAr: 'العملاء',
            parentNameEn: 'Customers',
            parentParentCode: '1100',
            nature: 'debit',
            sequenceKey: 'coa-customer-sub',
        });
        if (isPostgresProviderEnabled()) {
            const id = String(parsed.data.customerNumber || nextPrefixedId('cus'));
            item = await pgCreateCustomer({
                id,
                customerNumber: parsed.data.customerNumber || id,
                name: parsed.data.name,
                category: parsed.data.category,
                accountCode: customerAccountCode,
                phone: parsed.data.phone,
                creditLimit: parsed.data.creditLimit,
                address: parsed.data.address,
                allowedDiscount: parsed.data.allowedDiscount || 0,
                salesRepId: parsed.data.salesRepId,
                balance: 0,
            });
        } else {
            item = addCustomer({
                name: parsed.data.name,
                category: parsed.data.category,
                accountCode: customerAccountCode,
                phone: parsed.data.phone,
                creditLimit: parsed.data.creditLimit,
                address: parsed.data.address,
                customerNumber: parsed.data.customerNumber,
                salesRepId: parsed.data.salesRepId,
            });
        }
        revalidationPath = '/admin/data/customers';
    } else if (itemType === 'supplier') {
        const parsed = supplierItemSchema.safeParse(values);
        if (!parsed.success) return buildValidationFailure(parsed.error);
        const supplierNumber = parsed.data.supplierNumber || '';
        const accountCode = await ensureEntitySubAccountCodeRuntime({
            explicitAccountCode: parsed.data.accountCode,
            reservedParentCodes: ['2110', '2111'],
            entityName: parsed.data.name,
            parentCode: '2111',
            parentNameAr: 'الموردون',
            parentNameEn: 'Suppliers',
            parentParentCode: '2100',
            nature: 'credit',
            sequenceKey: 'coa-supplier-sub',
        });
        
        if (isPostgresProviderEnabled()) {
            const id = String(supplierNumber || nextPrefixedId('sup'));
            item = await pgCreateSupplier({
                id,
                supplierNumber: supplierNumber || id,
                name: parsed.data.name,
                phone: parsed.data.phone,
                address: parsed.data.address,
                paymentTerms: parsed.data.paymentTerms,
                taxNumber: parsed.data.taxNumber,
                balance: 0,
                inactive: false,
                accountCode,
            });
        } else {
            item = addSupplier({
                name: parsed.data.name,
                phone: parsed.data.phone,
                address: parsed.data.address,
                paymentTerms: parsed.data.paymentTerms,
                supplierNumber,
                taxNumber: parsed.data.taxNumber,
                accountCode,
            });
        }
        revalidationPath = '/admin/data/suppliers';
    } else if (itemType === 'sales-rep') {
        const parsed = salesRepItemSchema.safeParse(values);
        if (!parsed.success) return buildValidationFailure(parsed.error);
        if (isPostgresProviderEnabled()) {
            const id = String(values?.id || nextPrefixedId('srep'));
            item = await pgCreateSalesRep({
                id,
                name: parsed.data.name,
                phone: parsed.data.phone,
                region: parsed.data.region,
                commissionRate: typeof parsed.data.commissionRate === 'number' ? parsed.data.commissionRate : 0,
            });
        } else {
            item = addSalesRep({
                name: parsed.data.name,
                phone: parsed.data.phone,
                region: parsed.data.region,
                commissionRate: parsed.data.commissionRate,
            });
        }
        revalidationPath = '/admin/data/sales-reps';
    } else if (itemType === 'unit') {
        const parsed = unitItemSchema.safeParse(values);
        if (!parsed.success) return buildValidationFailure(parsed.error);
        let record: any;
        try {
            if (isPostgresProviderEnabled()) {
                record = await pgCreateManagedUnit({
                    id: String(values?.id || nextPrefixedId('munit')),
                    unitNumber: String(await pgNextNamedSequence('managed-unit-ref')),
                    description: parsed.data.description,
                    shortCode: parsed.data.shortCode || '',
                    notes: parsed.data.notes || '',
                });
            } else {
                record = addManagedUnit({ description: parsed.data.description, shortCode: parsed.data.shortCode || '', notes: parsed.data.notes || '' });
            }
        } catch (error: any) {
            if (error?.code === '23505') {
                return { error: 'وحدة بهذا الوصف أو الرقم موجودة مسبقاً.' };
            }
            return { error: error?.message || 'Failed to add unit.' };
        }
        item = {
            ...record,
            name: record.description,
        };
        revalidationPath = '/admin/data/units';
    }
    
    if (revalidationPath) {
        revalidatePath(revalidationPath);
        if (itemType === 'customer' || itemType === 'supplier') {
            revalidatePath('/admin/data/parties');
        }
        if (itemType === 'product-shape') {
            revalidatePath('/admin/data/materials');
        }
        if (itemType === 'material') {
            revalidatePath('/admin/sales');
            revalidatePath('/admin/sales/pos');
        }
    }
    
    return { success: true, item };
}

export async function handleAddItemGroup(values: z.infer<typeof itemGroupSchema>) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const parsed = itemGroupSchema.safeParse(values);
    if (!parsed.success) return { error: 'Invalid data', details: parsed.error.flatten() };

    let group: any;
    if (isPostgresProviderEnabled()) {
        group = await pgCreateItemGroup({
            id: nextPrefixedId('grp'),
            name: parsed.data.name,
            isPosEnabled: parsed.data.isPosEnabled,
            usesDefaultTax: parsed.data.usesDefaultTax,
            taxRate: parsed.data.taxRate,
        });
    } else {
        group = addItemGroup(parsed.data as { name: string; isPosEnabled: boolean; usesDefaultTax?: boolean; taxRate?: number });
    }
    revalidatePath('/admin/data/item-groups');
    revalidatePath('/admin/sales/pos');
    return { success: true, item: group };
}

export async function handleAddWarehouse(values: z.infer<typeof warehouseSchema>) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const parsed = warehouseSchema.safeParse(values);
    if (!parsed.success) return { error: 'Invalid data', details: parsed.error.flatten() };

    try {
        const managerName = await resolveWarehouseManagerNameRuntime(parsed.data.managerEmployeeId || '', parsed.data.managerName || '');
        const normalizedBranch = String(parsed.data.branchName || '').trim().toLowerCase();
        const normalizedName = String(parsed.data.name || '').trim().toLowerCase();

        let item: any;
        if (isPostgresProviderEnabled()) {
            const existing = await pgQuery<{ id: string }>(
                `
                SELECT id
                FROM warehouses
                WHERE LOWER(name) = $1
                  AND LOWER(COALESCE(NULLIF(TRIM(raw->>'branchName'), ''), '')) = $2
                LIMIT 1
                `,
                [normalizedName, normalizedBranch]
            );
            if ((existing.rowCount || 0) > 0) {
                return { error: 'Warehouse already exists in this branch' };
            }

            const warehouseNumber = `WH-${String(await pgNextNamedSequence('warehouse-ref')).padStart(4, '0')}`;
            item = await pgCreateWarehouse({
                id: nextPrefixedId('wh'),
                name: parsed.data.name,
                warehouseNumber,
                branchName: parsed.data.branchName || '',
                departments: (parsed.data.departments || []).map((entry) => String(entry || '').trim()).filter(Boolean),
                warehouseType: parsed.data.warehouseType || 'branch',
                managerEmployeeId: parsed.data.managerEmployeeId || '',
                managerName,
                operatingStatus: parsed.data.operatingStatus || 'active',
                city: parsed.data.city || '',
                address: parsed.data.address || '',
                contactPhone: parsed.data.contactPhone || '',
                allowIssueWithoutStock: parsed.data.allowIssueWithoutStock === true,
                useInPos: parsed.data.useInPos !== false,
                location: parsed.data.location || '',
                notes: parsed.data.notes || '',
                inactive: (parsed.data.operatingStatus || 'active') !== 'active',
                shelves: [],
            });
        } else {
            item = addWarehouse({
                ...parsed.data,
                managerName,
            } as {
                name: string;
                branchName?: string;
                departments?: string[];
                warehouseType?: 'main' | 'branch' | 'returns' | 'transit';
                managerEmployeeId?: string;
                managerName?: string;
                operatingStatus?: 'active' | 'stopped' | 'inventory';
                city?: string;
                address?: string;
                contactPhone?: string;
                allowIssueWithoutStock?: boolean;
                useInPos?: boolean;
                location?: string;
                notes?: string;
            });
        }
        revalidatePath('/admin/data/materials');
        revalidatePath('/admin/data/warehouses');
        revalidatePath('/admin/general-settings');
        return { success: true, item };
    } catch (e: any) {
        if (e?.code === '23505') {
            return { error: 'Warehouse already exists in this branch' };
        }
        return { error: e?.message || 'Failed to add warehouse.' };
    }
}

export async function handleUpdateWarehouse(id: string, values: z.infer<typeof warehouseSchema>) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const parsed = warehouseSchema.safeParse(values);
    if (!parsed.success) return { error: 'Invalid data', details: parsed.error.flatten() };

    try {
        const managerName = await resolveWarehouseManagerNameRuntime(parsed.data.managerEmployeeId || '', parsed.data.managerName || '');
        const normalizedBranch = String(parsed.data.branchName || '').trim().toLowerCase();
        const normalizedName = String(parsed.data.name || '').trim().toLowerCase();

        let item: any = null;
        if (isPostgresProviderEnabled()) {
            const existing = await pgQuery<{ id: string }>(
                `
                SELECT id
                FROM warehouses
                WHERE id <> $1
                  AND LOWER(name) = $2
                  AND LOWER(COALESCE(NULLIF(TRIM(raw->>'branchName'), ''), '')) = $3
                LIMIT 1
                `,
                [id, normalizedName, normalizedBranch]
            );
            if ((existing.rowCount || 0) > 0) {
                return { error: 'Warehouse already exists in this branch' };
            }

            item = await mutateWarehousePostgres(id, (current) => ({
                ...current,
                id,
                warehouseNumber: String(current.warehouseNumber || '').trim(),
                name: parsed.data.name,
                branchName: parsed.data.branchName || '',
                departments: (parsed.data.departments || []).map((entry) => String(entry || '').trim()).filter(Boolean),
                warehouseType: parsed.data.warehouseType || 'branch',
                managerEmployeeId: parsed.data.managerEmployeeId || '',
                managerName,
                operatingStatus: parsed.data.operatingStatus || 'active',
                city: parsed.data.city || '',
                address: parsed.data.address || '',
                contactPhone: parsed.data.contactPhone || '',
                allowIssueWithoutStock: parsed.data.allowIssueWithoutStock === true,
                useInPos: parsed.data.useInPos !== false,
                location: parsed.data.location || '',
                notes: parsed.data.notes || '',
                inactive: (parsed.data.operatingStatus || 'active') !== 'active',
                shelves: Array.isArray(current.shelves) ? current.shelves : [],
            }));
        } else {
            item = updateWarehouseData(id, {
                ...parsed.data,
                managerName,
            });
        }

        if (!item) return { error: 'Warehouse not found.' };
        revalidatePath('/admin/data/warehouses');
        revalidatePath('/admin/data/materials');
        return { success: true, item };
    } catch (e: any) {
        if (e?.code === '23505') {
            return { error: 'Warehouse already exists in this branch' };
        }
        return { error: e?.message || 'Failed to update warehouse.' };
    }
}

export async function handleDeleteWarehouse(id: string) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    try {
        if (isPostgresProviderEnabled()) {
            const warehouseRow = await pgQuery<{ raw: Record<string, any> }>('SELECT raw FROM warehouses WHERE id = $1 LIMIT 1', [id]);
            const current = warehouseRow.rows[0]?.raw || null;
            const shelves = Array.isArray(current?.shelves) ? current.shelves : [];
            if (shelves.length > 0) {
                return { error: 'Cannot delete warehouse that still has shelves' };
            }
        } else {
            const current = getWarehouses().find((entry) => entry.id === id);
            if ((current?.shelves || []).length > 0) {
                return { error: 'Cannot delete warehouse that still has shelves' };
            }
        }

        const usageMessage = await findWarehouseOrShelfUsageRuntime({ warehouseId: id });
        if (usageMessage) {
            return { error: usageMessage };
        }
        const success = isPostgresProviderEnabled()
            ? await pgDeleteWarehouse(id)
            : deleteWarehouseData(id);
        if (!success) return { error: 'Warehouse not found.' };
        revalidatePath('/admin/data/warehouses');
        revalidatePath('/admin/data/materials');
        return { success: true };
    } catch (e: any) {
        return { error: e?.message || 'Failed to delete warehouse.' };
    }
}

export async function handleAddShelf(warehouseId: string, values: z.infer<typeof shelfSchema>) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const parsed = shelfSchema.safeParse(values);
    if (!parsed.success) return { error: 'Invalid data', details: parsed.error.flatten() };

    try {
        let shelf: any = null;
        if (isPostgresProviderEnabled()) {
            const shelfNumber = `SH-${String(await pgNextNamedSequence('shelf-ref')).padStart(5, '0')}`;
            const updated = await mutateWarehousePostgres(warehouseId, async (current) => {
                if (current.inactive === true) {
                    throw new Error('Warehouse is inactive');
                }
                const shelves = Array.isArray(current.shelves) ? current.shelves : [];
                const duplicate = shelves.some((entry: any) => String(entry?.name || '').trim().toLowerCase() === parsed.data.name.trim().toLowerCase());
                if (duplicate) {
                    throw new Error('Shelf already exists');
                }
                const nextSequence = shelves.reduce((max: number, entry: any) => Math.max(max, Number(entry?.sequence || 0)), 0) + 1;
                shelf = {
                    id: `${warehouseId}-s${nextSequence}`,
                    shelfNumber,
                    name: parsed.data.name.trim(),
                    sequence: nextSequence,
                    notes: parsed.data.notes || '',
                    inactive: false,
                };
                return {
                    ...current,
                    shelves: [...shelves, shelf],
                };
            });
            if (!updated) return { error: 'Warehouse not found.' };
        } else {
            const currentWarehouse = getWarehouses().find((entry) => entry.id === warehouseId);
            if (currentWarehouse?.inactive) {
                return { error: 'Warehouse is inactive' };
            }
            shelf = addShelfToWarehouse(warehouseId, parsed.data as { name: string; notes?: string });
        }
        revalidatePath('/admin/data/warehouses');
        revalidatePath('/admin/data/materials');
        return { success: true, item: shelf };
    } catch (e: any) {
        return { error: e?.message || 'Failed to add shelf.' };
    }
}

export async function handleUpdateShelf(warehouseId: string, shelfId: string, values: z.infer<typeof shelfSchema>) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const parsed = shelfSchema.safeParse(values);
    if (!parsed.success) return { error: 'Invalid data', details: parsed.error.flatten() };

    try {
        let shelf: any = null;
        if (isPostgresProviderEnabled()) {
            const updated = await mutateWarehousePostgres(warehouseId, (current) => {
                const shelves = Array.isArray(current.shelves) ? current.shelves : [];
                const shelfIndex = shelves.findIndex((entry: any) => String(entry?.id || '') === shelfId);
                if (shelfIndex === -1) {
                    throw new Error('Shelf not found');
                }
                const duplicate = shelves.some((entry: any) => String(entry?.id || '') !== shelfId && String(entry?.name || '').trim().toLowerCase() === parsed.data.name.trim().toLowerCase());
                if (duplicate) {
                    throw new Error('Shelf already exists');
                }
                const currentShelf = shelves[shelfIndex];
                shelf = {
                    ...currentShelf,
                    shelfNumber: currentShelf.shelfNumber,
                    name: parsed.data.name.trim(),
                    notes: parsed.data.notes || '',
                };
                const nextShelves = [...shelves];
                nextShelves[shelfIndex] = shelf;
                return { ...current, shelves: nextShelves };
            });
            if (!updated) return { error: 'Warehouse not found.' };
        } else {
            shelf = updateShelfInWarehouse(warehouseId, shelfId, parsed.data);
        }
        if (!shelf) return { error: 'Shelf not found.' };
        revalidatePath('/admin/data/warehouses');
        revalidatePath('/admin/data/materials');
        return { success: true, item: shelf };
    } catch (e: any) {
        return { error: e?.message || 'Failed to update shelf.' };
    }
}

export async function handleDeleteShelf(warehouseId: string, shelfId: string) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    try {
        const usageMessage = await findWarehouseOrShelfUsageRuntime({ warehouseId, shelfId });
        if (usageMessage) {
            return { error: usageMessage };
        }
        let success = false;
        if (isPostgresProviderEnabled()) {
            const updated = await mutateWarehousePostgres(warehouseId, (current) => {
                const shelves = Array.isArray(current.shelves) ? current.shelves : [];
                const filtered = shelves.filter((entry: any) => String(entry?.id || '') !== shelfId);
                success = filtered.length !== shelves.length;
                return { ...current, shelves: filtered };
            });
            if (!updated) return { error: 'Warehouse not found.' };
        } else {
            success = deleteShelfFromWarehouse(warehouseId, shelfId);
        }
        if (!success) return { error: 'Shelf not found.' };
        revalidatePath('/admin/data/warehouses');
        revalidatePath('/admin/data/materials');
        return { success: true };
    } catch (e: any) {
        return { error: e?.message || 'Failed to delete shelf.' };
    }
}

export async function handleToggleWarehouseActive(id: string, inactive: boolean) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    try {
        let item: any = null;
        if (isPostgresProviderEnabled()) {
            item = await mutateWarehousePostgres(id, (current) => ({
                ...current,
                id,
                inactive,
                shelves: Array.isArray(current.shelves) ? current.shelves : [],
            }));
        } else {
            item = updateWarehouseData(id, { inactive });
        }
        if (!item) return { error: 'Warehouse not found.' };
        revalidatePath('/admin/data/warehouses');
        revalidatePath('/admin/data/materials');
        return { success: true, item };
    } catch (e: any) {
        return { error: e?.message || 'Failed to update warehouse status.' };
    }
}

export async function handleToggleMaterialStoreEnabled(id: string, storeEnabled: boolean) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    try {
        let item: any = null;
        if (isPostgresProviderEnabled()) {
            item = await pgUpdateMaterial(id, { storeEnabled } as any);
        } else {
            const success = updateMaterial(id, { storeEnabled } as any);
            if (!success) return { error: 'Item not found.' };
            item = getMaterials().find((entry) => String((entry as any)?.id || '') === String(id || '')) || null;
        }

        if (!item) return { error: 'Item not found.' };

        revalidatePath('/admin/data/materials');
        revalidatePath('/admin/sales/pos');
        revalidatePath('/admin/store/checkout');
        return { success: true, item };
    } catch (e: any) {
        return { error: e?.message || 'Failed to update store availability.' };
    }
}

export async function handleToggleShelfActive(warehouseId: string, shelfId: string, inactive: boolean) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    try {
        let item: any = null;
        if (isPostgresProviderEnabled()) {
            const updated = await mutateWarehousePostgres(warehouseId, (current) => {
                const shelves = Array.isArray(current.shelves) ? current.shelves : [];
                const index = shelves.findIndex((entry: any) => String(entry?.id || '') === shelfId);
                if (index === -1) {
                    throw new Error('Shelf not found');
                }
                item = { ...shelves[index], inactive };
                const nextShelves = [...shelves];
                nextShelves[index] = item;
                return { ...current, shelves: nextShelves };
            });
            if (!updated) return { error: 'Warehouse not found.' };
        } else {
            item = updateShelfInWarehouse(warehouseId, shelfId, { inactive });
        }
        if (!item) return { error: 'Shelf not found.' };
        revalidatePath('/admin/data/warehouses');
        revalidatePath('/admin/data/materials');
        return { success: true, item };
    } catch (e: any) {
        return { error: e?.message || 'Failed to update shelf status.' };
    }
}

export async function handleGenerateShelves(warehouseId: string, values: z.infer<typeof shelvesSchema>) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const parsed = shelvesSchema.safeParse(values);
    if (!parsed.success) return { error: 'Invalid data', details: parsed.error.flatten() };

    const payload = {
        prefix: String(parsed.data.prefix || '').trim(),
        separator: String(parsed.data.separator || ''),
        startNumber: Number.isFinite(parsed.data.startNumber) ? Number(parsed.data.startNumber) : 1,
        count: parsed.data.count,
    };

    try {
        let result: { added: any[]; skipped: string[] };
        if (isPostgresProviderEnabled()) {
            let added: any[] = [];
            let skipped: string[] = [];
            const updated = await mutateWarehousePostgres(warehouseId, async (current) => {
                if (current.inactive === true) {
                    throw new Error('Warehouse is inactive');
                }
                const shelves = Array.isArray(current.shelves) ? current.shelves : [];
                const existingNames = new Set(shelves.map((s: any) => String(s?.name || '').trim().toLowerCase()));
                const existingMaxSequence = shelves.reduce((max: number, s: any) => Math.max(max, Number(s?.sequence || 0)), 0);
                let nextSequence = existingMaxSequence;

                const prefix = String(payload.prefix || '').trim();
                const separator = String(payload.separator || '');
                const startNumber = Number(payload.startNumber || 1);
                const count = Number(payload.count || 0);

                added = [];
                skipped = [];

                for (let i = 0; i < count; i += 1) {
                    const shelfName = `${prefix}${separator}${startNumber + i}`.trim();
                    if (!shelfName) continue;
                    if (existingNames.has(shelfName.toLowerCase())) {
                        skipped.push(shelfName);
                        continue;
                    }
                    nextSequence += 1;
                    const shelfRef = await pgNextNamedSequence('shelf-ref');
                    const shelf = {
                        id: `${warehouseId}-s${nextSequence}`,
                        shelfNumber: `SH-${String(shelfRef).padStart(5, '0')}`,
                        name: shelfName,
                        sequence: nextSequence,
                        notes: '',
                        inactive: false,
                    };
                    existingNames.add(shelfName.toLowerCase());
                    added.push(shelf);
                }

                return {
                    ...current,
                    shelves: [...shelves, ...added],
                };
            });
            if (!updated) throw new Error('Warehouse not found');
            result = { added, skipped };
        } else {
            const currentWarehouse = getWarehouses().find((entry) => entry.id === warehouseId);
            if (currentWarehouse?.inactive) {
                return { error: 'Warehouse is inactive' };
            }
            result = addShelvesToWarehouse(warehouseId, payload);
        }
        revalidatePath('/admin/data/materials');
        revalidatePath('/admin/data/warehouses');
        return { success: true, ...result };
    } catch (e: any) {
        return { error: e?.message || 'Failed to add shelves.' };
    }
}

export async function handleUpdateItemGroup(id: string, values: z.infer<typeof itemGroupSchema>) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const parsed = itemGroupSchema.safeParse(values);
    if (!parsed.success) return { error: 'Invalid data', details: parsed.error.flatten() };

    if (isPostgresProviderEnabled()) {
        const next = await pgUpdateItemGroup(id, parsed.data);
        if (!next) return { error: 'Group not found.' };
    } else {
        const success = updateItemGroup(id, parsed.data);
        if (!success) return { error: 'Group not found.' };
    }
    revalidatePath('/admin/data/item-groups');
    revalidatePath('/admin/sales/pos');
    return { success: true };
}

export async function handleDeleteItemGroup(id: string) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    if (isPostgresProviderEnabled()) {
        const success = await pgDeleteItemGroup(id);
        if (!success) return { error: 'Group not found.' };
    } else {
        const success = deleteItemGroup(id);
        if (!success) return { error: 'Group not found.' };
    }
    revalidatePath('/admin/data/item-groups');
    revalidatePath('/admin/sales/pos');
    return { success: true };
}

export async function handleUpdateListItem(itemType: 'material' | 'expense' | 'product-shape' | 'customer' | 'supplier' | 'sales-rep' | 'unit', id: string, values: any) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    let revalidationPath = '';
    if (itemType === 'material') {
        const parsed = materialItemSchema.safeParse(values);
        if (!parsed.success) return buildValidationFailure(parsed.error);
        try {
            const previousMaterial = isPostgresProviderEnabled()
                ? await pgGetMaterialById(id)
                : (getMaterials().find((entry) => String(entry.id || '').trim() === String(id || '').trim()) || null);
            for (const unitDescription of collectMaterialUnitDescriptions(parsed.data)) {
                await ensureManagedUnitRuntime(unitDescription);
            }
            if (isPostgresProviderEnabled()) {
                const normalized = normalizeMaterialUnitPayload(parsed.data as any) as any;
                const next = await pgUpdateMaterial(id, normalized);
                if (!next) return { error: 'Item not found.' };
                await syncMaterialAlternativesBidirectional({
                    materialId: id,
                    nextAlternativeIds: normalized.alternativeItemIds,
                    previousAlternativeIds: (previousMaterial as any)?.alternativeItemIds,
                });
            } else {
                const normalized = normalizeMaterialUnitPayload(parsed.data as any) as any;
                const success = updateMaterial(id, normalized);
                if (!success) return { error: 'Item number already exists.' };
                await syncMaterialAlternativesBidirectional({
                    materialId: id,
                    nextAlternativeIds: normalized.alternativeItemIds,
                    previousAlternativeIds: (previousMaterial as any)?.alternativeItemIds,
                });
            }
        } catch (e: any) {
            return { error: e?.message || 'Failed to update item.' };
        }
        revalidationPath = '/admin/data/materials';
    } else if (itemType === 'expense') {
        const parsed = expenseItemSchema.safeParse(values);
        if (!parsed.success) return buildValidationFailure(parsed.error);
        const expenseAccountCode = await ensureEntitySubAccountCodeRuntime({
            explicitAccountCode: String((values as any)?.accountCode || '').trim(),
            reservedParentCodes: ['5110'],
            entityName: parsed.data.name,
            parentCode: '5110',
            parentNameAr: 'مصروفات التشغيل',
            parentNameEn: 'Operating Expenses',
            parentParentCode: '5000',
            nature: 'debit',
            sequenceKey: 'coa-expense-sub',
        });
        if (isPostgresProviderEnabled()) {
            const next = await pgUpdateExpense(id, {
                name: parsed.data.name,
                accountCode: expenseAccountCode,
                realEstateProjectId: parsed.data.realEstateProjectId || undefined,
                realEstateUnitId: parsed.data.realEstateUnitId || undefined,
                realEstateCostType: parsed.data.realEstateCostType || 'general',
                realEstateAllocationMethod: parsed.data.realEstateAllocationMethod || 'area',
            });
            if (!next) return { error: 'Expense not found.' };
        } else {
            updateExpense(id, { ...(parsed.data as any), accountCode: expenseAccountCode });
        }
        revalidationPath = '/admin/data/expenses';
    } else if (itemType === 'product-shape') {
        const parsed = listItemSchema.safeParse(values);
        if (!parsed.success) return buildValidationFailure(parsed.error);
        try {
            if (isPostgresProviderEnabled()) {
                const next = await pgUpdateProductShapeDefinition(id, { name: parsed.data.name });
                if (!next) return { error: 'الشكل غير موجود.' };
            } else {
                updateProductShapeDefinition(id, parsed.data.name);
            }
        } catch (e: any) {
            const msg = String(e?.message || '');
            const isdup = e?.code === '23505' || msg.includes('موجود مسبقاً') || msg.includes('already exists') || msg.includes('unique');
            if (isdup) return { error: 'شكل/حجم بهذا الاسم موجود مسبقاً' };
            return { error: msg || 'تعذر تعديل الشكل' };
        }
        revalidationPath = '/admin/data/product-shapes';
    } else if (itemType === 'customer') {
        const parsed = customerItemSchema.safeParse(values);
        if (!parsed.success) return buildValidationFailure(parsed.error);
        const customerAccountCode = await ensureEntitySubAccountCodeRuntime({
            explicitAccountCode: parsed.data.accountCode,
            reservedParentCodes: ['1130'],
            entityName: parsed.data.name,
            parentCode: '1130',
            parentNameAr: 'العملاء',
            parentNameEn: 'Customers',
            parentParentCode: '1100',
            nature: 'debit',
            sequenceKey: 'coa-customer-sub',
        });
        if (isPostgresProviderEnabled()) {
            const next = await pgUpdateCustomer(id, {
                name: parsed.data.name,
                category: parsed.data.category,
                accountCode: customerAccountCode,
                phone: parsed.data.phone,
                creditLimit: parsed.data.creditLimit,
                address: parsed.data.address,
                allowedDiscount: parsed.data.allowedDiscount,
                salesRepId: parsed.data.salesRepId,
            });
            if (!next) return { error: 'Customer not found.' };
        } else {
            updateCustomer(
                id,
                parsed.data.name,
                parsed.data.category,
                parsed.data.phone,
                parsed.data.creditLimit,
                parsed.data.address,
                parsed.data.allowedDiscount,
                parsed.data.salesRepId,
                customerAccountCode,
            );
        }
        revalidationPath = '/admin/data/customers';
    } else if (itemType === 'supplier') {
        const parsed = supplierItemSchema.safeParse(values);
        if (!parsed.success) return buildValidationFailure(parsed.error);
        const supplierAccountCode = await ensureEntitySubAccountCodeRuntime({
            explicitAccountCode: parsed.data.accountCode,
            reservedParentCodes: ['2110', '2111'],
            entityName: parsed.data.name,
            parentCode: '2111',
            parentNameAr: 'الموردون',
            parentNameEn: 'Suppliers',
            parentParentCode: '2100',
            nature: 'credit',
            sequenceKey: 'coa-supplier-sub',
        });
        if (isPostgresProviderEnabled()) {
            const next = await pgUpdateSupplier(id, {
                name: parsed.data.name,
                accountCode: supplierAccountCode,
                phone: parsed.data.phone,
                address: parsed.data.address,
                paymentTerms: parsed.data.paymentTerms,
                taxNumber: parsed.data.taxNumber,
            });
            if (!next) return { error: 'Supplier not found.' };
        } else {
            updateSupplier(
                id,
                parsed.data.name,
                parsed.data.phone,
                parsed.data.address,
                parsed.data.paymentTerms,
                parsed.data.taxNumber,
                supplierAccountCode,
            );
        }
        revalidationPath = '/admin/data/suppliers';
    } else if (itemType === 'sales-rep') {
        const parsed = salesRepItemSchema.safeParse(values);
        if (!parsed.success) return buildValidationFailure(parsed.error);
        if (isPostgresProviderEnabled()) {
            const next = await pgUpdateSalesRep(id, {
                name: parsed.data.name,
                phone: parsed.data.phone,
                region: parsed.data.region,
                commissionRate: typeof parsed.data.commissionRate === 'number' ? parsed.data.commissionRate : 0,
            });
            if (!next) return { error: 'Sales rep not found.' };
        } else {
            const success = updateSalesRep(id, {
                name: parsed.data.name,
                phone: parsed.data.phone,
                region: parsed.data.region,
                commissionRate: parsed.data.commissionRate,
            });
            if (!success) return { error: 'Sales rep not found.' };
        }
        revalidationPath = '/admin/data/sales-reps';
    } else if (itemType === 'unit') {
        const parsed = unitItemSchema.safeParse(values);
        if (!parsed.success) return buildValidationFailure(parsed.error);
        try {
            if (isPostgresProviderEnabled()) {
                const next = await pgUpdateManagedUnit(id, {
                    description: parsed.data.description,
                    shortCode: parsed.data.shortCode || '',
                    notes: parsed.data.notes || '',
                });
                if (!next) return { error: 'Unit not found.' };
            } else {
                const success = updateManagedUnit(id, { description: parsed.data.description, shortCode: parsed.data.shortCode || '', notes: parsed.data.notes || '' });
                if (!success) return { error: 'Unit not found.' };
            }
            revalidationPath = '/admin/data/units';
        } catch (error: any) {
            if (error?.code === '23505') {
                return { error: 'وحدة بهذا الوصف أو الرقم موجودة مسبقاً.' };
            }
            return { error: error?.message || 'Failed to update unit.' };
        }
    }

    if (revalidationPath) {
        revalidatePath(revalidationPath);
        if (itemType === 'customer' || itemType === 'supplier') {
            revalidatePath('/admin/data/parties');
        }
        if (itemType === 'product-shape') {
            revalidatePath('/admin/data/materials');
        }
        revalidatePath('/admin/production');
        if (itemType === 'material') {
            revalidatePath('/admin/sales');
            revalidatePath('/admin/sales/pos');
        }
    }
    return { success: true };
}

const itemUnitsBulkSchema = z.object({
    itemId: z.string().min(1),
    warehouseId: z.string().optional().default(''),
    rows: z.array(z.object({
        serialNumber: z.string().optional().default(''),
        rfidCode: z.string().optional().default(''),
    })).min(1),
});

export async function handleGetItemUnits() {
    const session = await getSession();
    if (!session?.user || (session.user.role !== 'admin' && session.user.role !== 'pos')) return { error: 'Unauthorized' };
    return { success: true, units: getItemUnits() };
}

export async function handleBulkUpsertItemUnits(values: z.infer<typeof itemUnitsBulkSchema>) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const parsed = itemUnitsBulkSchema.safeParse(values);
    if (!parsed.success) return { error: 'Invalid data', details: parsed.error.flatten() };

    const result = upsertItemUnitsBulk({
        itemId: parsed.data.itemId,
        warehouseId: (parsed.data.warehouseId || '').trim() || undefined,
        rows: parsed.data.rows,
    });

    revalidatePath('/admin/data/item-units');
    revalidatePath('/admin/sales');
    revalidatePath('/admin/sales/pos');

    return { success: true, ...result };
}

const itemUnitStatusSchema = z.object({
    unitIds: z.array(z.string().min(1)).min(1),
    status: z.enum(['available', 'in_stock', 'sold', 'returned', 'damaged']),
    invoiceId: z.string().optional().default(''),
});

export async function handleUpdateItemUnitsStatus(values: z.infer<typeof itemUnitStatusSchema>) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const parsed = itemUnitStatusSchema.safeParse(values);
    if (!parsed.success) return { error: 'Invalid data', details: parsed.error.flatten() };

    const changed = updateItemUnitsStatusByIds(parsed.data.unitIds, parsed.data.status, (parsed.data.invoiceId || '').trim() || undefined);
    revalidatePath('/admin/data/item-units');
    revalidatePath('/admin/sales');
    revalidatePath('/admin/sales/pos');
    return { success: true, changed };
}

const couponCheckItemSchema = z.object({
    id: z.string(),
    checkNumber: z.string().min(1),
    bankId: z.string().min(1),
    bankName: z.string().optional().default(''),
    checkDate: z.string().min(1),
    currency: z.string().min(1),
    amount: z.coerce.number().min(0.01),
});

const campaignItemSchema = z.object({
    id: z.string().optional().default(''),
    productId: z.string().optional().default(''),
    categoryId: z.string().optional().default(''),
    minQty: z.coerce.number().int().min(1),
    bundlePrice: z.coerce.number().positive(),
    regularUnitPrice: z.coerce.number().positive().optional(),
    maxApplications: z.coerce.number().int().positive().optional(),
});

const campaignCreateSchema = z.object({
    name: z.string().min(1),
    type: z.enum(['multi_buy', 'mix_match', 'buy_x_get_y', 'tier_pricing', 'fixed_bundle']).optional().default('multi_buy'),
    startDate: z.string().min(1),
    endDate: z.string().min(1),
    status: z.enum(['active', 'scheduled', 'expired', 'inactive']).optional().default('active'),
    description: z.string().optional().default(''),
    branchIds: z.array(z.string().min(1)).optional().default([]),
    customerTags: z.array(z.string().min(1)).optional().default([]),
    autoApplyInPos: z.coerce.boolean().optional().default(true),
    allowRepeats: z.coerce.boolean().optional().default(true),
    allowStacking: z.coerce.boolean().optional().default(false),
    priority: z.coerce.number().int().min(0).optional().default(0),
    maxApplicationsPerInvoice: z.coerce.number().int().min(0).optional().default(0),
    items: z.array(campaignItemSchema).min(1),
});

const campaignUpdateSchema = campaignCreateSchema.extend({
    campaignId: z.string().min(1),
});

const campaignDeleteSchema = z.object({
    campaignId: z.string().min(1),
});

export async function handleGetCampaigns() {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };
    const campaigns = await getCampaignsRuntime();
    return { success: true, campaigns };
}

export async function handleCreateCampaign(values: z.infer<typeof campaignCreateSchema>) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const parsed = campaignCreateSchema.safeParse(values);
    if (!parsed.success) return { error: 'Invalid data', details: parsed.error.flatten() };

    const start = new Date(parsed.data.startDate);
    const end = new Date(parsed.data.endDate);
    if (Number.isNaN(start.getTime()) || Number.isNaN(end.getTime()) || end.getTime() < start.getTime()) {
        return { error: 'تاريخ نهاية الحملة يجب أن يكون بعد تاريخ البداية.' };
    }

    const items = parsed.data.items
        .map((item) => ({
            productId: String(item.productId || '').trim() || undefined,
            categoryId: String(item.categoryId || '').trim() || undefined,
            minQty: Number(item.minQty || 0),
            bundlePrice: Number(item.bundlePrice || 0),
            regularUnitPrice: Number.isFinite(Number(item.regularUnitPrice)) ? Number(item.regularUnitPrice) : undefined,
            maxApplications: Number.isFinite(Number(item.maxApplications)) ? Number(item.maxApplications) : undefined,
        }))
        .filter((item) => item.minQty > 0 && item.bundlePrice > 0 && (item.productId || item.categoryId));

    if (items.length === 0) {
        return { error: 'يجب إضافة صنف واحد على الأقل للحملة.' };
    }

    const campaign = await createCampaignRuntime({
        name: String(parsed.data.name || '').trim(),
        type: parsed.data.type,
        startDate: start.toISOString(),
        endDate: end.toISOString(),
        status: parsed.data.status,
        description: String(parsed.data.description || '').trim() || undefined,
        branchIds: (parsed.data.branchIds || []).map((value) => String(value || '').trim()).filter(Boolean),
        customerTags: (parsed.data.customerTags || []).map((value) => String(value || '').trim()).filter(Boolean),
        autoApplyInPos: parsed.data.autoApplyInPos,
        allowRepeats: parsed.data.allowRepeats,
        allowStacking: parsed.data.allowStacking,
        priority: Number(parsed.data.priority || 0),
        maxApplicationsPerInvoice: Number(parsed.data.maxApplicationsPerInvoice || 0),
        items,
        createdBy: session.user.name || 'admin',
    });

    revalidatePath('/admin/data/campaigns');
    revalidatePath('/admin/sales');
    revalidatePath('/admin/sales/pos');
    return { success: true, campaign };
}

export async function handleUpdateCampaign(values: z.infer<typeof campaignUpdateSchema>) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const parsed = campaignUpdateSchema.safeParse(values);
    if (!parsed.success) return { error: 'Invalid data', details: parsed.error.flatten() };

    const start = new Date(parsed.data.startDate);
    const end = new Date(parsed.data.endDate);
    if (Number.isNaN(start.getTime()) || Number.isNaN(end.getTime()) || end.getTime() < start.getTime()) {
        return { error: 'تاريخ نهاية الحملة يجب أن يكون بعد تاريخ البداية.' };
    }

    const items = parsed.data.items
        .map((item) => ({
            id: String(item.id || '').trim() || undefined,
            campaignId: parsed.data.campaignId,
            productId: String(item.productId || '').trim() || undefined,
            categoryId: String(item.categoryId || '').trim() || undefined,
            minQty: Number(item.minQty || 0),
            bundlePrice: Number(item.bundlePrice || 0),
            regularUnitPrice: Number.isFinite(Number(item.regularUnitPrice)) ? Number(item.regularUnitPrice) : undefined,
            maxApplications: Number.isFinite(Number(item.maxApplications)) ? Number(item.maxApplications) : undefined,
        }))
        .filter((item) => item.minQty > 0 && item.bundlePrice > 0 && (item.productId || item.categoryId));

    if (items.length === 0) {
        return { error: 'يجب إضافة صنف واحد على الأقل للحملة.' };
    }

    const updated = await updateCampaignRuntime(parsed.data.campaignId, {
        name: String(parsed.data.name || '').trim(),
        type: parsed.data.type,
        startDate: start.toISOString(),
        endDate: end.toISOString(),
        status: parsed.data.status,
        description: String(parsed.data.description || '').trim() || undefined,
        branchIds: (parsed.data.branchIds || []).map((value) => String(value || '').trim()).filter(Boolean),
        customerTags: (parsed.data.customerTags || []).map((value) => String(value || '').trim()).filter(Boolean),
        autoApplyInPos: parsed.data.autoApplyInPos,
        allowRepeats: parsed.data.allowRepeats,
        allowStacking: parsed.data.allowStacking,
        priority: Number(parsed.data.priority || 0),
        maxApplicationsPerInvoice: Number(parsed.data.maxApplicationsPerInvoice || 0),
        items,
    });

    if (!updated) return { error: 'الحملة غير موجودة.' };

    revalidatePath('/admin/data/campaigns');
    revalidatePath('/admin/sales');
    revalidatePath('/admin/sales/pos');
    return { success: true, campaign: updated };
}

export async function handleDeleteCampaign(values: z.infer<typeof campaignDeleteSchema>) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const parsed = campaignDeleteSchema.safeParse(values);
    if (!parsed.success) return { error: 'Invalid data', details: parsed.error.flatten() };

    const done = await deleteCampaignRuntime(parsed.data.campaignId);
    if (!done) return { error: 'الحملة غير موجودة.' };

    revalidatePath('/admin/data/campaigns');
    revalidatePath('/admin/sales');
    revalidatePath('/admin/sales/pos');
    return { success: true };
}

const couponCreateSchema = z.object({
    title: z.string().min(1),
    amount: z.coerce.number().positive(),
    couponCode: z.string().optional().default(''),
    currencyCode: z.string().optional().default(''),
    expiryDate: z.string().optional().default(''),
    notes: z.string().optional().default(''),
    customerType: z.enum(['cash', 'customer']).optional().default('cash'),
    customerId: z.string().optional().default(''),
    paymentMethod: z.enum(['cash', 'check', 'credit']).optional(),
    paymentSource: z.enum(['cash', 'bank']).optional(),
    checks: z.array(couponCheckItemSchema).optional().default([]),
});

const couponStatusSchema = z.object({
    couponId: z.string().min(1),
    status: z.enum(['active', 'used', 'expired', 'cancelled']),
    notes: z.string().optional().default(''),
});

export async function handleGetCoupons() {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };
    const coupons = await getCouponsRuntime();
    return { success: true, coupons };
}

export async function handleValidateCouponCode(rawCode: string) {
    const session = await getSession();
    if (!session?.user) return { success: false, error: 'UNAUTHORIZED' as const };

    const code = String(rawCode || '').trim();
    if (!code) {
        return { success: false, error: 'COUPON_CODE_REQUIRED' as const };
    }

    const coupons = await getCouponsRuntime();
    const normalizedCode = code.toLowerCase();
    const coupon = coupons.find((entry) => String(entry.couponCode || '').trim().toLowerCase() === normalizedCode);

    if (!coupon) {
        return { success: false, error: 'COUPON_NOT_FOUND' as const };
    }

    if (coupon.status === 'cancelled') {
        return { success: false, error: 'COUPON_CANCELLED' as const, coupon };
    }
    if (coupon.status === 'used') {
        return { success: false, error: 'COUPON_USED' as const, coupon };
    }
    if (coupon.status === 'expired') {
        return { success: false, error: 'COUPON_EXPIRED' as const, coupon };
    }

    if (coupon.expiryDate) {
        const expiry = new Date(coupon.expiryDate).getTime();
        if (Number.isFinite(expiry) && expiry < Date.now()) {
            return { success: false, error: 'COUPON_EXPIRED' as const, coupon };
        }
    }

    if (Number(coupon.remainingAmount || 0) <= 0) {
        return { success: false, error: 'COUPON_NO_BALANCE' as const, coupon };
    }

    return {
        success: true,
        coupon: {
            id: coupon.id,
            couponCode: coupon.couponCode,
            couponNumber: coupon.couponNumber,
            title: coupon.title,
            remainingAmount: Number(coupon.remainingAmount || 0),
            originalAmount: Number(coupon.originalAmount || 0),
            currencyCode: coupon.currencyCode,
            status: coupon.status,
            expiryDate: coupon.expiryDate,
        },
    };
}

export async function handleCreateCoupon(values: z.infer<typeof couponCreateSchema>) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const parsed = couponCreateSchema.safeParse(values);
    if (!parsed.success) return { error: 'Invalid data', details: parsed.error.flatten() };

    const paymentMethod = parsed.data.paymentMethod || (parsed.data.paymentSource === 'bank' ? 'check' : 'cash');
    const customerType = parsed.data.customerType || 'cash';
    const customerId = String(parsed.data.customerId || '').trim();
    const checks = (parsed.data.checks || []).map((check) => ({
        ...check,
        checkNumber: String(check.checkNumber || '').trim(),
        bankId: String(check.bankId || '').trim(),
        bankName: String(check.bankName || '').trim(),
        checkDate: String(check.checkDate || '').trim(),
        currency: String(check.currency || '').trim(),
        amount: Number(check.amount || 0),
    })).filter((check) => check.checkNumber && check.bankId && check.checkDate && check.currency && check.amount > 0);

    if (customerType === 'customer' && !customerId) {
        return { error: 'يرجى اختيار الزبون المرتبط بالكوبون.' };
    }

    if (paymentMethod === 'credit' && customerType !== 'customer') {
        return { error: 'الدفع الآجل للكوبون يتطلب زبوناً عادياً.' };
    }

    if (paymentMethod === 'check') {
        if (checks.length === 0) {
            return { error: 'يجب تسجيل شيك واحد على الأقل عند اختيار السداد بالشيكات.' };
        }

        const checksTotal = checks.reduce((sum, check) => sum + Number(check.amount || 0), 0);
        if (Math.abs(checksTotal - Number(parsed.data.amount || 0)) > 0.0001) {
            return { error: 'مجموع الشيكات يجب أن يساوي قيمة الكوبون.' };
        }
    }

    try {
        let customer: Record<string, any> | null = null;
        let customerAccountCode = '';
        let customerAccountName = '';

        if (customerType === 'customer') {
            const customers = await getCustomersRuntime();
            customer = customers.find((entry) => String(entry?.id || '').trim() === customerId) || null;
            if (!customer) {
                return { error: 'الزبون المحدد غير موجود.' };
            }

            customerAccountCode = await ensureEntitySubAccountCodeRuntime({
                explicitAccountCode: String(customer.accountCode || '').trim(),
                reservedParentCodes: ['1130'],
                entityName: String(customer.name || '').trim() || 'زبون',
                parentCode: '1130',
                parentNameAr: 'العملاء',
                parentNameEn: 'Customers',
                parentParentCode: '1100',
                nature: 'debit',
                sequenceKey: 'coa-customer-sub',
            });

            const refreshedAccounts = await getChartOfAccountsRuntime();
            const customerAccount = (refreshedAccounts as Array<Record<string, any>>).find(
                (account) => String(account?.code || '').trim() === customerAccountCode,
            );
            customerAccountName = String(customerAccount?.nameAr || customerAccount?.nameEn || customer.name || 'العملاء');
        }

        const accounts = await getChartOfAccountsRuntime();
        const mutableAccounts = accounts as Array<Record<string, any>>;
        let accountsChanged = false;

        const currentAssets = ensureChartAccountInCollection(mutableAccounts, {
            preferredCode: '1100',
            nameAr: 'الأصول المتداولة',
            nameEn: 'Current Assets',
            parentCode: '',
            type: 'header',
        });
        accountsChanged = accountsChanged || currentAssets.changed;

        const cashAccount = ensureChartAccountInCollection(mutableAccounts, {
            preferredCode: '1110',
            nameAr: 'الصندوق',
            nameEn: 'Cash',
            parentCode: String(currentAssets.account?.code || '1100'),
            nature: 'debit',
        });
        accountsChanged = accountsChanged || cashAccount.changed;

        const notesReceivableAccount = ensureChartAccountInCollection(mutableAccounts, {
            preferredCode: '1140',
            nameAr: 'أوراق القبض',
            nameEn: 'Notes Receivable',
            parentCode: String(currentAssets.account?.code || '1100'),
            nature: 'debit',
        });
        accountsChanged = accountsChanged || notesReceivableAccount.changed;

        if (accountsChanged) {
            await saveChartOfAccountsRuntime(mutableAccounts);
        }

        const couponAccounting = await ensureCouponAccountingSetup();

        const validatedBanksById = new Map<string, any>();
        if (paymentMethod === 'check') {
            for (const check of checks) {
                const bank = await getBankByIdForCalc(check.bankId);
                if (!bank) {
                    return { error: `البنك المرتبط بالشيك ${check.checkNumber} غير موجود.` };
                }
                validatedBanksById.set(check.bankId, bank);
            }
        }

        const defaultCurrency = await getDefaultCurrencyRuntime();
        const baseCurrencyCode = String(defaultCurrency?.code || 'JOD').trim().toUpperCase() || 'JOD';
        const couponCurrencyCode = String(parsed.data.currencyCode || baseCurrencyCode).trim().toUpperCase() || baseCurrencyCode;
        const issueDateIso = new Date().toISOString();
        const couponExchangeRate = await resolveCouponExchangeRate({
            currencyCode: couponCurrencyCode,
            baseCurrencyCode,
            rateDate: issueDateIso,
        });
        const couponAmount = Number(parsed.data.amount || 0);
        const couponAmountBase = couponAmount * couponExchangeRate;

        const settlementAccountCode = paymentMethod === 'credit'
            ? (customerAccountCode || '1130')
            : paymentMethod === 'check'
                ? String(notesReceivableAccount.account?.code || '1140')
                : String(cashAccount.account?.code || '1110');
        const settlementAccountName = paymentMethod === 'credit'
            ? (customerAccountName || String(customer?.name || 'العملاء'))
            : paymentMethod === 'check'
                ? String(notesReceivableAccount.account?.nameAr || notesReceivableAccount.account?.nameEn || 'أوراق القبض')
                : String(cashAccount.account?.nameAr || cashAccount.account?.nameEn || 'الصندوق');

        const coupon = await createCouponRuntime({
            title: parsed.data.title,
            amount: couponAmount,
            couponCode: String(parsed.data.couponCode || '').trim() || undefined,
            currencyCode: couponCurrencyCode,
            baseCurrencyCode,
            exchangeRate: couponExchangeRate,
            rateDate: issueDateIso,
            originalAmountBase: couponAmountBase,
            remainingAmountBase: couponAmountBase,
            customerType,
            customerId: customerType === 'customer' ? customerId : undefined,
            customerName: customerType === 'customer'
                ? String(customer?.name || '').trim() || undefined
                : 'زبون نقدي',
            customerAccountCode: customerAccountCode || undefined,
            paymentMethod,
            settlementAccountCode,
            settlementAccountName,
            liabilityAccountCode: couponAccounting.couponLiabilityAccountCode,
            liabilityAccountName: couponAccounting.couponLiabilityAccountName,
            expiryDate: String(parsed.data.expiryDate || '').trim() || undefined,
            notes: String(parsed.data.notes || '').trim() || undefined,
            createdBy: session.user.name || 'admin',
        });

        try {
            const entries = await getJournalEntriesRuntime();
            const entryId = isPostgresProviderEnabled()
                ? `JE-${Date.now()}-${Math.floor(Math.random() * 1_000_000)}`
                : `JE-${nextNamedSequence('journal-entry')}`;
            const entry = await buildCouponIssuanceJournalEntryRecord({
                entryId,
                couponId: coupon.id,
                couponNumber: coupon.couponNumber,
                amount: Number(coupon.originalAmount || 0),
                amountBase: Number(coupon.originalAmountBase || couponAmountBase || coupon.originalAmount || 0),
                currencyCode: String(coupon.currencyCode || couponCurrencyCode || '').trim() || undefined,
                baseCurrencyCode: String(coupon.baseCurrencyCode || baseCurrencyCode || '').trim() || undefined,
                exchangeRate: Number(coupon.exchangeRate || couponExchangeRate || 0),
                rateDate: String(coupon.rateDate || issueDateIso || '').trim() || undefined,
                paymentMethod,
                settlementAccountCode,
                settlementAccountName,
                couponLiabilityAccountCode: couponAccounting.couponLiabilityAccountCode,
                couponLiabilityAccountName: couponAccounting.couponLiabilityAccountName,
                customerName: customerType === 'customer' ? String(customer?.name || '').trim() || undefined : undefined,
                createdBy: session.user.name || 'admin',
            });
            entries.unshift(entry);
            await saveJournalEntriesRuntime(entries);
        } catch (journalError) {
            console.error('Coupon issuance journal posting failed:', journalError);
        }

        if (paymentMethod === 'check') {
            for (const check of checks) {
                const bank = validatedBanksById.get(check.bankId);
                const checkCurrency = String(check.currency || baseCurrencyCode).trim() || baseCurrencyCode;
                const checkAmount = Number(check.amount || 0);
                const checkExchangeRate = checkCurrency === baseCurrencyCode
                    ? 1
                    : getExchangeRate(checkCurrency, baseCurrencyCode);

                await addIncomingCheckRuntime({
                    checkNumber: check.checkNumber,
                    bankId: check.bankId,
                    bankName: String(bank?.name || check.bankName || '').trim(),
                    checkDate: check.checkDate,
                    amount: checkAmount,
                    currency: checkCurrency,
                    convertedAmount: checkAmount * checkExchangeRate,
                    exchangeRate: checkExchangeRate,
                    customerId: customerType === 'customer' ? customerId : 'cash',
                    customerName: customerType === 'customer'
                        ? String(customer?.name || '').trim() || 'زبون عادي'
                        : 'زبون نقدي',
                    reference: coupon.couponNumber,
                    status: 'pending',
                    notes: `[COUPON:${coupon.id}] قبض شيك مقابل الكوبون ${coupon.couponNumber}`,
                    createdBy: session.user.name || 'admin',
                });
            }
        }

        revalidatePath('/admin/data/coupons');
        revalidatePath('/admin/checks/incoming');
        revalidatePath('/admin/sales');
        revalidatePath('/admin/sales/pos');
        revalidatePath('/admin/accounting/entries');
        return { success: true, coupon };
    } catch (error: any) {
        const message = String(error?.message || 'Failed to create coupon.');
        if (message.includes('COUPON_CODE_EXISTS')) {
            return { error: 'رمز الكوبون مستخدم مسبقاً.' };
        }
        if (message.includes('COUPON_AMOUNT_INVALID')) {
            return { error: 'قيمة الكوبون غير صالحة.' };
        }
        return { error: message };
    }
}

export async function handleUpdateCouponStatus(values: z.infer<typeof couponStatusSchema>) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const parsed = couponStatusSchema.safeParse(values);
    if (!parsed.success) return { error: 'Invalid data', details: parsed.error.flatten() };

    const updated = await updateCouponStatusRuntime(
        parsed.data.couponId,
        parsed.data.status,
        String(parsed.data.notes || '').trim() || undefined,
    );
    if (!updated) return { error: 'Coupon not found.' };

    revalidatePath('/admin/data/coupons');
    revalidatePath('/admin/sales');
    revalidatePath('/admin/sales/pos');
    return { success: true, coupon: updated };
}

export async function handleDeleteListItem(itemType: 'material' | 'expense' | 'product-shape' | 'customer' | 'supplier' | 'sales-rep' | 'unit', id: string) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };
    
    let revalidationPath = '';
    if (itemType === 'material') {
        if (isPostgresProviderEnabled()) {
            await pgDeleteMaterial(id);
        } else {
            deleteMaterial(id);
        }
        revalidationPath = '/admin/data/materials';
    } else if (itemType === 'expense') {
        if (isPostgresProviderEnabled()) {
            await pgDeleteExpense(id);
        } else {
            deleteExpense(id);
        }
        revalidationPath = '/admin/data/expenses';
    } else if (itemType === 'product-shape') {
        if (isPostgresProviderEnabled()) {
            await pgDeleteProductShapeDefinition(id);
        } else {
            deleteProductShapeDefinition(id);
        }
        revalidationPath = '/admin/data/product-shapes';
    } else if (itemType === 'customer') {
        if (isPostgresProviderEnabled()) {
            await pgDeleteCustomer(id);
        } else {
            deleteCustomer(id);
        }
        revalidationPath = '/admin/data/customers';
    } else if (itemType === 'supplier') {
        if (isPostgresProviderEnabled()) {
            await pgDeleteSupplier(id);
        } else {
            deleteSupplier(id);
        }
        revalidationPath = '/admin/data/suppliers';
    } else if (itemType === 'sales-rep') {
        if (isPostgresProviderEnabled()) {
            await pgDeleteSalesRep(id);
        } else {
            deleteSalesRep(id);
        }
        revalidationPath = '/admin/data/sales-reps';
    } else if (itemType === 'unit') {
        if (isPostgresProviderEnabled()) {
            await pgDeleteManagedUnit(id);
        } else {
            deleteManagedUnit(id);
        }
        revalidationPath = '/admin/data/units';
    }

    if (revalidationPath) {
        revalidatePath(revalidationPath);
        if (itemType === 'customer' || itemType === 'supplier') {
            revalidatePath('/admin/data/parties');
        }
        if (itemType === 'product-shape') {
            revalidatePath('/admin/data/materials');
        }
        revalidatePath('/admin/production');
        if (itemType === 'material') {
            revalidatePath('/admin/sales');
            revalidatePath('/admin/sales/pos');
        }
    }

    return { success: true };
}

export async function handleEnsureManagedUnit(description: string) {
    const session = await getSession();
    const role = session?.user?.role;
    if (!session?.user || (role !== 'admin' && role !== 'pos')) return { error: 'Unauthorized' };

    const normalizedDescription = String(description || '').trim();
    if (!normalizedDescription) {
        return { success: true, item: null };
    }

    try {
        const unit = await ensureManagedUnitRuntime(normalizedDescription);
        revalidatePath('/admin/data/units');
        revalidatePath('/admin/data/materials');
        return {
            success: true,
            item: unit
                ? {
                    ...unit,
                    name: (unit as any).description,
                }
                : null,
        };
    } catch (error: any) {
        return { error: error?.message || 'Failed to ensure unit.' };
    }
}

export async function handleGetManagedUnits() {
    const session = await getSession();
    const role = session?.user?.role;
    if (!session?.user || (role !== 'admin' && role !== 'pos')) return { error: 'Unauthorized' };

    const rawUnits = isPostgresProviderEnabled()
        ? (await pgGetManagedUnits({ page: 1, pageSize: 5000 })).items
        : getManagedUnits();

    const units = rawUnits.map((unit: any) => ({
        ...unit,
        name: unit.description,
    }));

    return { success: true, items: units };
}

export async function handleGetProductShapeDefinitions() {
    const session = await getSession();
    const role = session?.user?.role;
    if (!session?.user || (role !== 'admin' && role !== 'pos')) return { error: 'Unauthorized' };

    const rawItems = isPostgresProviderEnabled()
        ? (await pgGetProductShapeDefinitions({ page: 1, pageSize: 5000 })).items
        : getProductShapeDefinitions();

    const items = rawItems.map((entry: any) => ({
        id: String(entry.id || ''),
        name: String(entry.name || '').trim(),
    })).filter((entry: any) => entry.id && entry.name);

    return { success: true, items };
}

// Customer Pricing Action
const customerPricingSchema = z.object({
    category: z.string(),
    prices: z.array(z.object({
        materialId: z.string().min(1),
        price: z.coerce.number().min(0),
    })),
    bonus: z.object({
        materialId: z.string().optional(),
        buyQuantity: z.coerce.number().min(0).optional(),
        bonusQuantity: z.coerce.number().min(0).optional(),
    }).optional(),
});

export async function handleUpdateCustomerPricing(values: z.infer<typeof customerPricingSchema>) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const parsed = customerPricingSchema.safeParse(values);
    if (!parsed.success) {
        console.error(parsed.error);
        return { error: 'Invalid data submitted.' };
    }

    const { category, prices, bonus } = parsed.data;
    
    let bonusData: CustomerPricing['bonus'] | undefined = undefined;
    if (bonus?.materialId && bonus.buyQuantity && bonus.buyQuantity > 0 && bonus.bonusQuantity && bonus.bonusQuantity > 0) {
        bonusData = {
            materialId: bonus.materialId,
            buyQuantity: bonus.buyQuantity,
            bonusQuantity: bonus.bonusQuantity,
        };
    }

    const pricingData: CustomerPricing = {
        category,
        prices: prices.map((entry) => ({ materialId: entry.materialId, price: entry.price })),
        bonus: bonusData,
    };

    if (isPostgresProviderEnabled()) {
        await pgSetCustomerPricing(pricingData as unknown as Record<string, unknown>);
    } else {
        updateCustomerPricing(pricingData);
    }

    revalidatePath('/admin/data/customer-pricing');
    return { success: true, message: 'Customer pricing updated successfully.' };
}

// Sales Invoice Action
const disassemblyRecordSchema = z.object({
    date: z.string().optional(),
    parentItemId: z.string().min(1, 'Parent item is required.'),
    parentQuantity: z.coerce.number().min(0.0001, 'Parent quantity must be greater than zero.'),
    purchaseCost: z.coerce.number().min(0, 'Purchase cost must be non-negative.'),
    additionalCost: z.coerce.number().min(0).optional().default(0),
    sourceWarehouseId: z.string().optional().default(''),
    sourceShelfId: z.string().optional().default(''),
    targetWarehouseId: z.string().optional().default(''),
    targetShelfId: z.string().optional().default(''),
    notes: z.string().optional().default(''),
    parts: z.array(z.object({
        partItemId: z.string().min(1, 'Part item is required.'),
        quantity: z.coerce.number().min(0.0001, 'Part quantity must be greater than zero.'),
        expectedSalePrice: z.coerce.number().min(0, 'Expected sale price must be non-negative.'),
        notes: z.string().optional().default(''),
    })).min(1, 'At least one output part is required.'),
});

const realEstateProjectSchema = z.object({
    id: z.string().optional().default(''),
    name: z.string().min(1, 'Project name is required.'),
    code: z.string().optional().default(''),
    location: z.string().optional().default(''),
    startDate: z.string().optional().default(''),
    targetCompletionDate: z.string().optional().default(''),
    floorCount: z.coerce.number().min(0).optional().default(0),
    designSummary: z.string().optional().default(''),
    floorDetails: z.array(z.object({
        id: z.string().optional().default(''),
        floorLabel: z.string().optional().default(''),
        usageType: z.string().optional().default(''),
        description: z.string().optional().default(''),
        unitCount: z.coerce.number().min(0).optional().default(0),
        unitArea: z.coerce.number().min(0).optional().default(0),
        estimatedUnitSaleValue: z.coerce.number().min(0).optional().default(0),
        unitDetails: z.array(z.object({
            id: z.string().optional().default(''),
            unitLabel: z.string().optional().default(''),
            area: z.coerce.number().min(0).optional().default(0),
            estimatedSaleValue: z.coerce.number().min(0).optional().default(0),
            notes: z.string().optional().default(''),
        })).optional().default([]),
        notes: z.string().optional().default(''),
    })).optional().default([]),
    status: z.enum(['draft', 'active', 'completed']).optional().default('draft'),
    notes: z.string().optional().default(''),
    units: z.array(z.object({
        id: z.string().optional().default(''),
        unitCode: z.string().optional().default(''),
        name: z.string().optional().default(''),
        floor: z.string().optional().default(''),
        area: z.coerce.number().min(0).default(0),
        saleValue: z.coerce.number().min(0).optional().default(0),
        actualSaleValue: z.coerce.number().min(0).optional().default(0),
        directCost: z.coerce.number().min(0).optional().default(0),
        directCostEntries: z.array(z.object({
            id: z.string().optional().default(''),
            phase: z.string().optional().default(''),
            title: z.string().optional().default(''),
            amount: z.coerce.number().min(0).default(0),
            date: z.string().optional().default(''),
            notes: z.string().optional().default(''),
        })).optional().default([]),
        buyerCustomerId: z.string().optional().default(''),
        buyerName: z.string().optional().default(''),
        contractDate: z.string().optional().default(''),
        handoverDate: z.string().optional().default(''),
        collectedAmount: z.coerce.number().min(0).optional().default(0),
        lastCollectionDate: z.string().optional().default(''),
        installments: z.array(z.object({
            id: z.string().optional().default(''),
            title: z.string().optional().default(''),
            dueDate: z.string().optional().default(''),
            amount: z.coerce.number().min(0).default(0),
            paidAmount: z.coerce.number().min(0).optional().default(0),
            status: z.enum(['pending', 'partially-paid', 'paid', 'overdue']).optional().default('pending'),
            notes: z.string().optional().default(''),
        })).optional().default([]),
        status: z.enum(['planned', 'available', 'reserved', 'sold']).optional().default('planned'),
        notes: z.string().optional().default(''),
    })).optional().default([]),
    sharedCosts: z.array(z.object({
        id: z.string().optional().default(''),
        title: z.string().optional().default(''),
        category: z.string().optional().default(''),
        amount: z.coerce.number().min(0).default(0),
        allocationMethod: z.enum(['area', 'sale-value', 'manual-share']).optional().default('area'),
        notes: z.string().optional().default(''),
        unitAllocations: z.array(z.object({
            unitId: z.string().min(1),
            percentage: z.coerce.number().min(0).max(100).default(0),
        })).optional().default([]),
    })).optional().default([]),
    sharedCostAllocationMethod: z.enum(['area', 'sale-value', 'manual-share']).optional().default('area'),
    sharedCostUnitAllocations: z.array(z.object({
        unitId: z.string().min(1),
        percentage: z.coerce.number().min(0).max(100).default(0),
    })).optional().default([]),
});

const realEstateCostPostingSchema = z.object({
    projectId: z.string().min(1, 'Project is required.'),
    itemId: z.string().min(1, 'Item is required.'),
    date: z.string().optional().default(''),
    amount: z.coerce.number().positive('Amount must be greater than zero.'),
    paymentSource: z.enum(['cash', 'bank', 'payable']).optional().default('cash'),
    note: z.string().optional().default(''),
});

type PosShiftSession = {
    id: string;
    userId: string;
    userName: string;
    startedAt: string;
    endedAt?: string;
    status: 'active' | 'closed';
    openingCash: number;
    openingVisa: number;
    totalSalesAmount: number;
    invoicesCount: number;
    returnsCount: number;
    cashSalesAmount: number;
    visaSalesAmount: number;
    receivablesAmount: number;
    couponAmount: number;
    expectedCashAtClose: number;
    expectedVisaAtClose: number;
    countedCashAtClose?: number;
    countedVisaAtClose?: number;
    cashVariance?: number;
    visaVariance?: number;
    notes?: string;
    closeNotes?: string;
    requiresApproval?: boolean;
    approvedById?: string;
    approvedByName?: string;
    approvedAt?: string;
    cashVarianceHandled?: boolean;
    cashVarianceHandledAt?: string;
    cashVarianceHandlingMethod?: 'post_cash_difference' | 'charge_cashier' | 'transfer_without_difference_entry';
    cashVarianceHandlingEntryId?: string;
};

const posShiftOpenSchema = z.object({
    openingCash: z.coerce.number().min(0).default(0),
    openingVisa: z.coerce.number().min(0).default(0),
    notes: z.string().optional().default(''),
});

const posShiftCloseSchema = z.object({
    countedCash: z.coerce.number().min(0).default(0),
    countedVisa: z.coerce.number().min(0).default(0),
    notes: z.string().optional().default(''),
});

function toMoney(value: unknown): number {
    const num = Number(value || 0);
    if (!Number.isFinite(num)) return 0;
    return Math.round(num * 100) / 100;
}

function normalizePosShiftSession(input: any): PosShiftSession | null {
    if (!input || typeof input !== 'object') return null;
    const id = String(input.id || '').trim();
    const userId = String(input.userId || '').trim();
    const startedAt = String(input.startedAt || '').trim();
    if (!id || !userId || !startedAt) return null;

    return {
        id,
        userId,
        userName: String(input.userName || '').trim() || userId,
        startedAt,
        endedAt: String(input.endedAt || '').trim() || undefined,
        status: input.status === 'closed' ? 'closed' : 'active',
        openingCash: toMoney(input.openingCash),
        openingVisa: toMoney(input.openingVisa),
        totalSalesAmount: toMoney(input.totalSalesAmount),
        invoicesCount: Math.max(0, Number(input.invoicesCount || 0) || 0),
        returnsCount: Math.max(0, Number(input.returnsCount || 0) || 0),
        cashSalesAmount: toMoney(input.cashSalesAmount),
        visaSalesAmount: toMoney(input.visaSalesAmount),
        receivablesAmount: toMoney(input.receivablesAmount),
        couponAmount: toMoney(input.couponAmount),
        expectedCashAtClose: toMoney(input.expectedCashAtClose),
        expectedVisaAtClose: toMoney(input.expectedVisaAtClose),
        countedCashAtClose: input.countedCashAtClose === undefined ? undefined : toMoney(input.countedCashAtClose),
        countedVisaAtClose: input.countedVisaAtClose === undefined ? undefined : toMoney(input.countedVisaAtClose),
        cashVariance: input.cashVariance === undefined ? undefined : toMoney(input.cashVariance),
        visaVariance: input.visaVariance === undefined ? undefined : toMoney(input.visaVariance),
        notes: String(input.notes || '').trim() || undefined,
        closeNotes: String(input.closeNotes || '').trim() || undefined,
        requiresApproval: input.requiresApproval === true,
        approvedById: String(input.approvedById || '').trim() || undefined,
        approvedByName: String(input.approvedByName || '').trim() || undefined,
        approvedAt: String(input.approvedAt || '').trim() || undefined,
        cashVarianceHandled: input.cashVarianceHandled === true,
        cashVarianceHandledAt: String(input.cashVarianceHandledAt || '').trim() || undefined,
        cashVarianceHandlingMethod: ['post_cash_difference', 'charge_cashier', 'transfer_without_difference_entry'].includes(String(input.cashVarianceHandlingMethod || '').trim())
            ? (String(input.cashVarianceHandlingMethod || '').trim() as 'post_cash_difference' | 'charge_cashier' | 'transfer_without_difference_entry')
            : undefined,
        cashVarianceHandlingEntryId: String(input.cashVarianceHandlingEntryId || '').trim() || undefined,
    };
}

async function getPosShiftSessionsRuntime(): Promise<PosShiftSession[]> {
    if (isPostgresProviderEnabled()) {
        // TODO: Implement PostgreSQL data access for POS shift sessions
        // For now, fall back to JSON for PostgreSQL provider
    }

    const rows = getPosShiftSessions();
    return rows
        .map((entry: any) => normalizePosShiftSession(entry))
        .filter((entry: PosShiftSession | null): entry is PosShiftSession => !!entry)
        .sort((a, b) => String(b.startedAt).localeCompare(String(a.startedAt)));
}

async function savePosShiftSessionsRuntime(sessions: PosShiftSession[]) {
    if (isPostgresProviderEnabled()) {
        // TODO: Implement PostgreSQL data access for POS shift sessions
        // For now, fall back to JSON for PostgreSQL provider
    }

    savePosShiftSessions(sessions);
}

async function getActivePosShiftSessionForUserRuntime(userId: string): Promise<PosShiftSession | null> {
    const normalizedUserId = String(userId || '').trim();
    if (!normalizedUserId) return null;
    const sessions = await getPosShiftSessionsRuntime();
    return sessions.find((session) => session.userId === normalizedUserId && session.status === 'active') || null;
}

function getShiftVariancePolicy(settings: Record<string, unknown>) {
    const thresholdRaw = Number((settings as any)?.posShiftVarianceApprovalThreshold ?? 0);
    const threshold = Number.isFinite(thresholdRaw) && thresholdRaw > 0 ? thresholdRaw : 0;
    const allowCloseWithVariance = !(
        (settings as any)?.posAllowCloseShiftWithVariance === false ||
        (settings as any)?.posAllowCloseShiftWithVariance === 'false'
    );
    return { threshold, allowCloseWithVariance };
}

export async function handleGetPosShiftStatus() {
    const session = await getSession();
    if (!session?.user || (session.user.role !== 'admin' && session.user.role !== 'pos')) return { error: 'Unauthorized' };

    const sessions = await getPosShiftSessionsRuntime();
    const activeShift = sessions.find((entry) => entry.userId === session.user.id && entry.status === 'active') || null;
    const activeShiftAny = sessions.find((entry) => entry.status === 'active') || null;
    const lastClosedShift = sessions.find((entry) => entry.userId === session.user.id && entry.status === 'closed') || null;
    return { success: true, activeShift, activeShiftAny, lastClosedShift };
}

export async function handleGetEmployeeCashboxSummary(employeeCashAccountCode: string) {
    const session = await getSession();
    if (!session?.user || (session.user.role !== 'admin' && session.user.role !== 'pos')) return { error: 'Unauthorized' };

    const normalizedCode = String(employeeCashAccountCode || '').trim();
    if (!normalizedCode) {
        return {
            success: true,
            summary: {
                openingCash: 0,
                cashSalesAmount: 0,
                expectedCashAtClose: 0,
            },
        };
    }

    const journalEntries = await getJournalEntriesRuntime();
    let balance = 0;
    let cashSalesAmount = 0;

    journalEntries.forEach((entry: any) => {
        const referenceType = String(entry?.referenceType || '').trim().toLowerCase();
        (entry?.lines || []).forEach((line: any) => {
            if (String(line?.accountCode || '').trim() !== normalizedCode) return;

            const debit = Number(line?.debit || 0);
            const credit = Number(line?.credit || 0);
            balance += debit - credit;

            if (referenceType === 'sales_invoice' && debit > 0) {
                cashSalesAmount += debit;
            }
        });
    });

    const netCash = toMoney(balance);
    return {
        success: true,
        summary: {
            openingCash: netCash,
            cashSalesAmount: toMoney(cashSalesAmount),
            expectedCashAtClose: netCash,
        },
    };
}

export async function handleOpenPosShift(values: z.infer<typeof posShiftOpenSchema>) {
    const session = await getSession();
    if (!session?.user || (session.user.role !== 'admin' && session.user.role !== 'pos')) return { error: 'Unauthorized' };

    const parsed = posShiftOpenSchema.safeParse(values);
    if (!parsed.success) {
        return { error: 'Invalid data submitted.' };
    }

    const sessions = await getPosShiftSessionsRuntime();
    const currentUserId = String(session.user.id || '').trim();
    const activeShift = sessions.find((entry) => entry.userId === currentUserId && entry.status === 'active');
    if (activeShift) {
        return { error: 'POS_SHIFT_ALREADY_ACTIVE' };
    }

    const openingCash = toMoney(parsed.data.openingCash);
    const openingVisa = toMoney(parsed.data.openingVisa);
    const newShift: PosShiftSession = {
        id: await nextPrefixedIdRuntime('pos-shift'),
        userId: currentUserId,
        userName: String(session.user.name || session.user.username || '').trim() || String(session.user.id || ''),
        startedAt: new Date().toISOString(),
        status: 'active',
        openingCash,
        openingVisa,
        totalSalesAmount: 0,
        invoicesCount: 0,
        returnsCount: 0,
        cashSalesAmount: 0,
        visaSalesAmount: 0,
        receivablesAmount: 0,
        couponAmount: 0,
        expectedCashAtClose: openingCash,
        expectedVisaAtClose: openingVisa,
        notes: String(parsed.data.notes || '').trim() || undefined,
    };

    await savePosShiftSessionsRuntime([newShift, ...sessions]);
    revalidatePath('/admin/sales/pos');
    return { success: true, activeShift: newShift };
}

export async function handleClosePosShift(values: z.infer<typeof posShiftCloseSchema>) {
    const session = await getSession();
    if (!session?.user || (session.user.role !== 'admin' && session.user.role !== 'pos')) return { error: 'Unauthorized' };

    const parsed = posShiftCloseSchema.safeParse(values);
    if (!parsed.success) {
        return { error: 'Invalid data submitted.' };
    }

    const settings = await getSettingsRuntime();
    const { threshold, allowCloseWithVariance } = getShiftVariancePolicy(settings as Record<string, unknown>);
    const sessions = await getPosShiftSessionsRuntime();
    const activeIndex = sessions.findIndex((entry) => entry.userId === session.user.id && entry.status === 'active');
    if (activeIndex === -1) {
        return { error: 'POS_SHIFT_NOT_ACTIVE' };
    }

    const activeShift = sessions[activeIndex];
    const countedCash = toMoney(parsed.data.countedCash);
    const countedVisa = toMoney(parsed.data.countedVisa);
    const expectedCash = toMoney(activeShift.expectedCashAtClose);
    const expectedVisa = toMoney(activeShift.expectedVisaAtClose);
    const cashVariance = toMoney(countedCash - expectedCash);
    const visaVariance = toMoney(countedVisa - expectedVisa);
    const absTotalVariance = Math.abs(cashVariance) + Math.abs(visaVariance);
    const requiresApproval = threshold > 0 && absTotalVariance > threshold;

    if (!allowCloseWithVariance && absTotalVariance > 0.0001) {
        return { error: 'POS_SHIFT_VARIANCE_NOT_ALLOWED' };
    }

    const closedShift: PosShiftSession = {
        ...activeShift,
        status: 'closed',
        endedAt: new Date().toISOString(),
        countedCashAtClose: countedCash,
        countedVisaAtClose: countedVisa,
        cashVariance,
        visaVariance,
        requiresApproval,
        closeNotes: String(parsed.data.notes || '').trim() || undefined,
    };

    sessions[activeIndex] = closedShift;
    await savePosShiftSessionsRuntime(sessions);
    revalidatePath('/admin/sales/pos');

    return {
        success: true,
        closedShift,
        requiresApproval,
    };
}

async function applyInvoiceToActivePosShiftRuntime(params: {
    userId: string;
    grandTotal: number;
    amountPaid: number;
    paymentBreakdown: Array<{ method: 'cash' | 'visa' | 'receivables' | 'coupon'; amount: number }>;
    isReturn: boolean;
}) {
    const userId = String(params.userId || '').trim();
    if (!userId) return;

    const sessions = await getPosShiftSessionsRuntime();
    const activeIndex = sessions.findIndex((entry) => entry.userId === userId && entry.status === 'active');
    if (activeIndex === -1) return;

    const active = sessions[activeIndex];
    const sign = params.isReturn ? -1 : 1;
    const breakdown = Array.isArray(params.paymentBreakdown) ? params.paymentBreakdown : [];

    const cashFromBreakdown = breakdown
        .filter((line) => line.method === 'cash')
        .reduce((sum, line) => sum + Number(line.amount || 0), 0);
    const visaFromBreakdown = breakdown
        .filter((line) => line.method === 'visa')
        .reduce((sum, line) => sum + Number(line.amount || 0), 0);
    const receivablesFromBreakdown = breakdown
        .filter((line) => line.method === 'receivables')
        .reduce((sum, line) => sum + Number(line.amount || 0), 0);
    const couponFromBreakdown = breakdown
        .filter((line) => line.method === 'coupon')
        .reduce((sum, line) => sum + Number(line.amount || 0), 0);

    const hasBreakdown = breakdown.length > 0;
    const fallbackPaid = hasBreakdown ? 0 : Number(params.amountPaid || 0);
    const cashDelta = toMoney((cashFromBreakdown + fallbackPaid) * sign);
    const visaDelta = toMoney(visaFromBreakdown * sign);
    const receivablesDelta = toMoney(receivablesFromBreakdown * sign);
    const couponDelta = toMoney(couponFromBreakdown * sign);

    const nextShift: PosShiftSession = {
        ...active,
        totalSalesAmount: toMoney(Number(active.totalSalesAmount || 0) + (Number(params.grandTotal || 0) * sign)),
        invoicesCount: Math.max(0, Number(active.invoicesCount || 0) + 1),
        returnsCount: Math.max(0, Number(active.returnsCount || 0) + (params.isReturn ? 1 : 0)),
        cashSalesAmount: toMoney(Number(active.cashSalesAmount || 0) + cashDelta),
        visaSalesAmount: toMoney(Number(active.visaSalesAmount || 0) + visaDelta),
        receivablesAmount: toMoney(Number(active.receivablesAmount || 0) + receivablesDelta),
        couponAmount: toMoney(Number(active.couponAmount || 0) + couponDelta),
        expectedCashAtClose: toMoney(Number(active.expectedCashAtClose || 0) + cashDelta),
        expectedVisaAtClose: toMoney(Number(active.expectedVisaAtClose || 0) + visaDelta),
    };

    sessions[activeIndex] = nextShift;
    await savePosShiftSessionsRuntime(sessions);
}

const saleInvoiceSchema = z.object({
    customerId: z.string().optional().default(''),
    amountPaid: z.coerce.number().min(0).optional().default(0),
    restaurantTableId: z.string().optional().default(''),
    restaurantAreaId: z.string().optional().default(''),
    restaurantChannel: z.enum(['dine_in', 'takeaway', 'delivery']).optional().default('dine_in'),
    restaurantGuestCount: z.coerce.number().int().min(1).optional().default(1),
    payments: z.array(z.object({
            method: z.enum(['cash', 'visa', 'receivables', 'coupon']),
      amount: z.coerce.number().min(0),
      customerName: z.string().optional(),
      bankAccountId: z.string().optional(),
            couponCode: z.string().optional(),
    })).optional().default([]),
    discountAmount: z.coerce.number().min(0).optional().default(0),
    isReturn: z.coerce.boolean().optional().default(false),
  items: z.array(z.object({
    materialId: z.string().min(1),
    quantity: z.coerce.number().min(1),
    unitPrice: z.coerce.number().min(0),
        description: z.string().optional().default(''),
        discount: z.coerce.number().min(0).optional().default(0),
                itemUnitId: z.string().optional().default(''),
                serialNumber: z.string().optional().default(''),
                rfidCode: z.string().optional().default(''),
                warehouseId: z.string().optional().default(''),
                shelfId: z.string().optional().default(''),
                printSectionId: z.string().optional().default(''),
                printLabel: z.string().optional().default(''),
                excludeFromPrepTicket: z.coerce.boolean().optional().default(false),
  })).min(1, 'At least one item is required.'),
});

export async function handleCreateSaleInvoice(values: z.infer<typeof saleInvoiceSchema>) {
    const session = await getSession();
    if (!session?.user || (session.user.role !== 'admin' && session.user.role !== 'pos')) return { error: 'Unauthorized' };
    const locale = (await cookies()).get('NEXT_LOCALE')?.value ?? 'ar';

    const parsed = saleInvoiceSchema.safeParse(values);
    if (!parsed.success) {
        console.error(parsed.error.flatten());
        return { error: 'Invalid data submitted.' };
    }
    
        const { customerId: rawCustomerId, amountPaid: rawAmountPaid, payments: paymentBreakdown, discountAmount, items: formItems, isReturn, restaurantTableId, restaurantAreaId, restaurantChannel, restaurantGuestCount } = parsed.data;
        const normalizedPaymentBreakdown: Array<{ method: 'cash' | 'visa' | 'receivables' | 'coupon'; amount: number; couponCode?: string }> = (paymentBreakdown || [])
            .map((payment) => ({
                method: payment.method,
                amount: Number(payment.amount || 0),
                couponCode: String((payment as any).couponCode || '').trim() || undefined,
            }))
            .filter((payment) => payment.amount > 0);
    
    // Calculate total paid from either single amountPaid or breakdown array
        const amountPaid = normalizedPaymentBreakdown.length > 0
            ? normalizedPaymentBreakdown.reduce((sum, p) => sum + p.amount, 0)
      : Math.max(0, Number(rawAmountPaid || 0));
    
    const customerId = (rawCustomerId || '').trim();
    const isCashCustomer = customerId.length === 0;

    if (isCashCustomer && normalizedPaymentBreakdown.some((payment) => payment.method === 'receivables' && payment.amount > 0)) {
        return { error: 'Cash customer cannot have receivables amount.' };
    }

    const couponPayments = normalizedPaymentBreakdown
        .filter((payment) => payment.method === 'coupon' && payment.amount > 0)
        .map((payment) => ({
            couponCode: String(payment.couponCode || '').trim(),
            amount: Number(payment.amount || 0),
        }));
    let redeemedCouponApplications: Array<{ couponId: string; couponCode: string; amount: number; amountBase?: number }> = [];

    if (couponPayments.some((line) => !line.couponCode)) {
        return { error: 'Coupon code is required for coupon payment lines.' };
    }

    if (couponPayments.length > 0) {
        const redeemResult = await redeemCouponsRuntime({
            lines: couponPayments,
            referenceId: undefined,
            redeemedBy: session.user.name || 'admin',
        });
        if (!redeemResult.success) {
            const code = String(redeemResult.error || 'COUPON_REDEEM_FAILED');
            if (code.startsWith('COUPON_NOT_FOUND')) {
                return { error: 'أحد الكوبونات غير موجود.' };
            }
            if (code.startsWith('COUPON_NOT_ACTIVE')) {
                return { error: 'أحد الكوبونات غير نشط.' };
            }
            if (code.startsWith('COUPON_EXPIRED')) {
                return { error: 'أحد الكوبونات منتهي الصلاحية.' };
            }
            if (code.startsWith('COUPON_INSUFFICIENT')) {
                return { error: 'رصيد أحد الكوبونات غير كاف.' };
            }
            return { error: 'تعذر استخدام الكوبون حالياً. حاول مرة أخرى.' };
        }
        redeemedCouponApplications = (redeemResult.applied || []) as Array<{ couponId: string; couponCode: string; amount: number; amountBase?: number }>;
    }

    // --- Recalculate server-side to ensure data integrity ---
    const allCustomers = await getCustomersRuntime();
    const customer = isCashCustomer ? undefined : allCustomers.find(c => c.id === customerId);
    if (!isCashCustomer && !customer) return { error: 'Customer not found.' };
    const salesRepId = customer?.salesRepId || '';

    const materials = await getMaterialsRuntime();
    const allPricing = await getCustomerPricingForCalc();
    const allItemUnits = getItemUnits();
    const settings = await getSettingsRuntime();
    const requireOpenShift = !(
        (settings as any)?.posRequireOpenShift === false ||
        (settings as any)?.posRequireOpenShift === 'false'
    );
    const activePosShift = requireOpenShift
        ? await getActivePosShiftSessionForUserRuntime(String(session.user.id || '').trim())
        : null;
    if (requireOpenShift && !activePosShift) {
        return { error: 'POS_SHIFT_REQUIRED' };
    }
    const warehousesEnabled = settings.warehousesEnabled === true || settings.warehousesEnabled === 'true';
    const allowOutOfStockSales = settings.allowOutOfStockSales === true || settings.allowOutOfStockSales === 'true';
    const defaultSalesWarehouseId = String(settings.defaultSalesWarehouseId || '').trim();
    const defaultSalesShelfId = String(settings.defaultSalesShelfId || '').trim();
    const allowedWarehouseIds = session.user.role === 'admin'
        ? null
        : new Set((session.user.warehouseIds || []).map((warehouseId) => String(warehouseId).trim()).filter(Boolean));
    if (warehousesEnabled && !isReturn && session.user.role !== 'admin' && (!allowedWarehouseIds || allowedWarehouseIds.size === 0)) {
        return {
            error:
                locale === 'ar'
                    ? 'لا توجد مستودعات مسموح بها مهيأة للمستخدم الحالي.'
                    : 'No allowed warehouses are configured for the current user.',
        };
    }
    const itemUnitById = new Map(allItemUnits.map((unit) => [unit.id, unit]));
    const customerCategory = customer?.category || 'general';
    const customerPricing = allPricing.find(p => p.category === customerCategory);
    const stockLocationsReport = warehousesEnabled && !isReturn && !allowOutOfStockSales
        ? getStockLocationsByMaterial(Array.from(new Set(formItems.map((item) => item.materialId))))
        : [];
    const availableLocationsByMaterial = new Map(
        stockLocationsReport.map((entry) => [
            entry.materialId,
            (entry.locations || []).filter(
                (location) =>
                    Number(location.quantity || 0) > 0 &&
                    (session.user.role === 'admin' || !!allowedWarehouseIds?.has(location.warehouseId))
            ),
        ])
    );
    const reservedQtyByLocation = new Map<string, number>();

    const signMultiplier = isReturn ? -1 : 1;
    let calculatedItems: SalesInvoiceItem[] = [];
    try {
      calculatedItems = formItems.map(item => {
        const material = materials.find(m => m.id === item.materialId);
        if (!material) throw new Error(`Material with ID ${item.materialId} not found`);

        const requiresTrackedUnit = material.hasSerialNumber === true || material.hasRfid === true;
        const normalizedUnitId = String(item.itemUnitId || '').trim();
        const selectedUnit = normalizedUnitId ? itemUnitById.get(normalizedUnitId) : undefined;

        if (requiresTrackedUnit) {
            if (!normalizedUnitId || !selectedUnit) {
                throw new Error(`Tracked unit is required for item ${material.name}`);
            }
            if (selectedUnit.itemId !== item.materialId) {
                throw new Error(`Tracked unit does not belong to item ${material.name}`);
            }
            if (!isReturn && selectedUnit.status === 'sold') {
                throw new Error(`Tracked unit already sold for item ${material.name}`);
            }
            if (Number(item.quantity || 0) !== 1) {
                throw new Error(`Tracked items must be sold with quantity 1 per line: ${material.name}`);
            }
        }

        const unitPrice = item.unitPrice;
        const lineSubtotal = item.quantity * unitPrice;
        const lineDiscount = Math.min(Math.max(Number(item.discount || 0), 0), lineSubtotal);
        const normalizedDescription = (item.description || '').trim();

        let bonus = 0;
        const bonusRule = customerPricing?.bonus;
        if (!isReturn && bonusRule && bonusRule.materialId === item.materialId && bonusRule.buyQuantity > 0 && item.quantity > 0) {
            bonus = Math.floor(item.quantity / bonusRule.buyQuantity) * bonusRule.bonusQuantity;
        }

        let resolvedWarehouseId = String(item.warehouseId || '').trim();
        let resolvedShelfId = String(item.shelfId || '').trim();

        if (warehousesEnabled && !isReturn && allowOutOfStockSales) {
            if (!resolvedWarehouseId && defaultSalesWarehouseId) {
                resolvedWarehouseId = defaultSalesWarehouseId;
            }
            if (!resolvedShelfId && defaultSalesShelfId) {
                resolvedShelfId = defaultSalesShelfId;
            }
        }

        if (warehousesEnabled && !isReturn && !allowOutOfStockSales) {
            const availableLocations = availableLocationsByMaterial.get(item.materialId) || [];

            if (availableLocations.length === 0) {
                throw new Error(`No stock available for item ${material.name}`);
            }

            if ((!resolvedWarehouseId || !resolvedShelfId) && availableLocations.length === 1) {
                resolvedWarehouseId = availableLocations[0].warehouseId;
                resolvedShelfId = availableLocations[0].shelfId;
            }

            if (!resolvedWarehouseId || !resolvedShelfId) {
                throw new Error(`Shelf source is required for item ${material.name}`);
            }

            const selectedLocation = availableLocations.find(
                (location) => location.warehouseId === resolvedWarehouseId && location.shelfId === resolvedShelfId
            );

            if (!selectedLocation) {
                throw new Error(`Selected shelf is not available for item ${material.name}`);
            }

            const locationKey = `${item.materialId}||${resolvedWarehouseId}||${resolvedShelfId}`;
            const nextReservedQty = (reservedQtyByLocation.get(locationKey) || 0) + Number(item.quantity || 0);
            if (nextReservedQty > Number(selectedLocation.quantity || 0)) {
                throw new Error(`Insufficient stock on selected shelf for item ${material.name}`);
            }
            reservedQtyByLocation.set(locationKey, nextReservedQty);
        }

        return {
            materialId: item.materialId,
            name: material.name,
            description: normalizedDescription || undefined,
                        itemUnitId: selectedUnit?.id,
                        serialNumber: selectedUnit?.serialNumber,
                        rfidCode: selectedUnit?.rfidCode,
            quantity: item.quantity,
            unitPrice,
            bonus,
            discount: lineDiscount,
            total: (lineSubtotal - lineDiscount) * signMultiplier,
            warehouseId: resolvedWarehouseId || undefined,
            shelfId: resolvedShelfId || undefined,
            printSectionId: String(item.printSectionId || material.printSectionId || '').trim() || undefined,
            printLabel: String(item.printLabel || material.printLabelOverride || '').trim() || undefined,
            excludeFromPrepTicket: item.excludeFromPrepTicket === true || material.excludeFromPrepTicket === true || undefined,
        };
            });
        } catch (error: any) {
            return { error: error?.message || 'Invalid serial/RFID selection.' };
        }

    let totalCampaignDiscountAmount = 0;

    if (!isReturn) {
        const activeCampaigns = await getActiveCampaignsRuntime(new Date().toISOString());
        const customerScopeTag = String(customer?.category || '').trim().toLowerCase();
        const applicableCampaigns = (activeCampaigns || []).filter((campaign: any) => {
            if (session.user.role === 'pos' && campaign?.autoApplyInPos === false) return false;
            const tags = Array.isArray(campaign?.customerTags)
                ? campaign.customerTags.map((value: any) => String(value || '').trim().toLowerCase()).filter(Boolean)
                : [];
            if (tags.length === 0 || tags.includes('all')) return true;
            if (!customerScopeTag) return false;
            return tags.includes(customerScopeTag);
        });
        if (applicableCampaigns.length > 0) {
            const campaignApplied = applyMultiBuyCampaigns({
                items: calculatedItems,
                activeCampaigns: applicableCampaigns as Array<Record<string, any>>,
                materials: materials as Array<Record<string, any>>,
            });
            totalCampaignDiscountAmount = roundCurrencyAmount(Math.max(0, Number(campaignApplied.totalCampaignDiscount || 0)));
            calculatedItems = campaignApplied.items.map((item) => {
                const lineSubtotal = Math.max(0, Number(item.quantity || 0) * Number(item.unitPrice || 0));
                const lineDiscount = Math.min(Math.max(Number(item.discount || 0), 0), lineSubtotal);
                return {
                    ...item,
                    discount: lineDiscount,
                    total: lineSubtotal - lineDiscount,
                };
            });
            if (campaignApplied.logs.length > 0) {
                console.log('[Campaigns Applied]', campaignApplied.logs.join(' | '));
            }
        }
    }

    const itemsSubTotal = calculatedItems.reduce((sum, item) => sum + Math.abs(item.total), 0);
    const bonusAmount = calculatedItems.reduce((sum, item) => sum + (item.bonus ? item.bonus * item.unitPrice : 0), 0);
    const safeDiscountAmount = Math.min(Math.max(Number(discountAmount || 0), 0), itemsSubTotal);
    const grandTotalBase = itemsSubTotal - safeDiscountAmount;
    const subTotal = isReturn ? -itemsSubTotal : itemsSubTotal;
    const grandTotal = isReturn ? -grandTotalBase : grandTotalBase;
    const amountDue = grandTotal - amountPaid;
    if (isCashCustomer && Math.abs(amountDue) > 0.0001) {
        return { error: 'Cash customer requires amount due to be 0.00.' };
    }

    // --- Update customer balance ---
    if (!isCashCustomer && customer) {
        customer.balance += amountDue;
        await saveCustomersRuntime(allCustomers);
    }
    
    // --- Create and save invoice record ---
    const cashCustomerId = 'cash';
    const cashCustomerName = locale === 'ar' ? 'زبون نقدي' : 'Cash Customer';
    const invoiceDate = new Date().toISOString();
    let invoice: SalesInvoice;

    if (isPostgresProviderEnabled()) {
        const { items: existingInvoices } = await pgGetInvoices({ page: 1, pageSize: 10000 });
        const currentYear = new Date().getFullYear();
        const currentYearInvoices = (existingInvoices || []).filter((entry: any) => {
            const invoiceNumber = String(entry?.invoiceNumber || '');
            const parts = invoiceNumber.split('/');
            if (parts.length < 3) return false;
            return Number(parts[1]) === currentYear;
        });
        const nextSequence = currentYearInvoices.length + 1;
        const sequenceStr = String(nextSequence).padStart(4, '0');
        const invoiceNumber = `S/${currentYear}/${sequenceStr}`;
        const invoiceId = `inv-${Date.now()}-${Math.floor(Math.random() * 1_000_000)}`;

        invoice = {
            _type: 'sales-invoice',
            id: invoiceId,
            invoiceNumber,
            date: invoiceDate,
            customerId: isCashCustomer ? cashCustomerId : customerId,
            customerName: isCashCustomer ? cashCustomerName : customer?.name || cashCustomerName,
            salesRepId: isCashCustomer ? '' : salesRepId,
            type: isReturn ? 'return' : 'sale',
            documentType: 'tax_invoice',
            items: calculatedItems,
            subTotal,
            grandTotal,
            discountAmount: safeDiscountAmount,
            campaignDiscountAmount: totalCampaignDiscountAmount || undefined,
            amountPaid,
            amountDue,
            status: 'active',
            postingStatus: 'posted',
            createdBy: session.user.name || 'admin',
            createdAt: invoiceDate,
            lockedBy: undefined,
            lockedAt: undefined,
            cancelledAt: undefined,
            cancelledBy: undefined,
            cancelledReason: undefined,
        } as SalesInvoice;

        await pgSaveInvoices([invoice as unknown as Record<string, unknown>]);
    } else {
        invoice = addInvoice({
            date: invoiceDate,
            customerId: isCashCustomer ? cashCustomerId : customerId,
            customerName: isCashCustomer ? cashCustomerName : customer?.name || cashCustomerName,
            salesRepId: isCashCustomer ? '' : salesRepId,
            type: isReturn ? 'return' : 'sale',
            postingStatus: 'posted',
            items: calculatedItems,
            subTotal,
            grandTotal,
            discountAmount: safeDiscountAmount,
            campaignDiscountAmount: totalCampaignDiscountAmount || undefined,
            amountPaid,
            amountDue,
            createdBy: session.user.name || 'admin',
        });
    }

    const normalizedRestaurantTableId = String(restaurantTableId || '').trim();
    if (normalizedRestaurantTableId) {
        const normalizedRestaurantAreaId = String(restaurantAreaId || '').trim() || undefined;
        const normalizedRestaurantChannel = restaurantChannel || 'dine_in';
        const normalizedRestaurantGuestCount = Math.max(1, Number(restaurantGuestCount || 1));
        const restaurantSessionId = `rst-sess-${invoice.id}`;
        const restaurantSessionNumber = String(invoice.invoiceNumber || invoice.id || restaurantSessionId).trim();
        const restaurantNow = new Date().toISOString();
        const pool = getPgPool();
        const client = await pool.connect();
        try {
            await client.query('BEGIN');
            await client.query(
                `UPDATE restaurant_tables SET status = 'occupied', area_id = COALESCE(area_id, $2), updated_at = NOW() WHERE id = $1`,
                [normalizedRestaurantTableId, normalizedRestaurantAreaId || null]
            );
            await client.query(
                `
                INSERT INTO restaurant_order_sessions (
                    id, session_number, channel, area_id, table_id, invoice_id, guest_count, status, started_at, closed_at, raw, created_at, updated_at
                ) VALUES (
                    $1, $2, $3, $4, $5, $6, $7, 'closed', $8, $9, $10::jsonb, NOW(), NOW()
                )
                ON CONFLICT (id) DO UPDATE SET
                    session_number = EXCLUDED.session_number,
                    channel = EXCLUDED.channel,
                    area_id = EXCLUDED.area_id,
                    table_id = EXCLUDED.table_id,
                    invoice_id = EXCLUDED.invoice_id,
                    guest_count = EXCLUDED.guest_count,
                    status = EXCLUDED.status,
                    closed_at = EXCLUDED.closed_at,
                    raw = EXCLUDED.raw,
                    updated_at = NOW()
                `,
                [
                    restaurantSessionId,
                    restaurantSessionNumber,
                    normalizedRestaurantChannel,
                    normalizedRestaurantAreaId || null,
                    normalizedRestaurantTableId,
                    invoice.id,
                    normalizedRestaurantGuestCount,
                    restaurantNow,
                    restaurantNow,
                    JSON.stringify({
                        source: 'pos',
                        invoiceId: invoice.id,
                        invoiceNumber: invoice.invoiceNumber,
                        customerId: customerId || undefined,
                        customerName: customer?.name,
                        paymentStatus,
                        totalAmount: grandTotal,
                        guestCount: normalizedRestaurantGuestCount,
                        tableId: normalizedRestaurantTableId,
                        areaId: normalizedRestaurantAreaId,
                        channel: normalizedRestaurantChannel,
                    }),
                ]
            );
            await client.query(
                `
                INSERT INTO restaurant_table_events (
                    id, session_id, table_id, event_type, event_at, actor_name, actor_id, reason, payload, created_at
                ) VALUES (
                    $1, $2, $3, 'session_opened', $4, $5, $6, $7, $8::jsonb, NOW()
                )
                ON CONFLICT (id) DO UPDATE SET
                    session_id = EXCLUDED.session_id,
                    table_id = EXCLUDED.table_id,
                    event_type = EXCLUDED.event_type,
                    event_at = EXCLUDED.event_at,
                    actor_name = EXCLUDED.actor_name,
                    actor_id = EXCLUDED.actor_id,
                    reason = EXCLUDED.reason,
                    payload = EXCLUDED.payload
                `,
                [
                    `rst-evt-${invoice.id}-opened`,
                    restaurantSessionId,
                    normalizedRestaurantTableId,
                    restaurantNow,
                    session.user.name || session.user.username || 'POS',
                    session.user.id || '',
                    'POS sale saved',
                    JSON.stringify({
                        invoiceId: invoice.id,
                        invoiceNumber: invoice.invoiceNumber,
                        status: invoice.status,
                    }),
                ]
            );
            await client.query(
                `
                INSERT INTO restaurant_table_events (
                    id, session_id, table_id, event_type, event_at, actor_name, actor_id, reason, payload, created_at
                ) VALUES (
                    $1, $2, $3, 'session_closed', $4, $5, $6, $7, $8::jsonb, NOW()
                )
                ON CONFLICT (id) DO UPDATE SET
                    session_id = EXCLUDED.session_id,
                    table_id = EXCLUDED.table_id,
                    event_type = EXCLUDED.event_type,
                    event_at = EXCLUDED.event_at,
                    actor_name = EXCLUDED.actor_name,
                    actor_id = EXCLUDED.actor_id,
                    reason = EXCLUDED.reason,
                    payload = EXCLUDED.payload
                `,
                [
                    `rst-evt-${invoice.id}-closed`,
                    restaurantSessionId,
                    normalizedRestaurantTableId,
                    restaurantNow,
                    session.user.name || session.user.username || 'POS',
                    session.user.id || '',
                    'POS sale finalized',
                    JSON.stringify({
                        invoiceId: invoice.id,
                        invoiceNumber: invoice.invoiceNumber,
                        status: invoice.status,
                    }),
                ]
            );
            await client.query(`UPDATE restaurant_tables SET status = 'available', updated_at = NOW() WHERE id = $1`, [normalizedRestaurantTableId]);
            await client.query('COMMIT');
        } catch (restaurantError) {
            await client.query('ROLLBACK');
            console.error('Restaurant session persistence failed:', restaurantError);
        } finally {
            client.release();
        }
    }

        const trackedUnitIds = calculatedItems
            .map((line) => String(line.itemUnitId || '').trim())
            .filter(Boolean);
        if (trackedUnitIds.length > 0) {
            updateItemUnitsStatusByIds(trackedUnitIds, isReturn ? 'returned' : 'sold', invoice.id);
        }

    // --- Create journal entries with linked entry IDs ---
    // Generate a base entry ID that will be used for all related journal entries
    const baseEntryId = isPostgresProviderEnabled()
        ? `JE-${Date.now()}-${Math.floor(Math.random() * 1_000_000)}`
        : (() => {
            const { generateUniqueSequentialNumber } = require('./data') as typeof import('./data');
            return `JE-${generateUniqueSequentialNumber()}`;
        })();
    
    // If using payment breakdown, don't include amountPaid here (it will be handled separately)
    const amountPaidForInvoiceJE = normalizedPaymentBreakdown.length > 0 ? 0 : amountPaid;
    const grossRevenueTotal = Math.abs(grandTotal) + safeDiscountAmount + totalCampaignDiscountAmount + bonusAmount;

    const couponFxByCode = new Map<string, { couponId: string; deltaBase: number }>();
    if (!isReturn && couponPayments.length > 0 && redeemedCouponApplications.length > 0) {
        const currentByCode = new Map<string, number>();
        couponPayments.forEach((line) => {
            const code = String(line.couponCode || '').trim().toLowerCase();
            if (!code) return;
            currentByCode.set(code, (currentByCode.get(code) || 0) + Number(line.amount || 0));
        });

        const historicalByCode = new Map<string, { couponId: string; amountBase: number }>();
        redeemedCouponApplications.forEach((line) => {
            const code = String(line.couponCode || '').trim().toLowerCase();
            if (!code) return;
            const amountBase = Number.isFinite(Number(line.amountBase)) ? Number(line.amountBase) : Number(line.amount || 0);
            const prev = historicalByCode.get(code);
            if (prev) {
                historicalByCode.set(code, { couponId: prev.couponId, amountBase: prev.amountBase + amountBase });
            } else {
                historicalByCode.set(code, { couponId: String(line.couponId || '').trim(), amountBase });
            }
        });

        historicalByCode.forEach((hist, code) => {
            const currentBase = Number(currentByCode.get(code) || 0);
            const deltaBase = currentBase - Number(hist.amountBase || 0);
            if (Math.abs(deltaBase) > 0.0000001 && hist.couponId) {
                couponFxByCode.set(code, { couponId: hist.couponId, deltaBase });
            }
        });
    }
    
    try {
        const accounts = await getChartOfAccountsRuntime();
        const couponAccounting = await ensureCouponAccountingSetup();
        const salesDiscountAccounting = await ensureSalesDiscountAccountingSetup();
        const revenueBreakdown = !isReturn
            ? buildRevenueBreakdownForSalesInvoice({
                items: calculatedItems,
                materials: materials as Array<Record<string, any>>,
                accounts: accounts as Array<Record<string, any>>,
                grossTotal: grossRevenueTotal,
            })
            : [];
        const customerArCode = String((customer as any)?.accountCode || '').trim();
        const customerArAccount = customerArCode
            ? (accounts as Array<Record<string, any>>).find((acc) => String(acc?.code || '').trim() === customerArCode)
            : null;
        const employeeCashCode = String((session.user as any)?.employeeCashAccountCode || '').trim();
        const employeeCashAccount = employeeCashCode
            ? (accounts as Array<Record<string, any>>).find((acc) => String(acc?.code || '').trim() === employeeCashCode)
            : null;

        const journalEntries = await getJournalEntriesRuntime();
        const newEntry = await buildSalesInvoiceJournalEntryRecord({
            entryId: `${baseEntryId}-1`,
            invoiceId: invoice.invoiceNumber,
            customerName: isCashCustomer ? cashCustomerName : customer?.name || cashCustomerName,
            customerAccountCode: customerArCode || undefined,
            customerAccountName: customerArAccount ? String(customerArAccount.nameAr || customerArAccount.nameEn || '') : undefined,
            cashAccountCode: employeeCashCode || undefined,
            cashAccountName: employeeCashAccount ? String(employeeCashAccount.nameAr || employeeCashAccount.nameEn || '') : undefined,
            grandTotal,
            discountAmount: safeDiscountAmount,
            campaignDiscountAmount: totalCampaignDiscountAmount,
            bonusAmount,
            amountPaid: amountPaidForInvoiceJE,
            createdBy: session.user.name || 'admin',
            isReturn,
            paymentBreakdown: normalizedPaymentBreakdown,
            couponLiabilityAccountCode: couponAccounting.couponLiabilityAccountCode,
            couponLiabilityAccountName: couponAccounting.couponLiabilityAccountName,
            revenueBreakdown,
            salesDiscountAccountCode: salesDiscountAccounting.salesDiscountAccountCode,
            salesDiscountAccountName: salesDiscountAccounting.salesDiscountAccountName,
            campaignDiscountAccountCode: salesDiscountAccounting.campaignDiscountAccountCode,
            campaignDiscountAccountName: salesDiscountAccounting.campaignDiscountAccountName,
            bonusDiscountAccountCode: salesDiscountAccounting.bonusDiscountAccountCode,
            bonusDiscountAccountName: salesDiscountAccounting.bonusDiscountAccountName,
            salesReturnAccountCode: salesDiscountAccounting.salesReturnAccountCode,
            salesReturnAccountName: salesDiscountAccounting.salesReturnAccountName,
        });
        journalEntries.unshift(newEntry);

        const couponCurrentSettlementBase = couponPayments.reduce((sum, line) => sum + Number(line.amount || 0), 0);
        const couponHistoricalSettlementBase = redeemedCouponApplications.reduce(
            (sum, line) => sum + (Number.isFinite(Number(line.amountBase)) ? Number(line.amountBase) : Number(line.amount || 0)),
            0,
        );
        const couponFxDifferenceBase = couponCurrentSettlementBase - couponHistoricalSettlementBase;

        if (!isReturn && Math.abs(couponFxDifferenceBase) > 0.0001) {
            const fxAmount = Math.abs(couponFxDifferenceBase);
            const fxEntryId = `${baseEntryId}-coupon-fx`;
            const nowIso = new Date().toISOString();
            const isLoss = couponFxDifferenceBase > 0;
            const fxEntry: JournalEntry = {
                id: fxEntryId,
                date: nowIso,
                createdAt: nowIso,
                description: `تسوية فروقات عملة الكوبونات لفاتورة ${invoice.invoiceNumber}`,
                referenceType: 'sales_invoice',
                referenceId: invoice.invoiceNumber,
                createdBy: session.user.name || 'admin',
                lines: isLoss
                    ? [
                        {
                            accountId: couponAccounting.fxLossAccountCode,
                            accountCode: couponAccounting.fxLossAccountCode,
                            accountName: couponAccounting.fxLossAccountName,
                            debit: fxAmount,
                            credit: 0,
                            description: `خسارة فروقات عملة لتسوية الكوبونات - فاتورة ${invoice.invoiceNumber}`,
                        },
                        {
                            accountId: couponAccounting.couponLiabilityAccountCode,
                            accountCode: couponAccounting.couponLiabilityAccountCode,
                            accountName: couponAccounting.couponLiabilityAccountName,
                            debit: 0,
                            credit: fxAmount,
                            description: `تصحيح رصيد التزام الكوبونات - فاتورة ${invoice.invoiceNumber}`,
                        },
                    ]
                    : [
                        {
                            accountId: couponAccounting.couponLiabilityAccountCode,
                            accountCode: couponAccounting.couponLiabilityAccountCode,
                            accountName: couponAccounting.couponLiabilityAccountName,
                            debit: fxAmount,
                            credit: 0,
                            description: `تصحيح رصيد التزام الكوبونات - فاتورة ${invoice.invoiceNumber}`,
                        },
                        {
                            accountId: couponAccounting.fxGainAccountCode,
                            accountCode: couponAccounting.fxGainAccountCode,
                            accountName: couponAccounting.fxGainAccountName,
                            debit: 0,
                            credit: fxAmount,
                            description: `ربح فروقات عملة لتسوية الكوبونات - فاتورة ${invoice.invoiceNumber}`,
                        },
                    ],
            };

            journalEntries.unshift(fxEntry);
        }

        await saveJournalEntriesRuntime(journalEntries);

        if (couponFxByCode.size > 0) {
            for (const [, fx] of couponFxByCode.entries()) {
                await applyCouponFxDifferenceRuntime(fx.couponId, fx.deltaBase, invoice.invoiceNumber);
            }
        }
    } catch (error) {
        console.error('Failed to create journal entry:', error);
        // Continue anyway - invoice was created successfully
    }

    try {
        await syncRealEstateUnitSaleAccountingEntry({
            invoice,
            customerName: isCashCustomer ? cashCustomerName : customer?.name || cashCustomerName,
            createdBy: session.user.name || 'admin',
        });
    } catch (error) {
        console.error('Failed to sync real-estate sale accounting:', error);
    }

    // Mixed payment methods are now represented in the invoice journal entry itself.

    if (activePosShift) {
        await applyInvoiceToActivePosShiftRuntime({
            userId: String(session.user.id || '').trim(),
            grandTotal,
            amountPaid,
            paymentBreakdown: normalizedPaymentBreakdown,
            isReturn,
        });
    }

    revalidatePath('/admin/sales');
    revalidatePath('/admin/sales/pos');
    revalidatePath('/admin/production');
    revalidatePath('/admin/data/customers');
    revalidatePath('/admin/sales/statement');
    
    return { success: true };
}

const checkItemSchema = z.object({
  id: z.string(),
  checkNumber: z.string(),
  bankId: z.string(),
  bankName: z.string(),
  checkDate: z.string(),
  currency: z.string(),
    amount: z.coerce.number().min(0.01, 'Check amount must be positive.'),
});

const customerPaymentSchema = z.object({
  customerId: z.string().min(1, 'Customer is required.'),
  amount: z.coerce.number().min(0.01, 'Amount must be positive.'),
  paymentMethod: z.string().optional().default('cash'),
  checks: z.array(checkItemSchema).optional().default([]),
});

export async function handleCustomerPayment(values: z.infer<typeof customerPaymentSchema>) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const parsed = customerPaymentSchema.safeParse(values);
    if (!parsed.success) {
        return { error: 'Invalid data submitted.' };
    }
    
    const { customerId, amount, paymentMethod, checks } = parsed.data;

    if (paymentMethod === 'check') {
        if (!checks || checks.length === 0) {
            return { error: 'At least one check is required.' };
        }
    }

    const defaultCurrency = getDefaultCurrency();
    const baseCurrencyCode = defaultCurrency?.code || 'JOD';
    const convertedAmount = amount; // Customer payments are recorded in base currency.

    const customers = await getCustomersRuntime();
    const customer = customers.find(c => c.id === customerId);
    if (!customer) {
        return { error: 'Customer not found.' };
    }

    const payment = addPayment({
        date: new Date().toISOString(),
        customerId,
        amount,
        salesRepId: customer?.salesRepId || '',
    });

    const success = updateCustomerBalance(customerId, -convertedAmount); // Subtract from balance
    if (!success) {
        return { error: 'Customer not found.' };
    }

    // --- Create journal entry for this payment ---
    try {
        const firstCheckBankId = paymentMethod === 'check' && checks && checks.length > 0 ? checks[0].bankId : undefined;
        if (paymentMethod === 'check' && firstCheckBankId) {
            const checkBank = await getBankByIdForCalc(firstCheckBankId);
            if (!checkBank?.accountCode) {
                return { error: 'Selected bank is not linked to a chart-of-accounts account.' };
            }
        }

        // If employee has a dedicated checks account and this is a check payment,
        // route the debit to the employee's checks account instead of the bank account.
        const employeeChecksCode = paymentMethod === 'check'
            ? String((session.user as any)?.employeeChecksAccountCode || '').trim()
            : '';

        if (paymentMethod === 'check' && employeeChecksCode) {
            const accounts = await getChartOfAccountsRuntime();
            const checksAccount = (accounts as Array<Record<string, any>>).find(
                (acc) => String(acc?.code || '').trim() === employeeChecksCode
            );
            const customerArCode = String((customer as any)?.accountCode || '1150').trim();
            const customerArAccount = (accounts as Array<Record<string, any>>).find(
                (acc) => String(acc?.code || '').trim() === customerArCode
            );
            const jeEntry: JournalEntry = {
                id: nextPrefixedId('je-chkpmt'),
                date: new Date().toISOString(),
                description: `قيد سند قبض شيك رقم ${payment.id} - ${customer.name}`,
                referenceType: 'payment',
                referenceId: payment.id,
                lines: [
                    {
                        accountId: employeeChecksCode,
                        accountCode: employeeChecksCode,
                        accountName: String(checksAccount?.nameAr || `شيكات واردة موظف`),
                        debit: convertedAmount,
                        credit: 0,
                        description: `شيك وارد من العميل ${customer.name}`,
                    },
                    {
                        accountId: customerArCode,
                        accountCode: customerArCode,
                        accountName: String(customerArAccount?.nameAr || 'العملاء'),
                        debit: 0,
                        credit: convertedAmount,
                        description: `تحصيل من العميل ${customer.name}`,
                    },
                ],
                createdBy: session.user.name || 'admin',
                createdAt: new Date().toISOString(),
            };
            const journalEntries = await getJournalEntriesRuntime();
            journalEntries.unshift(jeEntry);
            await saveJournalEntriesRuntime(journalEntries);
        } else {
            createCustomerPaymentJournalEntry(
                payment.id,
                customerId,
                customer.name,
                convertedAmount,
                session.user.name || 'admin',
                {
                    paymentMethod: paymentMethod as any,
                    bankId: firstCheckBankId,
                }
            );
        }
    } catch (error) {
        console.error('Failed to create journal entry:', error);
        // Continue anyway - payment was recorded successfully
    }

    // --- If payment method is check, save all checks to checks_received ---
    if (paymentMethod === 'check' && checks && checks.length > 0) {
        try {
            const { addIncomingCheck } = await import('./data');
            for (const check of checks) {
                const bank = await getBankByIdForCalc(check.bankId);
                if (!bank) {
                    console.error(`Bank not found for check ${check.checkNumber}`);
                    continue;
                }

                const checkCurrency = check.currency || baseCurrencyCode;
                const checkAmount = Number(check.amount || 0);
                const checkExchangeRate = checkCurrency === baseCurrencyCode
                    ? 1
                    : getExchangeRate(checkCurrency, baseCurrencyCode);
                addIncomingCheck({
                    checkNumber: check.checkNumber,
                    bankId: check.bankId,
                    bankName: bank.name,
                    checkDate: check.checkDate,
                    amount: checkAmount,
                    currency: checkCurrency,
                    convertedAmount: checkAmount * checkExchangeRate,
                    exchangeRate: checkExchangeRate,
                    customerId,
                    customerName: customer.name,
                    reference: `Payment #${payment.id}`,
                    status: 'pending',
                    notes: '',
                    createdBy: session.user.name || 'admin',
                });
            }
        } catch (error) {
            console.error('Failed to save checks:', error);
            // Continue anyway - payment was recorded successfully
        }
    }

    revalidatePath('/admin/sales/payment');
    revalidatePath('/admin/data/customers');
    revalidatePath('/admin/sales/statement');
    
    return { success: true };
}

const supplierAllocationSchema = z.object({
    purchaseOrderId: z.string().min(1, 'Invoice is required.'),
    amount: z.coerce.number().min(0.01, 'Amount must be positive.'),
});

const supplierPaymentSchema = z.object({
    supplierId: z.string().min(1, 'Supplier is required.'),
    amount: z.coerce.number().min(0.01, 'Amount must be positive.'),
    paymentMethod: z.string().optional().default('cash'),
    reference: z.string().optional(),
    notes: z.string().optional(),
    currencyCode: z.string().optional(),
    exchangeRate: z.coerce.number().positive().optional(),
    rateDate: z.string().optional(),
    isAdvance: z.coerce.boolean().optional().default(false),
    checkSource: z.enum(['issued', 'incoming']).optional().default('issued'),
    incomingCheckIds: z.array(z.string()).optional().default([]),
    postingStatus: z.enum(['draft', 'saved', 'posted']).optional().default('posted'),
    allocations: z.array(supplierAllocationSchema).optional().default([]),
    checks: z.array(z.object({
        id: z.string(),
        checkNumber: z.string(),
        bankId: z.string(),
        bankName: z.string(),
        checkDate: z.string(),
        currency: z.string(),
        amount: z.coerce.number().min(0.01).optional(),
    })).optional().default([]),
});

export async function handleSupplierPayment(values: z.infer<typeof supplierPaymentSchema>) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const parsed = supplierPaymentSchema.safeParse(values);
    if (!parsed.success) {
        return { error: 'Invalid data submitted.' };
    }

    const { supplierId, amount, paymentMethod, reference, notes, checks, checkSource, incomingCheckIds, currencyCode, exchangeRate, rateDate, isAdvance, postingStatus, allocations } = parsed.data;

    if (paymentMethod === 'check') {
        if (checkSource === 'incoming') {
            if (!incomingCheckIds || incomingCheckIds.length === 0) {
                return { error: 'At least one incoming check must be selected.' };
            }
        } else if (!checks || checks.length === 0) {
            return { error: 'At least one check is required.' };
        }
    }

    const defaultCurrency = getDefaultCurrency();
    const baseCurrencyCode = defaultCurrency?.code || 'JOD';
    const paymentCurrency = currencyCode || baseCurrencyCode;
    const paymentExchangeRate = paymentCurrency === baseCurrencyCode
        ? 1
        : (exchangeRate && exchangeRate > 0 ? exchangeRate : getExchangeRate(paymentCurrency, baseCurrencyCode));
    const paymentAmountBase = amount * paymentExchangeRate;

    const suppliers = await getSuppliersRuntime();
    const supplier = suppliers.find(s => s.id === supplierId);
    if (!supplier) {
        return { error: 'Supplier not found.' };
    }

    const lock = isPostgresProviderEnabled()
        ? await pgGetSupplierPaymentLockByBeneficiary(supplierId)
        : getSupplierPaymentLockByBeneficiary(supplierId);
    if (lock && lock.userId !== session.user.id) {
        return { error: `SUPPLIER_PAYMENT_LOCKED:${lock.userName}` };
    }

    const allocationsList = Array.isArray(allocations) ? allocations : [];
    const purchaseOrders = await getPurchaseOrdersRuntime();
    const allocationRecords: NonNullable<SupplierPayment['allocations']> = [];
    let totalAllocatedInPaymentCurrency = 0;
    let liabilityBase = 0;
    let totalFxDifferenceBase = 0;
    const epsilon = 0.01;

    const applyFinancialImpact = postingStatus !== 'draft';
    const selectedIncomingCheckIds = Array.isArray(incomingCheckIds) ? incomingCheckIds : [];

    if (paymentMethod === 'check' && checkSource === 'incoming') {
        const incomingChecks = await getIncomingChecksRuntime();
        const selectedIncomingChecks = incomingChecks.filter((entry) => selectedIncomingCheckIds.includes(entry.id));
        if (selectedIncomingChecks.length !== selectedIncomingCheckIds.length) {
            return { error: 'One or more selected incoming checks were not found.' };
        }
        const blockedCheck = selectedIncomingChecks.find((entry) => entry.status !== 'pending' || (entry.endorsementStatus && entry.endorsementStatus !== 'none'));
        if (blockedCheck) {
            return { error: `Incoming check ${blockedCheck.checkNumber} is not available for payment.` };
        }

        const totalIncomingInPaymentCurrency = selectedIncomingChecks.reduce((sum, entry) => {
            const checkCurrency = entry.currency || baseCurrencyCode;
            const checkAmount = Number(entry.amount || 0);
            if (checkCurrency === paymentCurrency) return sum + checkAmount;
            return sum + convertCurrency(checkAmount, checkCurrency, paymentCurrency);
        }, 0);
        if (Math.abs(totalIncomingInPaymentCurrency - amount) > epsilon) {
            return { error: 'Total selected incoming checks must equal payment amount.' };
        }
    }

    for (const allocation of allocationsList) {
        const order = purchaseOrders.find((entry) => entry.id === allocation.purchaseOrderId);
        if (!order) {
            return { error: 'Purchase invoice not found for allocation.' };
        }
        if (order.status === 'cancelled') {
            return { error: 'Cannot allocate to a cancelled purchase invoice.' };
        }

        const invoiceCurrency = order.currencyCode || baseCurrencyCode;
        const capturedInvoiceRate = Number(order.exchangeRate || 0);
        const derivedDueRate = Number(order.amountDue || 0) > 0 ? Number(order.amountDueBase || 0) / Number(order.amountDue || 1) : 0;
        const derivedGrandRate = Number(order.grandTotal || 0) > 0 ? Number(order.grandTotalBase || 0) / Number(order.grandTotal || 1) : 0;
        const invoiceRate = (
            Number.isFinite(capturedInvoiceRate) && capturedInvoiceRate > 0
                ? capturedInvoiceRate
                : Number.isFinite(derivedDueRate) && derivedDueRate > 0
                    ? derivedDueRate
                    : Number.isFinite(derivedGrandRate) && derivedGrandRate > 0
                        ? derivedGrandRate
                        : (invoiceCurrency === baseCurrencyCode ? 1 : getExchangeRate(invoiceCurrency, baseCurrencyCode))
        );

        const remainingDue = order.amountDue || 0;
        if (allocation.amount - remainingDue > epsilon) {
            return { error: 'Allocation exceeds remaining invoice balance.' };
        }

        const allocatedInPaymentCurrency = invoiceCurrency === paymentCurrency
            ? allocation.amount
            : convertCurrency(allocation.amount, invoiceCurrency, paymentCurrency);
        const baseAtInvoiceRate = allocation.amount * invoiceRate;
        const baseAtPaymentRate = allocatedInPaymentCurrency * paymentExchangeRate;
        const fxDifference = baseAtPaymentRate - baseAtInvoiceRate;

        allocationRecords.push({
            id: `${allocation.purchaseOrderId}-${Date.now()}`,
            purchaseOrderId: allocation.purchaseOrderId,
            purchaseOrderNumber: order.orderNumber,
            invoiceCurrencyCode: invoiceCurrency,
            invoiceExchangeRate: invoiceRate,
            invoiceRateDate: order.rateDate,
            amount: allocation.amount,
            amountBase: baseAtPaymentRate,
            fxDifferenceBase: fxDifference,
        });

        totalAllocatedInPaymentCurrency += allocatedInPaymentCurrency;
        liabilityBase += baseAtInvoiceRate;
        totalFxDifferenceBase += fxDifference;

        if (applyFinancialImpact) {
            const newAmountPaid = (order.amountPaid || 0) + allocation.amount;
            const newAmountDue = Math.max(0, (order.amountDue || 0) - allocation.amount);
            const newAmountPaidBase = (order.amountPaidBase || 0) + baseAtInvoiceRate;
            const newAmountDueBase = Math.max(0, (order.amountDueBase ?? (order.amountDue || 0) * invoiceRate) - baseAtInvoiceRate);
            updatePurchaseOrder(order.id, {
                amountPaid: newAmountPaid,
                amountDue: newAmountDue,
                amountPaidBase: newAmountPaidBase,
                amountDueBase: newAmountDueBase,
            });
        }
    }

    if (paymentCurrency !== baseCurrencyCode && !isAdvance) {
        if (!allocationRecords || allocationRecords.length === 0) {
            return { error: 'Allocation is required for foreign currency payments unless marked as advance.' };
        }
        if (Math.abs(totalAllocatedInPaymentCurrency - amount) > epsilon) {
            return { error: 'Allocated amount must equal payment amount for foreign currency payments.' };
        }
    }

    const liabilityImpactBase = allocationRecords.length > 0 ? liabilityBase : paymentAmountBase;

    const usePostgres = isPostgresProviderEnabled();

    const payment = usePostgres ? await pgAddSupplierPayment({
        date: new Date().toISOString(),
        paymentMethod: paymentMethod as any,
        checkSource: paymentMethod === 'check' ? checkSource : undefined,
        incomingCheckIds: paymentMethod === 'check' && checkSource === 'incoming' ? selectedIncomingCheckIds : [],
        postingStatus,
        supplierId,
        amount,
        amountBase: paymentAmountBase,
        currencyCode: paymentCurrency,
        baseCurrencyCode,
        exchangeRate: paymentExchangeRate,
        rateDate: rateDate || new Date().toISOString(),
        isAdvance: !!isAdvance,
        allocations: allocationRecords,
        totalFxDifferenceBase,
        reference,
        notes,
    }) : addSupplierPayment({
        date: new Date().toISOString(),
        paymentMethod: paymentMethod as any,
        checkSource: paymentMethod === 'check' ? checkSource : undefined,
        incomingCheckIds: paymentMethod === 'check' && checkSource === 'incoming' ? selectedIncomingCheckIds : [],
        postingStatus,
        supplierId,
        amount,
        amountBase: paymentAmountBase,
        currencyCode: paymentCurrency,
        baseCurrencyCode,
        exchangeRate: paymentExchangeRate,
        rateDate: rateDate || new Date().toISOString(),
        isAdvance: !!isAdvance,
        allocations: allocationRecords,
        totalFxDifferenceBase,
        reference,
        notes,
    });

    if (applyFinancialImpact) {
        const success = usePostgres
            ? await pgUpdateSupplierBalance(supplierId, -liabilityImpactBase)
            : updateSupplierBalance(supplierId, -liabilityImpactBase);
        if (!success) {
            return { error: 'Supplier not found.' };
        }
    }

    if (postingStatus === 'posted') {
        try {
            let journalBankId: string | undefined;
            if (paymentMethod === 'check') {
                if (checkSource === 'issued' && checks && checks.length > 0) {
                    journalBankId = checks[0].bankId;
                } else if (checkSource === 'incoming' && selectedIncomingCheckIds.length > 0) {
                    const allIncomingChecks = await getIncomingChecksRuntime();
                    const selectedIncoming = allIncomingChecks.find((entry) => entry.id === selectedIncomingCheckIds[0]);
                    journalBankId = selectedIncoming?.bankId;
                }
                if (journalBankId) {
                    const linkedBank = await getBankByIdForCalc(journalBankId);
                    if (!linkedBank?.accountCode) {
                        return { error: 'Selected bank is not linked to a chart-of-accounts account.' };
                    }
                }
            }

            const journalEntry = createSupplierPaymentJournalEntry(
                payment.id,
                supplierId,
                supplier.name,
                liabilityImpactBase,
                paymentAmountBase,
                allocationRecords.length > 0 ? totalFxDifferenceBase : 0,
                session.user.name || 'admin',
                {
                    paymentMethod: paymentMethod as any,
                    bankId: journalBankId,
                }
            );

            if (usePostgres) {
                await pgSaveJournalEntry([journalEntry]);
            }
        } catch (error) {
            console.error('Failed to create journal entry:', error);
        }
    }

    if (paymentMethod === 'check' && checkSource === 'incoming' && applyFinancialImpact) {
        for (const checkId of selectedIncomingCheckIds) {
            const done = usePostgres
                ? await pgEndorseIncomingCheck(
                    checkId,
                    'endorsed-to-party',
                    supplierId,
                    supplier.name,
                    'supplier',
                    `Supplier Payment #${payment.id}`
                )
                : endorseIncomingCheck(
                checkId,
                'endorsed-to-party',
                supplierId,
                supplier.name,
                'supplier',
                `Supplier Payment #${payment.id}`
            );
            if (!done) {
                return { error: 'Failed to endorse incoming check to supplier.' };
            }
        }
    }

    if (paymentMethod === 'check' && checkSource === 'issued' && checks && checks.length > 0) {
        try {
            for (const check of checks) {
                const bank = await getBankByIdForCalc(check.bankId);
                if (!bank) {
                    console.error(`Bank not found for check ${check.checkNumber}`);
                    continue;
                }

                const checkCurrency = check.currency || baseCurrencyCode;
                const checkExchangeRate = checkCurrency === baseCurrencyCode
                    ? 1
                    : getExchangeRate(checkCurrency, baseCurrencyCode);
                const checkRecord = {
                    checkNumber: check.checkNumber,
                    bankId: check.bankId,
                    bankName: bank.name,
                    checkDate: check.checkDate,
                    amount: Number(check.amount || 0),
                    currency: checkCurrency,
                    convertedAmount: Number(check.amount || 0) * checkExchangeRate,
                    exchangeRate: checkExchangeRate,
                    supplierId,
                    supplierName: supplier.name,
                    reference: `Supplier Payment #${payment.id}`,
                    status: 'pending' as const,
                    notes: notes || '',
                    createdBy: session.user.name || 'admin',
                };

                if (usePostgres) {
                    await pgAddIssuedCheck(checkRecord);
                } else {
                    const { addIssuedCheck } = await import('./data');
                    addIssuedCheck(checkRecord);
                }
            }
        } catch (error) {
            console.error('Failed to save issued checks:', error);
        }
    }

    revalidatePath('/admin/purchases/payment');
    revalidatePath('/admin/purchases');
    revalidatePath('/admin/purchases/history');
    revalidatePath('/admin/data/suppliers');
    revalidatePath('/admin/sales/checks');

    return { success: true, payment };
}

export async function handleAcquireSupplierPaymentLock(supplierId: string) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };
    const id = String(supplierId || '').trim();
    if (!id) return { error: 'Supplier is required.' };

    const result = isPostgresProviderEnabled()
        ? await pgAcquireSupplierPaymentLock(id, session.user.id, session.user.name || session.user.id)
        : acquireSupplierPaymentLock(id, session.user.id, session.user.name || session.user.id);
    if (!result.success) {
        return {
            error: 'SUPPLIER_PAYMENT_LOCKED',
            lockedBy: result.lockedBy || 'مستخدم آخر',
        };
    }
    return { success: true };
}

export async function handleReleaseSupplierPaymentLock(supplierId: string) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };
    const id = String(supplierId || '').trim();
    if (!id) return { success: true };
    if (isPostgresProviderEnabled()) {
        await pgReleaseSupplierPaymentLock(id, session.user.id);
    } else {
        releaseSupplierPaymentLock(id, session.user.id);
    }
    return { success: true };
}

export async function handleGetSupplierPaymentLocksStatus(supplierIds: string[]) {
        const session = await getSession();
        if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

        const ids = Array.from(new Set((supplierIds || []).map((id) => String(id || '').trim()).filter(Boolean)));
        if (ids.length === 0) return { success: true, statuses: {} as Record<string, { locked: boolean; lockedBy?: string }> };

        const now = new Date().toISOString();
        const allLocks = (
            isPostgresProviderEnabled()
                ? (await pgGetSupplierPaymentLocks({ page: 1, pageSize: 200 })).items
                : getSupplierPaymentLocks()
        ).filter((lock) => lock.expiresAt > now);
        const statuses: Record<string, { locked: boolean; lockedBy?: string }> = {};

        ids.forEach((id) => {
            const lock = allLocks.find((entry) => entry.beneficiaryId === id);
            if (!lock) {
                statuses[id] = { locked: false };
                return;
            }
            if (lock.userId === session.user.id) {
                statuses[id] = { locked: false };
                return;
            }
            statuses[id] = { locked: true, lockedBy: String(lock.userName || 'مستخدم آخر') };
        });

        return { success: true, statuses };
}

const printerConfigSchema = z.object({
  id: z.string().optional(),
  name: z.string().optional(),
  connectionType: z.enum(['network', 'windows', 'usb']).optional().default('network'),
  ipAddress: z.string().optional(),
  port: z.coerce.number().int().min(1).max(65535).optional().default(9100),
  shareName: z.string().optional(),
  paperWidth: z.enum(['58mm', '80mm', 'a4']).optional().default('80mm'),
  role: z.enum(['receipt', 'prep', 'both']).optional().default('both'),
  enabled: z.coerce.boolean().optional().default(true),
});

const printSectionConfigSchema = z.object({
  id: z.string().optional(),
  name: z.string().optional(),
  printerId: z.string().optional(),
  copies: z.coerce.number().int().min(1).max(5).optional().default(1),
  printPrices: z.coerce.boolean().optional().default(false),
  enabled: z.coerce.boolean().optional().default(true),
});

const restaurantAreaConfigSchema = z.object({
    id: z.string().optional(),
    name: z.string().optional().default(''),
    sortOrder: z.coerce.number().int().min(0).optional().default(0),
});

const restaurantTableConfigSchema = z.object({
    id: z.string().optional(),
    name: z.string().optional().default(''),
    areaId: z.string().optional().default(''),
    seats: z.coerce.number().int().min(1).max(20).optional().default(4),
});

const employeePermissionProfileSchema = z.object({
    id: z.string().min(1),
    name: z.string().min(1),
    description: z.string().optional(),
    role: z.enum(['admin', 'employee', 'pos']),
    permissions: z.array(z.string()).optional().default([]),
});

const generalSettingsSchema = z.object({
  appName: z.string().optional(),
  appCurrency: z.string().optional(),
    approvedIpAddress: z.string().optional(),
  appLogoUrl: z.string().optional(),
    deploymentMode: z.string().optional().default('local'),
    documentStoragePath: z.string().optional().default(''),
  posShowSuppliers: z.coerce.boolean().optional().default(false),
  salesRepsEnabled: z.coerce.boolean().optional().default(false),
  businessMode: z.string().optional().default('inventory'),
  realEstateEnabled: z.coerce.boolean().optional().default(false),
  warehousesEnabled: z.coerce.boolean().optional().default(false),
    allowOutOfStockSales: z.coerce.boolean().optional().default(false),
        blockSalesBelowCost: z.coerce.boolean().optional().default(false),
        salesShipmentWorkflowEnabled: z.coerce.boolean().optional().default(false),
    purchaseShelfTaskEnabled: z.coerce.boolean().optional().default(false),
  defaultSalesWarehouseId: z.string().optional(),
  defaultSalesShelfId: z.string().optional(),
    defaultPosVisaBankAccountId: z.string().optional().default(''),
        restaurantPosEnabled: z.coerce.boolean().optional().default(false),
        restaurantPosAreasEnabled: z.coerce.boolean().optional().default(true),
        restaurantPosSplitBillEnabled: z.coerce.boolean().optional().default(true),
        restaurantPosMergeTablesEnabled: z.coerce.boolean().optional().default(true),
        restaurantPosTransferItemEnabled: z.coerce.boolean().optional().default(true),
        restaurantPosPartialCheckoutEnabled: z.coerce.boolean().optional().default(true),
        restaurantPosKotEnabled: z.coerce.boolean().optional().default(true),
        restaurantPosAutoReserveMinutes: z.coerce.number().int().min(0).max(720).optional().default(90),
        restaurantPosDefaultGuestCount: z.coerce.number().int().min(1).max(100).optional().default(2),
        restaurantPosAreas: z.array(restaurantAreaConfigSchema).optional().default([]),
        restaurantPosTables: z.array(restaurantTableConfigSchema).optional().default([]),
    posShowItemNumberColumn: z.coerce.boolean().optional(),
    posShowUnitColumn: z.coerce.boolean().optional(),
    posShowDescriptionColumn: z.coerce.boolean().optional(),
    posShowBarcodeColumn: z.coerce.boolean().optional(),
    posShowQuantityColumn: z.coerce.boolean().optional(),
    posShowPriceColumn: z.coerce.boolean().optional(),
    posShowItemDiscountColumn: z.coerce.boolean().optional(),
    posShowBonusColumn: z.coerce.boolean().optional(),
    posShowTotalColumn: z.coerce.boolean().optional(),
    posShowActionsColumn: z.coerce.boolean().optional(),
    posShowWeighedItemsButton: z.coerce.boolean().optional(),
  defaultPurchaseWarehouseId: z.string().optional(),
  defaultPurchaseShelfId: z.string().optional(),
    defaultTaxMethod: z.string().optional().default('tax-inclusive'),
  defaultInvoiceTaxRate: z.coerce.number().min(0).max(100).optional().default(0.1),
  defaultLineTaxRate: z.coerce.number().min(0).max(100).optional().default(0.1),
    fxAutoUpdateRates: z.coerce.boolean().optional().default(false),
    fxLockBaseCurrency: z.coerce.boolean().optional().default(false),
    scaleMode: z.string().optional().default('manual'),
    scaleReadRegex: z.string().optional().default('([0-9]+(?:[\\.,][0-9]+)?)'),
    scaleDecimalSeparator: z.string().optional().default('auto'),
    scaleHidMinLength: z.coerce.number().int().min(1).max(20).optional().default(3),
    scaleSerialBaudRate: z.coerce.number().int().min(110).max(921600).optional().default(9600),
    scaleSerialDataBits: z.coerce.number().int().optional().default(8),
    scaleSerialStopBits: z.coerce.number().optional().default(1),
    scaleSerialParity: z.enum(['none', 'even', 'odd']).optional().default('none'),
    scaleSerialAutoConnect: z.coerce.boolean().optional().default(false),
    customPrintersEnabled: z.coerce.boolean().optional().default(false),
    printerAutoPrintEnabled: z.coerce.boolean().optional().default(false),
    printTransportMode: z.string().optional().default('browser'),
    defaultCustomerReceiptPrinterId: z.string().optional().default(''),
    printerConfigs: z.array(printerConfigSchema).optional().default([]),
    printSections: z.array(printSectionConfigSchema).optional().default([]),
    printHeaderRightText: z.string().optional().default(''),
    printHeaderCenterText: z.string().optional().default(''),
    printHeaderLeftText: z.string().optional().default(''),
    printHeaderText: z.string().optional().default(''),
    printFooterText: z.string().optional().default(''),
    purchaseShipmentWorkflowEnabled: z.coerce.boolean().optional().default(false),
    purchasePostingFollowupEnabled: z.coerce.boolean().optional().default(false),
    aiInvoiceEntryEnabled: z.coerce.boolean().optional().default(false),
    aiInvoiceApiKey: z.string().optional().default(''),
    showEditingMessageToUser: z.coerce.boolean().optional().default(false),
    employeePermissionProfiles: z.array(employeePermissionProfileSchema).optional(),
});

// Category Management Actions
const addCategorySchema = z.object({
    name: z.string().min(1, 'Category name is required.'),
    nameEn: z.string().optional(),
    discountPercent: z.coerce.number().min(0).max(100).optional(),
    description: z.string().optional(),
});

export async function handleAddCategory(values: z.infer<typeof addCategorySchema>) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const parsed = addCategorySchema.safeParse(values);
    if (!parsed.success) {
        return { error: 'Invalid data submitted.' };
    }

    try {
        let category: { id: string; name: string; categoryNumber?: string; nameEn?: string; discountPercent?: number; description?: string };
        const normalizedName = String(parsed.data.name || '').trim();
        const normalizedNameEn = String(parsed.data.nameEn || '').trim();
        const normalizedDescription = String(parsed.data.description || '').trim();
        const normalizedDiscount = Number(parsed.data.discountPercent || 0);
        if (isPostgresProviderEnabled()) {
            const created = await pgCreateCustomerCategory({
                id: nextPrefixedId('cat'),
                categoryNumber: `CAT-${String(await pgNextNamedSequence('customer-category-ref')).padStart(4, '0')}`,
                name: normalizedName,
                nameEn: normalizedNameEn || undefined,
                discountPercent: Number.isFinite(normalizedDiscount) ? normalizedDiscount : 0,
                description: normalizedDescription || undefined,
            }) as Record<string, unknown>;
            category = {
                id: String(created.id || ''),
                name: String(created.name || normalizedName),
                categoryNumber: String(created.categoryNumber || '').trim() || undefined,
                nameEn: String(created.nameEn || '').trim() || undefined,
                discountPercent: Number(created.discountPercent || 0),
                description: String(created.description || '').trim() || undefined,
            };
        } else {
            category = addCustomerCategory({
                name: normalizedName,
                nameEn: normalizedNameEn || undefined,
                discountPercent: Number.isFinite(normalizedDiscount) ? normalizedDiscount : 0,
                description: normalizedDescription || undefined,
            });
        }
        revalidatePath('/admin/data/customers');
        revalidatePath('/admin/data/customer-pricing');
        revalidatePath('/admin/data/categories');
        return { success: true, category };
    } catch (error: any) {
        if (error?.code === '23505') {
            return { error: 'تصنيف بهذا الاسم أو الرقم المرجعي موجود مسبقاً.' };
        }
        return { error: error.message || 'Failed to add category.' };
    }
}

export async function handleDeleteCategory(id: string) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    let success = false;
    if (isPostgresProviderEnabled()) {
        success = await pgDeleteCustomerCategory(id);
    } else {
        success = deleteCustomerCategory(id);
    }
    if (success) {
        revalidatePath('/admin/data/customers');
        revalidatePath('/admin/data/customer-pricing');
        revalidatePath('/admin/data/categories');
        return { success: true };
    }
    return { error: 'Failed to delete category.' };
}

export async function handleGetPrinterConfiguration() {
    const session = await getSession();
    if (!session?.user) return { error: 'Unauthorized' };

    const settings = await getSettingsRuntime();
    return {
        success: true,
        settings: {
            customPrintersEnabled: settings?.customPrintersEnabled === true || settings?.customPrintersEnabled === 'true',
            printerAutoPrintEnabled: settings?.printerAutoPrintEnabled === true || settings?.printerAutoPrintEnabled === 'true',
            printTransportMode: settings?.printTransportMode === 'native-bridge' ? 'native-bridge' : 'browser',
            defaultCustomerReceiptPrinterId: String(settings?.defaultCustomerReceiptPrinterId || ''),
            printerConfigs: Array.isArray(settings?.printerConfigs) ? settings.printerConfigs : [],
            printSections: Array.isArray(settings?.printSections) ? settings.printSections : [],
        },
    };
}

const quickAddPrinterSchema = z.object({
    name: z.string().min(1),
    connectionType: z.enum(['network', 'windows', 'usb']).optional().default('network'),
    ipAddress: z.string().optional(),
    port: z.coerce.number().int().min(1).max(65535).optional(),
    shareName: z.string().optional(),
    paperWidth: z.enum(['58mm', '80mm', 'a4']).optional().default('80mm'),
    role: z.enum(['receipt', 'prep', 'both']).optional().default('prep'),
    enabled: z.coerce.boolean().optional().default(true),
});

const quickAddPrintSectionSchema = z.object({
    name: z.string().min(1),
    printerId: z.string().optional(),
    copies: z.coerce.number().int().min(1).max(5).optional().default(1),
    printPrices: z.coerce.boolean().optional().default(false),
    enabled: z.coerce.boolean().optional().default(true),
});

export async function handleQuickAddPrinterConfig(values: z.infer<typeof quickAddPrinterSchema>) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const parsed = quickAddPrinterSchema.safeParse(values);
    if (!parsed.success) return { error: 'Invalid data submitted.' };

    const settings = await getSettingsRuntime();
    const existingPrinters = Array.isArray(settings?.printerConfigs) ? settings.printerConfigs : [];
    const normalizedName = String(parsed.data.name || '').trim();
    if (!normalizedName) return { error: 'Printer name is required.' };

    const duplicate = existingPrinters.find((entry: any) => String(entry?.name || '').trim().toLowerCase() === normalizedName.toLowerCase());
    if (duplicate) return { error: 'Printer already exists.' };

    const printer = {
        id: `printer-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
        name: normalizedName,
        connectionType: parsed.data.connectionType,
        ipAddress: String(parsed.data.ipAddress || '').trim() || undefined,
        port: parsed.data.connectionType === 'network'
            ? (parsed.data.port ?? 9100)
            : (parsed.data.port === undefined ? undefined : parsed.data.port),
        shareName: String(parsed.data.shareName || '').trim() || undefined,
        paperWidth: parsed.data.paperWidth,
        role: parsed.data.role,
        enabled: parsed.data.enabled !== false,
    };

    const newSettings = {
        ...settings,
        customPrintersEnabled: true,
        printerConfigs: [...existingPrinters, printer],
    };

    await saveSettingsRuntime(newSettings as Record<string, unknown>);

    revalidatePath('/admin/general-settings');
    revalidatePath('/admin/data/materials');

    return { success: true, printer };
}

export async function handleQuickAddPrintSection(values: z.infer<typeof quickAddPrintSectionSchema>) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const parsed = quickAddPrintSectionSchema.safeParse(values);
    if (!parsed.success) return { error: 'Invalid data submitted.' };

    const settings = await getSettingsRuntime();
    const existingPrinters = Array.isArray(settings?.printerConfigs) ? settings.printerConfigs : [];
    const printerIds = new Set(existingPrinters.map((entry: any) => String(entry?.id || '').trim()));
    const existingSections = Array.isArray(settings?.printSections) ? settings.printSections : [];

    const normalizedName = String(parsed.data.name || '').trim();
    if (!normalizedName) return { error: 'Section name is required.' };

    const duplicate = existingSections.find((entry: any) => String(entry?.name || '').trim().toLowerCase() === normalizedName.toLowerCase());
    if (duplicate) return { error: 'Section already exists.' };

    const normalizedPrinterId = String(parsed.data.printerId || '').trim();
    const section = {
        id: `section-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
        name: normalizedName,
        printerId: printerIds.has(normalizedPrinterId) ? normalizedPrinterId : undefined,
        copies: Math.max(1, Math.min(5, Number(parsed.data.copies || 1))),
        printPrices: parsed.data.printPrices === true,
        enabled: parsed.data.enabled !== false,
    };

    const newSettings = {
        ...settings,
        customPrintersEnabled: true,
        printSections: [...existingSections, section],
    };

    await saveSettingsRuntime(newSettings as Record<string, unknown>);

    revalidatePath('/admin/general-settings');
    revalidatePath('/admin/data/materials');

    return { success: true, section };
}

export async function handleGetDisassemblyRecords() {
    const session = await getSession();
    if (!session?.user) return { error: 'Unauthorized' };

    const records = await getDisassemblyRecordsRuntime();
    return {
        success: true,
        items: [...records].sort((left, right) => String(right.date || '').localeCompare(String(left.date || ''))),
    };
}

export async function handleGetDisassemblyTraceForMaterial(materialId: string) {
    const session = await getSession();
    if (!session?.user) return { error: 'Unauthorized' };

    const normalizedMaterialId = String(materialId || '').trim();
    if (!normalizedMaterialId) {
        return { success: true, items: [] };
    }

    const records = await getDisassemblyRecordsRuntime();
    const matchingRecords = records
        .map((record) => ({
            ...record,
            parts: (record.parts || []).filter((part) => String(part.partItemId || '').trim() === normalizedMaterialId),
        }))
        .filter((record) => record.parts.length > 0)
        .sort((left, right) => String(right.date || '').localeCompare(String(left.date || '')));

    return { success: true, items: matchingRecords };
}

export async function handleEnsureRealEstateAccountingSetup() {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const accounts = await ensureRealEstateAccountingSetup();
    revalidatePath('/admin/accounting/chart');
    return { success: true, accounts };
}

export async function handleGetRealEstateProjects() {
    const session = await getSession();
    if (!session?.user) return { error: 'Unauthorized' };

    const accountingSetup = await ensureRealEstateAccountingSetup();
    const projects = await getRealEstateProjectsRuntime();
    let updated = false;
    const normalizedProjects: RealEstateProject[] = [];

    for (const project of projects) {
        if (!String(project?.accounting?.projectAccountCode || '').trim()) {
            const accounting = await ensureRealEstateAccountingSetup({
                id: String(project.id || '').trim(),
                name: String(project.name || '').trim(),
                code: String(project.code || '').trim(),
            });
            normalizedProjects.push({
                ...project,
                accounting: {
                    ...(project.accounting || {}),
                    ...accounting,
                },
            });
            updated = true;
        } else {
            normalizedProjects.push(project);
        }
    }

    if (updated) {
        await saveRealEstateProjectsRuntime(normalizedProjects);
    }

    const items = updated ? normalizedProjects : projects;
    return {
        success: true,
        accountingSetup,
        items: [...items].sort((left, right) => String(right.updatedAt || right.createdAt || '').localeCompare(String(left.updatedAt || left.createdAt || ''))),
    };
}

export async function handleSaveRealEstateProject(values: z.infer<typeof realEstateProjectSchema>) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const parsed = realEstateProjectSchema.safeParse(values);
    if (!parsed.success) {
        console.error(parsed.error.flatten());
        return { error: 'Invalid data submitted.' };
    }

    const projects = await getRealEstateProjectsRuntime();
    const now = new Date().toISOString();
    const projectId = String(parsed.data.id || '').trim() || nextPrefixedId('reproj');
    const existingProject = projects.find((entry) => String(entry.id || '').trim() === projectId);
    const trimmedName = String(parsed.data.name || '').trim();
    if (!trimmedName) {
        return { error: 'Project name is required.' };
    }

    const normalizedFloorCountInput = Math.max(0, Number(parsed.data.floorCount || 0));
    const designSummary = String(parsed.data.designSummary || '').trim();
    const normalizedFloorDetails = (parsed.data.floorDetails || []).reduce<Array<NonNullable<RealEstateProject['floorDetails']>[number]>>((acc, floor, index) => {
        const floorLabel = String(floor.floorLabel || '').trim();
        const usageType = String(floor.usageType || '').trim();
        const description = String(floor.description || '').trim();
        const notes = String(floor.notes || '').trim();
        const unitCount = Math.max(0, Number(floor.unitCount || 0));
        const unitArea = Math.max(0, Number(floor.unitArea || 0));
        const estimatedUnitSaleValue = Math.max(0, Number((floor as any).estimatedUnitSaleValue || 0));
        const unitDetails = (floor.unitDetails || [])
            .map((entry, entryIndex) => ({
                id: String(entry.id || '').trim() || nextPrefixedId('refunit'),
                unitLabel: String(entry.unitLabel || '').trim() || `Unit ${entryIndex + 1}`,
                area: Math.max(0, Number(entry.area || 0)),
                estimatedSaleValue: Math.max(0, Number(entry.estimatedSaleValue || 0)),
                notes: String(entry.notes || '').trim() || undefined,
            }))
            .filter((entry) => entry.unitLabel || (entry.area || 0) > 0 || (entry.estimatedSaleValue || 0) > 0 || entry.notes);
        const derivedUnitCount = unitDetails.length > 0 ? unitDetails.length : unitCount;
        const derivedUnitArea = unitDetails.length > 0
            ? Number((unitDetails.reduce((sum, entry) => sum + Math.max(0, Number(entry.area || 0)), 0) / unitDetails.length).toFixed(2))
            : unitArea;

        const hasMeaningfulData = Boolean(floorLabel || usageType || description || notes || derivedUnitCount > 0 || derivedUnitArea > 0 || estimatedUnitSaleValue > 0 || unitDetails.length > 0);
        if (!hasMeaningfulData) {
            return acc;
        }

        acc.push({
            id: String(floor.id || '').trim() || nextPrefixedId('refloor'),
            floorLabel: floorLabel || `Floor ${index + 1}`,
            usageType: usageType || undefined,
            description: description || undefined,
            unitCount: derivedUnitCount > 0 ? derivedUnitCount : undefined,
            unitArea: derivedUnitArea > 0 ? derivedUnitArea : undefined,
            estimatedUnitSaleValue: estimatedUnitSaleValue > 0 ? estimatedUnitSaleValue : undefined,
            unitDetails: unitDetails.length > 0 ? unitDetails : undefined,
            notes: notes || undefined,
        });

        return acc;
    }, []);
    const normalizedFloorCount = Math.max(normalizedFloorCountInput, normalizedFloorDetails.length);

    const derivedUnitsFromFloorDetails = normalizedFloorDetails.flatMap((floor, floorIndex) => {
        const floorLabel = String(floor.floorLabel || `Floor ${floorIndex + 1}`).trim();
        const rawUnitDetails = Array.isArray(floor.unitDetails) ? floor.unitDetails : [];
        const fallbackUnitCount = rawUnitDetails.length > 0 ? rawUnitDetails.length : Math.max(0, Number(floor.unitCount || 0));
        const fallbackArea = Math.max(0, Number(floor.unitArea || 0));
        const fallbackSaleValue = Math.max(0, Number((floor as any).estimatedUnitSaleValue || 0));
        const unitDetails = rawUnitDetails.length > 0
            ? rawUnitDetails
            : Array.from({ length: fallbackUnitCount }, (_, detailIndex) => ({
                id: `${String(floor.id || `floor-${floorIndex + 1}`)}-unit-${detailIndex + 1}`,
                unitLabel: '',
                area: fallbackArea,
                estimatedSaleValue: fallbackSaleValue,
                notes: '',
            }));

        return unitDetails.reduce<Array<Partial<RealEstateProject['units'][number]>>>((acc, detail, detailIndex) => {
            const unitLabel = String(detail.unitLabel || '').trim();
            const unitNotes = String(detail.notes || '').trim();
            const area = Math.max(0, Number(detail.area || 0));
            const estimatedSaleValue = Math.max(0, Number(detail.estimatedSaleValue || 0));
            if (!unitLabel && !unitNotes && area <= 0 && estimatedSaleValue <= 0) {
                return acc;
            }

            acc.push({
                id: String(detail.id || '').trim() || nextPrefixedId('reunit'),
                unitCode: `F${floorIndex + 1}-U${detailIndex + 1}`,
                name: unitLabel || `Unit ${detailIndex + 1}`,
                floor: floorLabel || undefined,
                area,
                saleValue: estimatedSaleValue > 0 ? estimatedSaleValue : undefined,
                notes: unitNotes || undefined,
                status: 'available',
            });
            return acc;
        }, []);
    });

    const unitsSource = derivedUnitsFromFloorDetails.length > 0
        ? derivedUnitsFromFloorDetails.map((derivedUnit) => {
            const matchedUnit = (parsed.data.units || []).find((entry) => {
                const sameId = String(entry.id || '').trim() && String(entry.id || '').trim() === String(derivedUnit.id || '').trim();
                const sameFloor = String(entry.floor || '').trim() === String(derivedUnit.floor || '').trim();
                const sameName = String(entry.name || entry.unitCode || '').trim().toLowerCase() === String(derivedUnit.name || derivedUnit.unitCode || '').trim().toLowerCase();
                return sameId || (sameFloor && sameName);
            });
            return { ...(matchedUnit || {}), ...derivedUnit };
        })
        : (parsed.data.units || []);

    const normalizedUnits = unitsSource.reduce<Array<RealEstateProject['units'][number]>>((acc, unit, index) => {
        const unitCode = String(unit.unitCode || '').trim();
        const name = String(unit.name || '').trim();
        const floor = String(unit.floor || '').trim();
        const buyerCustomerId = String(unit.buyerCustomerId || '').trim();
        const buyerName = String(unit.buyerName || '').trim();
        const contractDate = String(unit.contractDate || '').trim();
        const handoverDate = String(unit.handoverDate || '').trim();
        const lastCollectionDate = String(unit.lastCollectionDate || '').trim();
        const notes = String(unit.notes || '').trim();
        const area = Math.max(0, Number(unit.area || 0));
        const saleValue = Math.max(0, Number(unit.saleValue || 0));
        const actualSaleValue = Math.max(0, Number(unit.actualSaleValue || 0));
        const directCostEntries = (unit.directCostEntries || [])
            .map((entry) => ({
                id: String(entry.id || '').trim() || nextPrefixedId('redce'),
                phase: String(entry.phase || '').trim() || undefined,
                title: String(entry.title || '').trim() || undefined,
                amount: Math.max(0, Number(entry.amount || 0)),
                date: String(entry.date || '').trim() || undefined,
                notes: String(entry.notes || '').trim() || undefined,
            }))
            .filter((entry) => entry.phase || entry.title || entry.amount > 0 || entry.date || entry.notes);
        const directCost = directCostEntries.length > 0
            ? directCostEntries.reduce((sum, entry) => sum + entry.amount, 0)
            : Math.max(0, Number(unit.directCost || 0));
        const collectedAmount = Math.max(0, Number(unit.collectedAmount || 0));
        const installments = (unit.installments || [])
            .map((installment, installmentIndex) => ({
                id: String(installment.id || '').trim() || nextPrefixedId('reinst'),
                title: String(installment.title || '').trim() || `Installment ${installmentIndex + 1}`,
                dueDate: String(installment.dueDate || '').trim() || undefined,
                amount: Math.max(0, Number(installment.amount || 0)),
                paidAmount: Math.max(0, Number(installment.paidAmount || 0)),
                status: (installment.status || 'pending') as 'pending' | 'partially-paid' | 'paid' | 'overdue',
                notes: String(installment.notes || '').trim() || undefined,
            }))
            .filter((installment) => installment.title || installment.dueDate || installment.amount > 0 || (installment.paidAmount || 0) > 0);

        const hasMeaningfulData = Boolean(
            unitCode
            || name
            || floor
            || buyerCustomerId
            || buyerName
            || contractDate
            || handoverDate
            || lastCollectionDate
            || notes
            || area > 0
            || saleValue > 0
            || actualSaleValue > 0
            || directCost > 0
            || collectedAmount > 0
            || installments.length > 0
            || directCostEntries.length > 0,
        );

        if (!hasMeaningfulData) {
            return acc;
        }

        acc.push({
            id: String(unit.id || '').trim() || nextPrefixedId('reunit'),
            unitCode: unitCode || `UNIT-${index + 1}`,
            name: name || `Unit ${index + 1}`,
            floor: floor || undefined,
            area,
            saleValue,
            actualSaleValue,
            directCost,
            directCostEntries,
            buyerCustomerId: buyerCustomerId || undefined,
            buyerName: buyerName || undefined,
            contractDate: contractDate || undefined,
            handoverDate: handoverDate || undefined,
            collectedAmount,
            lastCollectionDate: lastCollectionDate || undefined,
            installments,
            status: (unit.status || 'planned') as 'planned' | 'available' | 'reserved' | 'sold',
            notes: notes || undefined,
        });

        return acc;
    }, []);

    const unitIdSet = new Set(normalizedUnits.map((unit) => unit.id));
    const normalizedProjectSharedUnitAllocations = (parsed.data.sharedCostUnitAllocations || [])
        .map((allocation) => ({
            unitId: String(allocation.unitId || '').trim(),
            percentage: Math.max(0, Math.min(100, Number(allocation.percentage || 0))),
        }))
        .filter((allocation) => allocation.unitId && unitIdSet.has(allocation.unitId));
    const normalizedProjectSharedAllocationMethod = (parsed.data.sharedCostAllocationMethod || 'area') as 'area' | 'sale-value' | 'manual-share';

    const normalizedSharedCosts = (parsed.data.sharedCosts || []).reduce<Array<RealEstateProject['sharedCosts'][number]>>((acc, entry, index) => {
        const title = String(entry.title || '').trim();
        const category = String(entry.category || '').trim();
        const notes = String(entry.notes || '').trim();
        const amount = Math.max(0, Number(entry.amount || 0));
        const unitAllocations = (entry.unitAllocations || [])
            .map((allocation) => ({
                unitId: String(allocation.unitId || '').trim(),
                percentage: Math.max(0, Math.min(100, Number(allocation.percentage || 0))),
            }))
            .filter((allocation) => allocation.unitId && unitIdSet.has(allocation.unitId));

        const hasMeaningfulData = Boolean(title || category || notes || amount > 0 || unitAllocations.length > 0);
        if (!hasMeaningfulData) {
            return acc;
        }

        acc.push({
            id: String(entry.id || '').trim() || nextPrefixedId('reshared'),
            title: title || `Shared Cost ${index + 1}`,
            category: category || undefined,
            amount,
            allocationMethod: (entry.allocationMethod || 'area') as 'area' | 'sale-value' | 'manual-share',
            notes: notes || undefined,
            unitAllocations,
        });

        return acc;
    }, []);

    for (const cost of normalizedSharedCosts) {
        if (cost.allocationMethod === 'manual-share') {
            const totalPercentage = cost.unitAllocations.reduce((sum, allocation) => sum + allocation.percentage, 0);
            if (totalPercentage <= 0) {
                return { error: `Manual allocation percentages are required for ${cost.title}.` };
            }
        }
    }

    if (normalizedProjectSharedAllocationMethod === 'manual-share') {
        const totalProjectAllocationPercentage = normalizedProjectSharedUnitAllocations.reduce((sum, allocation) => sum + allocation.percentage, 0);
        if (totalProjectAllocationPercentage <= 0) {
            return { error: 'Manual allocation percentages are required for building-level shared purchases.' };
        }
    }

    const currentYear = new Date().getFullYear();
    const sequence = projects.filter((entry) => String(entry.code || '').includes(`REA/${currentYear}/`)).length + 1;
    const projectCode = String(parsed.data.code || '').trim() || `REA/${currentYear}/${String(sequence).padStart(3, '0')}`;
    const accountingSetup = await ensureRealEstateAccountingSetup({
        id: projectId,
        name: trimmedName,
        code: projectCode,
    });

    const project: RealEstateProject = {
        id: projectId,
        name: trimmedName,
        code: projectCode,
        location: String(parsed.data.location || '').trim() || undefined,
        startDate: String(parsed.data.startDate || '').trim() || undefined,
        targetCompletionDate: String(parsed.data.targetCompletionDate || '').trim() || undefined,
        floorCount: normalizedFloorCount > 0 ? normalizedFloorCount : undefined,
        designSummary: designSummary || undefined,
        floorDetails: normalizedFloorDetails,
        status: (parsed.data.status || 'draft') as 'draft' | 'active' | 'completed',
        notes: String(parsed.data.notes || '').trim() || undefined,
        units: normalizedUnits,
        sharedCosts: normalizedSharedCosts,
        sharedCostAllocationMethod: normalizedProjectSharedAllocationMethod,
        sharedCostUnitAllocations: normalizedProjectSharedUnitAllocations,
        accounting: {
            ...(existingProject?.accounting || {}),
            ...accountingSetup,
        },
        createdBy: existingProject?.createdBy || session.user.name || session.user.id,
        createdAt: existingProject?.createdAt || now,
        updatedAt: now,
    };

    const nextProjects = [project, ...projects.filter((entry) => String(entry.id || '').trim() !== projectId)];
    await saveRealEstateProjectsRuntime(nextProjects);

    revalidatePath('/admin/data/real-estate');
    revalidatePath('/admin/data');
    revalidatePath('/admin/accounting/chart');
    return { success: true, project };
}

export async function handleDeleteRealEstateProject(projectId: string) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const normalizedId = String(projectId || '').trim();
    if (!normalizedId) {
        return { error: 'Project id is required.' };
    }

    const projects = await getRealEstateProjectsRuntime();
    await saveRealEstateProjectsRuntime(projects.filter((entry) => String(entry.id || '').trim() !== normalizedId));

    revalidatePath('/admin/data/real-estate');
    revalidatePath('/admin/data');
    return { success: true };
}

async function syncProductionRealEstateExpenseEntries(params: {
    report: ProductionReport;
    expenses: Array<{ expenseId: string; value: number }>;
    createdBy: string;
}) {
    const reportId = String(params.report?.id || '').trim();
    const autoEntryId = `je-prod-realestate-${reportId}`;
    const existingJournalEntries = await getJournalEntriesRuntime();
    const journalEntriesWithoutAuto = existingJournalEntries.filter((entry) => String(entry.id || '').trim() !== autoEntryId);

    if (!reportId) {
        if (journalEntriesWithoutAuto.length !== existingJournalEntries.length) {
            await saveJournalEntriesRuntime(journalEntriesWithoutAuto);
            revalidatePath('/admin/accounting/entries');
            revalidatePath('/admin/data/real-estate');
        }
        return { success: true, autoPostedCount: 0 };
    }

    const expenseLines = Array.isArray(params.expenses) ? params.expenses : [];
    if (expenseLines.length === 0) {
        if (journalEntriesWithoutAuto.length !== existingJournalEntries.length) {
            await saveJournalEntriesRuntime(journalEntriesWithoutAuto);
            revalidatePath('/admin/accounting/entries');
            revalidatePath('/admin/data/real-estate');
        }
        return { success: true, autoPostedCount: 0 };
    }

    const projects = await getRealEstateProjectsRuntime();
    const expenseCatalog = await getExpensesRuntime();
    const accounts = await getChartOfAccountsRuntime();
    const payableAccount = ensureChartAccountInCollection(accounts, {
        preferredCode: '2130',
        nameAr: 'مصروفات مستحقة',
        nameEn: 'Accrued Expenses',
        parentCode: '2100',
        nature: 'credit',
    }).account;

    const debitLines: JournalEntryLine[] = [];
    let totalAmount = 0;
    let projectsChanged = false;

    for (const [index, expenseLine] of expenseLines.entries()) {
        const normalizedAmount = Math.round(Number(expenseLine?.value || 0) * 100) / 100;
        if (!Number.isFinite(normalizedAmount) || normalizedAmount <= 0) continue;

        const expenseItem = expenseCatalog.find((entry) => String(entry.id || '').trim() === String(expenseLine?.expenseId || '').trim());
        const projectId = String(expenseItem?.realEstateProjectId || '').trim();
        if (!expenseItem || !projectId) continue;

        const projectIndex = projects.findIndex((entry) => String(entry.id || '').trim() === projectId);
        if (projectIndex === -1) continue;

        const project = projects[projectIndex];
        if (!String(project?.accounting?.projectAccountCode || '').trim()) {
            const accounting = await ensureRealEstateAccountingSetup({
                id: String(project.id || '').trim(),
                name: String(project.name || '').trim(),
                code: String(project.code || '').trim(),
            });
            projects[projectIndex] = {
                ...project,
                accounting: {
                    ...(project.accounting || {}),
                    ...accounting,
                },
                updatedAt: new Date().toISOString(),
            };
            projectsChanged = true;
        }

        const effectiveProject = projects[projectIndex];
        const itemCostType = String(expenseItem.realEstateCostType || 'general').trim();
        const unit = (effectiveProject.units || []).find((entry) => String(entry.id || '').trim() === String(expenseItem.realEstateUnitId || '').trim());
        const debitAccountCode = String(
            effectiveProject.accounting?.projectAccountCode
            || (itemCostType === 'shared-project' ? effectiveProject.accounting?.sharedCostAccountCode : effectiveProject.accounting?.directCostAccountCode)
            || effectiveProject.accounting?.projectsRootAccountCode
            || '1192'
        ).trim();
        const debitAccount = accounts.find((entry) => String(entry.code || '').trim() === debitAccountCode && entry.type === 'account') || payableAccount;
        const costTypeLabel = itemCostType === 'direct-unit'
            ? 'تكلفة مباشرة'
            : itemCostType === 'shared-project'
                ? 'تكلفة مشتركة'
                : 'تكلفة عامة';
        const unitLabel = unit ? ` - ${String(unit.name || unit.unitCode || '').trim()}` : '';
        const description = `ترحيل تلقائي من تقرير الإنتاج ${reportId} - ${costTypeLabel} للمشروع ${String(effectiveProject.name || '').trim()}${unitLabel} - ${String(expenseItem.name || `مصروف ${index + 1}`).trim()}`;

        debitLines.push({
            accountId: String(debitAccount.id || debitAccount.code || '1192'),
            accountCode: String(debitAccount.code || '1192'),
            accountName: String(debitAccount.nameAr || debitAccount.nameEn || 'مشروع عقاري'),
            debit: normalizedAmount,
            credit: 0,
            description,
        });
        totalAmount = Math.round((totalAmount + normalizedAmount) * 100) / 100;
    }

    if (projectsChanged) {
        await saveRealEstateProjectsRuntime(projects);
    }
    await saveChartOfAccountsRuntime(accounts);

    if (debitLines.length === 0) {
        if (journalEntriesWithoutAuto.length !== existingJournalEntries.length) {
            await saveJournalEntriesRuntime(journalEntriesWithoutAuto);
            revalidatePath('/admin/accounting/entries');
            revalidatePath('/admin/data/real-estate');
        }
        return { success: true, autoPostedCount: 0 };
    }

    const entryDescription = `ترحيل تلقائي لمصاريف المشاريع من تقرير الإنتاج ${reportId}`;
    const entry: JournalEntry = {
        id: autoEntryId,
        date: String(params.report?.date || new Date().toISOString()),
        description: entryDescription,
        referenceType: 'production',
        referenceId: reportId,
        lines: [
            ...debitLines,
            {
                accountId: String(payableAccount.id || payableAccount.code || '2130'),
                accountCode: String(payableAccount.code || '2130'),
                accountName: String(payableAccount.nameAr || payableAccount.nameEn || 'مصروفات مستحقة'),
                debit: 0,
                credit: totalAmount,
                description: entryDescription,
            },
        ],
        createdBy: params.createdBy,
        createdAt: new Date().toISOString(),
    };

    journalEntriesWithoutAuto.unshift(entry);
    await saveJournalEntriesRuntime(journalEntriesWithoutAuto);

    revalidatePath('/admin/accounting/entries');
    revalidatePath('/admin/data/real-estate');
    return { success: true, autoPostedCount: debitLines.length, entry };
}

function roundCurrencyAmount(value: number): number {
    return Math.round((Number(value || 0) + Number.EPSILON) * 100) / 100;
}

function pickLatestIsoDate(values: Array<string | undefined>): string | undefined {
    return values
        .map((value) => String(value || '').trim().slice(0, 10))
        .filter(Boolean)
        .sort()
        .at(-1);
}

function applyRealEstateInstallmentCollectionState(unit: RealEstateUnit, collectedAmount: number, referenceDate?: string): RealEstateUnit {
    const normalizedCollectedAmount = Math.max(0, roundCurrencyAmount(collectedAmount));
    const installments = Array.isArray(unit?.installments) ? unit.installments : [];
    const latestCollectionDate = normalizedCollectedAmount > 0
        ? (pickLatestIsoDate([referenceDate, unit.lastCollectionDate]) || unit.lastCollectionDate)
        : undefined;

    if (installments.length === 0) {
        return {
            ...unit,
            collectedAmount: normalizedCollectedAmount,
            lastCollectionDate: latestCollectionDate,
        };
    }

    let remainingCollected = normalizedCollectedAmount;
    const comparisonDate = String(referenceDate || new Date().toISOString()).slice(0, 10);
    const comparisonTime = comparisonDate
        ? new Date(`${comparisonDate}T00:00:00`).getTime()
        : Date.now();

    const nextInstallments = installments.map((installment, index) => {
        const amount = Math.max(0, Number(installment?.amount || 0));
        const appliedPaidAmount = roundCurrencyAmount(Math.min(amount, remainingCollected));
        remainingCollected = roundCurrencyAmount(Math.max(0, remainingCollected - appliedPaidAmount));
        const dueDate = String(installment?.dueDate || '').trim().slice(0, 10);
        const dueTime = dueDate ? new Date(`${dueDate}T00:00:00`).getTime() : Number.POSITIVE_INFINITY;

        let status = installment?.status || 'pending';
        if (amount <= 0) {
            status = 'pending';
        } else if (appliedPaidAmount >= amount - 0.01) {
            status = 'paid';
        } else if (appliedPaidAmount > 0) {
            status = dueTime <= comparisonTime ? 'overdue' : 'partially-paid';
        } else {
            status = dueTime <= comparisonTime ? 'overdue' : 'pending';
        }

        return {
            ...installment,
            id: String(installment?.id || `installment-${index + 1}`),
            paidAmount: appliedPaidAmount,
            status,
        };
    });

    return {
        ...unit,
        collectedAmount: normalizedCollectedAmount,
        lastCollectionDate: latestCollectionDate,
        installments: nextInstallments,
    };
}

function buildAutoRealEstateInstallmentSchedule(params: {
    totalAmount: number;
    firstDueDate?: string;
    count: number;
    interval: 'monthly' | 'quarterly';
}) {
    const normalizedTotal = Math.max(0, roundCurrencyAmount(Number(params.totalAmount || 0)));
    const normalizedCount = Math.max(0, Math.floor(Number(params.count || 0)));
    const normalizedFirstDueDate = String(params.firstDueDate || '').trim();

    if (normalizedTotal <= 0 || normalizedCount <= 0 || !normalizedFirstDueDate) {
        return [] as RealEstateInstallment[];
    }

    const parsedFirstDueDate = new Date(normalizedFirstDueDate);
    if (Number.isNaN(parsedFirstDueDate.getTime())) {
        return [] as RealEstateInstallment[];
    }

    const intervalMonths = params.interval === 'quarterly' ? 3 : 1;
    const perInstallment = roundCurrencyAmount(normalizedTotal / normalizedCount);
    let remaining = normalizedTotal;

    return Array.from({ length: normalizedCount }, (_, index) => {
        const dueDate = format(addMonths(parsedFirstDueDate, index * intervalMonths), 'yyyy-MM-dd');
        const amount = index === normalizedCount - 1 ? roundCurrencyAmount(remaining) : perInstallment;
        remaining = roundCurrencyAmount(Math.max(0, remaining - amount));
        return {
            id: `auto-installment-${index + 1}`,
            title: `القسط ${index + 1}`,
            dueDate,
            amount,
            paidAmount: 0,
            status: 'pending' as const,
        };
    });
}

function extractRealEstateRefsFromInvoice(
    invoice: {
        items?: Array<{
            materialId?: string;
            total?: number;
            realEstateProjectId?: string;
            realEstateProjectName?: string;
            realEstateUnitId?: string;
            realEstateUnitName?: string;
        }>;
        realEstateProjectId?: string;
        realEstateProjectName?: string;
        realEstateUnitId?: string;
        realEstateUnitName?: string;
    } | undefined,
    materialById: Map<string, any>
) {
    const invoiceProjectId = String((invoice as any)?.realEstateProjectId || '').trim();
    const invoiceUnitId = String((invoice as any)?.realEstateUnitId || '').trim();
    const invoiceProjectName = String((invoice as any)?.realEstateProjectName || '').trim() || undefined;
    const invoiceUnitName = String((invoice as any)?.realEstateUnitName || '').trim() || undefined;

    return (invoice?.items || [])
        .map((item) => {
            const material = materialById.get(String(item.materialId || '').trim());
            const projectId = String(item.realEstateProjectId || material?.realEstateProjectId || invoiceProjectId || '').trim();
            const unitId = String(item.realEstateUnitId || material?.realEstateUnitId || invoiceUnitId || '').trim();
            if (!projectId || !unitId) return null;
            return {
                projectId,
                projectName: String(item.realEstateProjectName || material?.realEstateProjectName || invoiceProjectName || '').trim() || undefined,
                unitId,
                unitName: String(item.realEstateUnitName || material?.realEstateUnitName || invoiceUnitName || '').trim() || undefined,
                item,
            };
        })
        .filter(Boolean) as Array<{ projectId: string; projectName?: string; unitId: string; unitName?: string; item: SalesInvoiceItem }>;
}

export async function syncRealEstateCollectionsFromSalesReceipts(params: {
    invoiceIds: string[];
    paymentDate?: string;
}) {
    const normalizedInvoiceIds = Array.from(
        new Set((params.invoiceIds || []).map((invoiceId) => String(invoiceId || '').trim()).filter(Boolean))
    );

    if (normalizedInvoiceIds.length === 0) {
        return { success: true, updatedUnits: 0 };
    }

    const service = getSalesInvoiceService();
    const materials = await getMaterialsRuntime();
    const projects = await getRealEstateProjectsRuntime();
    if (projects.length === 0) {
        return { success: true, updatedUnits: 0 };
    }

    const materialById = new Map(materials.map((entry) => [String(entry.id || '').trim(), entry]));
    const seedInvoices = (await Promise.all(normalizedInvoiceIds.map((invoiceId) => service.getById(invoiceId))))
        .filter(Boolean) as Array<any>;

    const touchedRefs = new Set<string>();
    const touchedCustomers = new Set<string>();

    for (const invoice of seedInvoices) {
        touchedCustomers.add(String(invoice.customerId || '').trim());
        for (const ref of extractRealEstateRefsFromInvoice(invoice, materialById)) {
            touchedRefs.add(`${ref.projectId}::${ref.unitId}`);
        }
    }

    if (touchedRefs.size === 0) {
        return { success: true, updatedUnits: 0 };
    }

    const relevantInvoices = new Map<string, any>();
    for (const invoice of seedInvoices) {
        relevantInvoices.set(String(invoice.id || '').trim(), invoice);
    }

    for (const customerId of touchedCustomers) {
        if (!customerId) continue;
        const listed = await service.list({ customerId, take: 5000 });
        for (const invoice of listed.items || []) {
            const refs = extractRealEstateRefsFromInvoice(invoice, materialById);
            if (refs.some((entry) => touchedRefs.has(`${entry.projectId}::${entry.unitId}`))) {
                relevantInvoices.set(String(invoice.id || '').trim(), invoice);
            }
        }
    }

    const updatedProjects = [...projects];
    let updatedUnits = 0;
    let projectsChanged = false;

    for (const refKey of touchedRefs) {
        const [projectId, unitId] = refKey.split('::');
        const projectIndex = updatedProjects.findIndex((project) => String(project.id || '').trim() === projectId);
        if (projectIndex === -1) continue;

        const project = updatedProjects[projectIndex];
        const currentUnit = (project.units || []).find((unit) => String(unit.id || '').trim() === unitId);
        if (!currentUnit) continue;

        let totalCollected = 0;
        let totalContractValue = 0;
        let latestCollectionDate = pickLatestIsoDate([currentUnit.lastCollectionDate, params.paymentDate]);
        let buyerCustomerId = String(currentUnit.buyerCustomerId || '').trim() || undefined;
        let buyerName = String(currentUnit.buyerName || '').trim() || undefined;

        for (const invoice of relevantInvoices.values()) {
            if (String(invoice.status || 'active').trim() === 'cancelled') continue;
            if (String(invoice.type || 'sale').trim() === 'return') continue;

            const refs = extractRealEstateRefsFromInvoice(invoice, materialById)
                .filter((entry) => `${entry.projectId}::${entry.unitId}` === refKey);
            if (refs.length === 0) continue;

            const absoluteLineTotal = (invoice.items || []).reduce((sum, item) => sum + Math.max(0, Math.abs(Number(item.total || 0))), 0);
            if (absoluteLineTotal <= 0) continue;

            const invoiceLevelDiscount = Math.max(0, Number(((invoice as any)?.discountAmount ?? (invoice as any)?.invoiceDiscountAmount) || 0));
            const invoiceCollected = Math.max(0, Number(((invoice as any)?.amountPaid ?? (invoice as any)?.amountReceived) || 0));

            for (const entry of refs) {
                const grossLineAmount = Math.max(0, Math.abs(Number(entry.item.total || 0)));
                const proportionalDiscount = absoluteLineTotal > 0
                    ? roundCurrencyAmount((invoiceLevelDiscount * grossLineAmount) / absoluteLineTotal)
                    : 0;
                const netRevenue = Math.max(0, roundCurrencyAmount(grossLineAmount - proportionalDiscount));
                totalContractValue += netRevenue;
                totalCollected += absoluteLineTotal > 0
                    ? roundCurrencyAmount(invoiceCollected * (grossLineAmount / absoluteLineTotal))
                    : 0;
            }

            if (invoiceCollected > 0) {
                latestCollectionDate = pickLatestIsoDate([latestCollectionDate, String(invoice.date || '').slice(0, 10)]);
            }
            buyerCustomerId = String(invoice.customerId || '').trim() || buyerCustomerId;
            buyerName = String(invoice.customerName || '').trim() || buyerName;
        }

        const nextUnit = applyRealEstateInstallmentCollectionState({
            ...currentUnit,
            buyerCustomerId,
            buyerName,
            actualSaleValue: Math.max(0, Number(currentUnit.actualSaleValue || 0)) > 0
                ? currentUnit.actualSaleValue
                : roundCurrencyAmount(totalContractValue),
        }, totalCollected, latestCollectionDate);

        if (JSON.stringify(nextUnit) === JSON.stringify(currentUnit)) {
            continue;
        }

        updatedProjects[projectIndex] = {
            ...project,
            units: (project.units || []).map((unit) => String(unit.id || '').trim() === unitId ? nextUnit : unit),
            updatedAt: new Date().toISOString(),
        };
        updatedUnits += 1;
        projectsChanged = true;
    }

    if (projectsChanged) {
        await saveRealEstateProjectsRuntime(updatedProjects);
        revalidatePath('/admin/data/real-estate');
    }

    return { success: true, updatedUnits };
}

function appendJournalLine(lines: JournalEntryLine[], nextLine: JournalEntryLine) {
    const debit = roundCurrencyAmount(Number(nextLine.debit || 0));
    const credit = roundCurrencyAmount(Number(nextLine.credit || 0));
    if (debit <= 0 && credit <= 0) return;

    const existing = lines.find((line) =>
        String(line.accountCode || '').trim() === String(nextLine.accountCode || '').trim()
        && String(line.description || '').trim() === String(nextLine.description || '').trim()
    );
    if (existing) {
        existing.debit = roundCurrencyAmount(Number(existing.debit || 0) + debit);
        existing.credit = roundCurrencyAmount(Number(existing.credit || 0) + credit);
        return;
    }

    lines.push({
        ...nextLine,
        debit,
        credit,
    });
}

function calculateRealEstateUnitTotalCost(project: RealEstateProject, unitId: string): number {
    const normalizedUnitId = String(unitId || '').trim();
    if (!normalizedUnitId) return 0;

    const units = Array.isArray(project?.units) ? project.units : [];
    const sharedCosts = Array.isArray(project?.sharedCosts) ? project.sharedCosts : [];
    const currentUnit = units.find((unit) => String(unit?.id || '').trim() === normalizedUnitId);
    if (!currentUnit) return 0;

    const totalArea = units.reduce((sum, unit) => sum + Math.max(0, Number(unit?.area || 0)), 0);
    const totalSaleValue = units.reduce((sum, unit) => sum + Math.max(0, Number(unit?.saleValue || 0)), 0);

    const allocatedSharedCost = sharedCosts.reduce((sum, entry) => {
        const amount = Math.max(0, Number(entry?.amount || 0));
        if (amount <= 0) return sum;

        const allocationMethod = String(entry?.allocationMethod || 'area').trim();
        if (allocationMethod === 'sale-value') {
            return sum + (totalSaleValue > 0 ? (amount * Math.max(0, Number(currentUnit.saleValue || 0))) / totalSaleValue : 0);
        }

        if (allocationMethod === 'manual-share') {
            const manualShare = Array.isArray(entry?.unitAllocations)
                ? entry.unitAllocations.find((allocation) => String(allocation?.unitId || '').trim() === normalizedUnitId)
                : undefined;
            return sum + ((amount * Math.max(0, Number(manualShare?.percentage || 0))) / 100);
        }

        return sum + (totalArea > 0 ? (amount * Math.max(0, Number(currentUnit.area || 0))) / totalArea : 0);
    }, 0);

    return roundCurrencyAmount(Math.max(0, Number(currentUnit.directCost || 0)) + allocatedSharedCost);
}

async function syncRealEstateUnitSaleAccountingEntry(params: {
    invoice: SalesInvoice;
    customerName: string;
    createdBy: string;
    previousInvoice?: SalesInvoice;
}) {
    const invoiceId = String(params.invoice?.id || '').trim();
    if (!invoiceId) {
        return { success: true, entry: null, updatedUnits: 0 };
    }

    const autoEntryId = `je-realestate-sale-${invoiceId}`;
    const allJournalEntries = await getJournalEntriesRuntime();
    const nextJournalEntries = allJournalEntries.filter((entry) => String(entry.id || '').trim() !== autoEntryId);
    const materials = await getMaterialsRuntime();
    const projects = await getRealEstateProjectsRuntime();
    const accounts = await getChartOfAccountsRuntime();
    const materialById = new Map(materials.map((entry) => [String(entry.id || '').trim(), entry]));
    const updatedProjects = [...projects];
    const lines: JournalEntryLine[] = [];

    const isReturnInvoice = params.invoice.type === 'return';
    const isCancelledInvoice = String((params.invoice as any)?.status || 'active').trim() === 'cancelled';
    const absoluteLineTotal = (params.invoice.items || []).reduce((sum, item) => sum + Math.max(0, Math.abs(Number(item.total || 0))), 0);
    const invoiceLevelDiscount = Math.max(0, Number((params.invoice as any)?.discountAmount || 0));

    const extractRealEstateRefs = (invoice?: SalesInvoice) => extractRealEstateRefsFromInvoice(invoice as any, materialById)
        .map((entry) => ({
            ...entry,
            material: materialById.get(String(entry.item.materialId || '').trim()),
        }))
        .filter(Boolean) as Array<{ projectId: string; projectName?: string; unitId: string; unitName?: string; material: any; item: SalesInvoiceItem }>;

    const currentRefs = extractRealEstateRefs(params.invoice);
    const previousRefs = extractRealEstateRefs(params.previousInvoice);
    const touchedRefs = new Set([...currentRefs, ...previousRefs].map((entry) => `${entry.projectId}::${entry.unitId}`));
    const activeSaleRefs = !isReturnInvoice && !isCancelledInvoice
        ? new Set(currentRefs.map((entry) => `${entry.projectId}::${entry.unitId}`))
        : new Set<string>();

    let updatedUnits = 0;
    let projectsChanged = false;

    for (const ref of touchedRefs) {
        const [projectId, unitId] = ref.split('::');
        const projectIndex = updatedProjects.findIndex((entry) => String(entry.id || '').trim() === String(projectId || '').trim());
        if (projectIndex === -1) continue;

        let project = updatedProjects[projectIndex];
        if (!String(project?.accounting?.projectAccountCode || '').trim()) {
            const accounting = await ensureRealEstateAccountingSetup({
                id: String(project.id || '').trim(),
                name: String(project.name || '').trim(),
                code: String(project.code || '').trim(),
            });
            project = {
                ...project,
                accounting: {
                    ...(project.accounting || {}),
                    ...accounting,
                },
                updatedAt: new Date().toISOString(),
            };
            updatedProjects[projectIndex] = project;
            projectsChanged = true;
        }

        const shouldMarkSold = activeSaleRefs.has(ref);
        const nextUnits = (project.units || []).map((unit) => {
            if (String(unit.id || '').trim() !== String(unitId || '').trim()) return unit;
            const nextStatus = shouldMarkSold ? 'sold' : 'available';
            const nextUnit = shouldMarkSold
                ? applyRealEstateInstallmentCollectionState({
                    ...unit,
                    status: nextStatus as typeof unit.status,
                }, Number(unit.collectedAmount || 0), unit.lastCollectionDate)
                : applyRealEstateInstallmentCollectionState({
                    ...unit,
                    status: nextStatus as typeof unit.status,
                    buyerCustomerId: undefined,
                    buyerName: undefined,
                    contractDate: undefined,
                    actualSaleValue: 0,
                    collectedAmount: 0,
                    lastCollectionDate: undefined,
                }, 0);

            const hasChanged = JSON.stringify(unit) !== JSON.stringify(nextUnit);
            if (!hasChanged) return unit;
            updatedUnits += 1;
            return nextUnit;
        });

        const unitsChanged = nextUnits.some((unit, index) => unit !== (project.units || [])[index]);
        if (unitsChanged) {
            updatedProjects[projectIndex] = {
                ...project,
                units: nextUnits,
                updatedAt: new Date().toISOString(),
            };
            projectsChanged = true;
        }
    }

    const genericSalesAccount = ensureChartAccountInCollection(accounts, {
        preferredCode: '4110',
        nameAr: 'إيرادات المبيعات',
        nameEn: 'Sales Revenue',
        parentCode: '4100',
        nature: 'credit',
    }).account;
    const salesReturnAccount = ensureChartAccountInCollection(accounts, {
        preferredCode: '4111',
        nameAr: 'مردودات المبيعات',
        nameEn: 'Sales Returns',
        parentCode: '4100',
        nature: 'debit',
    }).account;

    if (!isCancelledInvoice) {
        for (const [index, entry] of currentRefs.entries()) {
            const projectIndex = updatedProjects.findIndex((project) => String(project.id || '').trim() === entry.projectId);
            if (projectIndex === -1) continue;
            let project = updatedProjects[projectIndex];
            let unit = (project.units || []).find((item) => String(item.id || '').trim() === entry.unitId);
            if (!unit) continue;

            const salesRevenueAccount = accounts.find((account) => String(account.code || '').trim() === String(project.accounting?.salesRevenueAccountCode || '').trim() && account.type === 'account')
                || ensureChartAccountInCollection(accounts, {
                    preferredCode: '4114',
                    nameAr: 'إيرادات بيع الوحدات العقارية',
                    nameEn: 'Real Estate Unit Sales Revenue',
                    parentCode: '4110',
                    nature: 'credit',
                }).account;
            const costOfSalesAccount = accounts.find((account) => String(account.code || '').trim() === String(project.accounting?.costOfSalesAccountCode || '').trim() && account.type === 'account')
                || ensureChartAccountInCollection(accounts, {
                    preferredCode: '5171',
                    nameAr: 'تكلفة الوحدات العقارية المباعة',
                    nameEn: 'Cost of Real Estate Units Sold',
                    parentCode: '5100',
                    nature: 'debit',
                }).account;
            const projectAccount = accounts.find((account) => String(account.code || '').trim() === String(project.accounting?.projectAccountCode || '').trim() && account.type === 'account')
                || ensureChartAccountInCollection(accounts, {
                    preferredCode: '1192',
                    nameAr: 'تكاليف مباشرة للمشاريع العقارية',
                    nameEn: 'Real Estate Direct Costs',
                    parentCode: '1191',
                    nature: 'debit',
                }).account;

            const grossLineAmount = Math.max(0, Math.abs(Number(entry.item.total || 0)));
            const proportionalDiscount = absoluteLineTotal > 0 ? roundCurrencyAmount((invoiceLevelDiscount * grossLineAmount) / absoluteLineTotal) : 0;
            const netRevenue = Math.max(0, roundCurrencyAmount(grossLineAmount - proportionalDiscount));
            const allocatedCollected = absoluteLineTotal > 0
                ? roundCurrencyAmount(Math.max(0, Number(params.invoice.amountPaid || 0)) * (grossLineAmount / absoluteLineTotal))
                : 0;
            const unitCost = Math.max(0, roundCurrencyAmount(calculateRealEstateUnitTotalCost(project, entry.unitId) * Math.max(1, Number((entry.item as any).quantity || 1))));
            const unitLabel = String(unit.name || unit.unitCode || `Unit ${index + 1}`).trim();
            const revenueDescription = isReturnInvoice
                ? `عكس إيراد بيع الوحدة ${unitLabel} - ${project.name} - ${params.customerName}`
                : `إيراد بيع الوحدة ${unitLabel} - ${project.name} - ${params.customerName}`;
            const costDescription = isReturnInvoice
                ? `عكس تكلفة بيع الوحدة ${unitLabel} - ${project.name}`
                : `تكلفة بيع الوحدة ${unitLabel} - ${project.name}`;

            if (!isReturnInvoice) {
                const requestedContractValue = Math.max(0, Number((params.invoice as any).realEstateContractValue || 0));
                const requestedDownPayment = Math.max(0, Number((params.invoice as any).realEstateDownPayment || 0));
                const requestedDeferredAmount = Math.max(0, Number((params.invoice as any).realEstateDeferredAmount || 0));
                const requestedInstallmentMode = String((params.invoice as any).realEstateInstallmentMode || 'existing').trim() === 'auto' ? 'auto' : 'existing';
                const requestedInstallmentCount = Math.max(0, Number((params.invoice as any).realEstateInstallmentCount || 0));
                const requestedFirstDueDate = String((params.invoice as any).realEstateFirstDueDate || '').slice(0, 10);
                const requestedInstallmentInterval = String((params.invoice as any).realEstateInstallmentInterval || 'monthly').trim() === 'quarterly' ? 'quarterly' : 'monthly';

                const nextUnits = (project.units || []).map((currentUnitItem) => {
                    if (String(currentUnitItem.id || '').trim() !== entry.unitId) return currentUnitItem;
                    const nextCollectedAmount = Math.max(Number(currentUnitItem.collectedAmount || 0), allocatedCollected);
                    const generatedInstallments = requestedInstallmentMode === 'auto'
                        ? buildAutoRealEstateInstallmentSchedule({
                            totalAmount: requestedDeferredAmount > 0
                                ? requestedDeferredAmount
                                : Math.max(0, (requestedContractValue > 0 ? requestedContractValue : netRevenue) - Math.max(requestedDownPayment, allocatedCollected)),
                            firstDueDate: requestedFirstDueDate,
                            count: requestedInstallmentCount,
                            interval: requestedInstallmentInterval,
                        })
                        : [];
                    const nextInstallments = generatedInstallments.length > 0
                        ? generatedInstallments
                        : (Array.isArray(currentUnitItem.installments) ? currentUnitItem.installments : []);

                    return applyRealEstateInstallmentCollectionState({
                        ...currentUnitItem,
                        status: 'sold' as const,
                        buyerCustomerId: String(params.invoice.customerId || '').trim() || currentUnitItem.buyerCustomerId,
                        buyerName: String(params.customerName || currentUnitItem.buyerName || '').trim() || undefined,
                        contractDate: String((params.invoice as any).realEstateContractDate || params.invoice.date || currentUnitItem.contractDate || '').slice(0, 10) || currentUnitItem.contractDate,
                        handoverDate: String((params.invoice as any).realEstateHandoverDate || currentUnitItem.handoverDate || '').slice(0, 10) || currentUnitItem.handoverDate,
                        actualSaleValue: requestedContractValue > 0 ? requestedContractValue : netRevenue,
                        collectedAmount: nextCollectedAmount,
                        lastCollectionDate: allocatedCollected > 0 ? String(params.invoice.date || '').slice(0, 10) : currentUnitItem.lastCollectionDate,
                        installments: nextInstallments,
                    }, nextCollectedAmount, allocatedCollected > 0 ? String(params.invoice.date || '').slice(0, 10) : currentUnitItem.lastCollectionDate);
                });
                const updatedUnit = nextUnits.find((item) => String(item.id || '').trim() === entry.unitId);
                if (updatedUnit && JSON.stringify(updatedUnit) !== JSON.stringify(unit)) {
                    updatedProjects[projectIndex] = {
                        ...project,
                        units: nextUnits,
                        updatedAt: new Date().toISOString(),
                    };
                    project = updatedProjects[projectIndex];
                    unit = updatedUnit;
                    projectsChanged = true;
                }
            }

            if (netRevenue > 0) {
                if (isReturnInvoice) {
                    appendJournalLine(lines, {
                        accountId: String(salesRevenueAccount.id || salesRevenueAccount.code || '4114'),
                        accountCode: String(salesRevenueAccount.code || '4114'),
                        accountName: String(salesRevenueAccount.nameAr || salesRevenueAccount.nameEn || 'إيرادات بيع الوحدات العقارية'),
                        debit: netRevenue,
                        credit: 0,
                        description: revenueDescription,
                    });
                    appendJournalLine(lines, {
                        accountId: String(salesReturnAccount.id || salesReturnAccount.code || '4111'),
                        accountCode: String(salesReturnAccount.code || '4111'),
                        accountName: String(salesReturnAccount.nameAr || salesReturnAccount.nameEn || 'مردودات المبيعات'),
                        debit: 0,
                        credit: netRevenue,
                        description: revenueDescription,
                    });
                } else {
                    appendJournalLine(lines, {
                        accountId: String(genericSalesAccount.id || genericSalesAccount.code || '4110'),
                        accountCode: String(genericSalesAccount.code || '4110'),
                        accountName: String(genericSalesAccount.nameAr || genericSalesAccount.nameEn || 'إيرادات المبيعات'),
                        debit: netRevenue,
                        credit: 0,
                        description: revenueDescription,
                    });
                    appendJournalLine(lines, {
                        accountId: String(salesRevenueAccount.id || salesRevenueAccount.code || '4114'),
                        accountCode: String(salesRevenueAccount.code || '4114'),
                        accountName: String(salesRevenueAccount.nameAr || salesRevenueAccount.nameEn || 'إيرادات بيع الوحدات العقارية'),
                        debit: 0,
                        credit: netRevenue,
                        description: revenueDescription,
                    });
                }
            }

            if (unitCost > 0) {
                if (isReturnInvoice) {
                    appendJournalLine(lines, {
                        accountId: String(projectAccount.id || projectAccount.code || '1192'),
                        accountCode: String(projectAccount.code || '1192'),
                        accountName: String(projectAccount.nameAr || projectAccount.nameEn || 'مشروع عقاري'),
                        debit: unitCost,
                        credit: 0,
                        description: costDescription,
                    });
                    appendJournalLine(lines, {
                        accountId: String(costOfSalesAccount.id || costOfSalesAccount.code || '5171'),
                        accountCode: String(costOfSalesAccount.code || '5171'),
                        accountName: String(costOfSalesAccount.nameAr || costOfSalesAccount.nameEn || 'تكلفة الوحدات العقارية المباعة'),
                        debit: 0,
                        credit: unitCost,
                        description: costDescription,
                    });
                } else {
                    appendJournalLine(lines, {
                        accountId: String(costOfSalesAccount.id || costOfSalesAccount.code || '5171'),
                        accountCode: String(costOfSalesAccount.code || '5171'),
                        accountName: String(costOfSalesAccount.nameAr || costOfSalesAccount.nameEn || 'تكلفة الوحدات العقارية المباعة'),
                        debit: unitCost,
                        credit: 0,
                        description: costDescription,
                    });
                    appendJournalLine(lines, {
                        accountId: String(projectAccount.id || projectAccount.code || '1192'),
                        accountCode: String(projectAccount.code || '1192'),
                        accountName: String(projectAccount.nameAr || projectAccount.nameEn || 'مشروع عقاري'),
                        debit: 0,
                        credit: unitCost,
                        description: costDescription,
                    });
                }
            }
        }
    }

    if (projectsChanged) {
        await saveRealEstateProjectsRuntime(updatedProjects);
    }
    await saveChartOfAccountsRuntime(accounts);

    if (lines.length === 0) {
        if (nextJournalEntries.length !== allJournalEntries.length) {
            await saveJournalEntriesRuntime(nextJournalEntries);
        }
        revalidatePath('/admin/data/real-estate');
        revalidatePath('/admin/accounting/entries');
        revalidatePath('/admin/sales');
        return { success: true, entry: null, updatedUnits };
    }

    const entry: JournalEntry = {
        id: autoEntryId,
        date: String(params.invoice.date || new Date().toISOString()),
        description: isReturnInvoice
            ? `قيد عكس بيع وحدات عقارية من الفاتورة ${String(params.invoice.invoiceNumber || invoiceId)}`
            : `قيد بيع وحدات عقارية من الفاتورة ${String(params.invoice.invoiceNumber || invoiceId)}`,
        referenceType: 'sales_invoice',
        referenceId: String(params.invoice.invoiceNumber || invoiceId),
        invoiceId,
        lines,
        createdBy: params.createdBy,
        createdAt: new Date().toISOString(),
    };

    nextJournalEntries.unshift(entry);
    await saveJournalEntriesRuntime(nextJournalEntries);

    revalidatePath('/admin/data/real-estate');
    revalidatePath('/admin/accounting/entries');
    revalidatePath('/admin/sales');
    return { success: true, entry, updatedUnits };
}

export async function handlePostRealEstateCostEntry(values: z.infer<typeof realEstateCostPostingSchema>) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const parsed = realEstateCostPostingSchema.safeParse(values);
    if (!parsed.success) {
        console.error(parsed.error.flatten());
        return { error: 'Invalid data submitted.' };
    }

    const { projectId, itemId, date, amount, paymentSource, note } = parsed.data;
    const projects = await getRealEstateProjectsRuntime();
    const projectIndex = projects.findIndex((entry) => String(entry.id || '').trim() === String(projectId || '').trim());
    if (projectIndex === -1) {
        return { error: 'Real-estate project not found.' };
    }

    const project = projects[projectIndex];
    const accountingSetup = await ensureRealEstateAccountingSetup({
        id: String(project.id || '').trim(),
        name: String(project.name || '').trim(),
        code: String(project.code || '').trim(),
    });

    const nextProject = {
        ...project,
        accounting: {
            ...(project.accounting || {}),
            ...accountingSetup,
        },
    } as RealEstateProject;
    const nextProjects = [...projects];
    nextProjects[projectIndex] = nextProject;
    await saveRealEstateProjectsRuntime(nextProjects);

    const materials = await getMaterialsRuntime();
    const expenses = await getExpensesRuntime();
    const selectedItem = [...materials, ...expenses].find((entry) => String(entry.id || '').trim() === String(itemId || '').trim());
    if (!selectedItem) {
        return { error: 'Linked item not found.' };
    }

    const accounts = await getChartOfAccountsRuntime();
    const cashAccount = ensureChartAccountInCollection(accounts, {
        preferredCode: '1110',
        nameAr: 'الصندوق',
        nameEn: 'Cash',
        parentCode: '1100',
        nature: 'debit',
    }).account;
    const bankAccount = ensureChartAccountInCollection(accounts, {
        preferredCode: '1120',
        nameAr: 'البنك',
        nameEn: 'Bank',
        parentCode: '1100',
        nature: 'debit',
    }).account;
    const payableAccount = ensureChartAccountInCollection(accounts, {
        preferredCode: '2130',
        nameAr: 'مصروفات مستحقة',
        nameEn: 'Accrued Expenses',
        parentCode: '2100',
        nature: 'credit',
    }).account;
    await saveChartOfAccountsRuntime(accounts);

    const itemCostType = String(selectedItem.realEstateCostType || 'general').trim();
    const unit = (nextProject.units || []).find((entry) => String(entry.id || '').trim() === String(selectedItem.realEstateUnitId || '').trim());
    const debitAccountCode = String(
        nextProject.accounting?.projectAccountCode
        || (itemCostType === 'shared-project' ? nextProject.accounting?.sharedCostAccountCode : nextProject.accounting?.directCostAccountCode)
        || nextProject.accounting?.projectsRootAccountCode
        || '1192'
    ).trim();
    const debitAccount = accounts.find((entry) => String(entry.code || '').trim() === debitAccountCode) || cashAccount;
    const settlementAccount = paymentSource === 'bank'
        ? bankAccount
        : paymentSource === 'payable'
            ? payableAccount
            : cashAccount;

    const normalizedDate = String(date || new Date().toISOString()).trim() || new Date().toISOString();
    const normalizedAmount = Math.round(Number(amount || 0) * 100) / 100;
    const costTypeLabel = itemCostType === 'direct-unit'
        ? 'تكلفة مباشرة'
        : itemCostType === 'shared-project'
            ? 'تكلفة مشتركة'
            : 'تكلفة عامة';
    const itemLabel = String(selectedItem.name || '').trim() || String(itemId || '').trim();
    const unitLabel = unit ? ` - ${String(unit.name || unit.unitCode || '').trim()}` : '';
    const description = String(note || '').trim() || `قيد تكلفة ${costTypeLabel} للمشروع ${nextProject.name}${unitLabel} - ${itemLabel}`;
    const now = new Date().toISOString();

    const entry: JournalEntry = {
        id: nextPrefixedId('je-recost'),
        date: normalizedDate,
        description,
        referenceType: 'expense',
        referenceId: nextProject.id,
        lines: [
            {
                accountId: String(debitAccount.id || debitAccount.code || '1192'),
                accountCode: String(debitAccount.code || '1192'),
                accountName: String(debitAccount.nameAr || debitAccount.nameEn || 'مشروع عقاري'),
                debit: normalizedAmount,
                credit: 0,
                description,
            },
            {
                accountId: String(settlementAccount.id || settlementAccount.code || '1110'),
                accountCode: String(settlementAccount.code || '1110'),
                accountName: String(settlementAccount.nameAr || settlementAccount.nameEn || 'الصندوق'),
                debit: 0,
                credit: normalizedAmount,
                description,
            },
        ],
        createdBy: session.user.name || session.user.id,
        createdAt: now,
    };

    const journalEntries = await getJournalEntriesRuntime();
    journalEntries.unshift(entry);
    await saveJournalEntriesRuntime(journalEntries);

    revalidatePath('/admin/data/real-estate');
    revalidatePath('/admin/accounting/entries');
    return { success: true, entry };
}

export async function handleCreateDisassemblyRecord(values: z.infer<typeof disassemblyRecordSchema>) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const parsed = disassemblyRecordSchema.safeParse(values);
    if (!parsed.success) {
        console.error(parsed.error.flatten());
        return { error: 'Invalid data submitted.' };
    }

    const {
        date,
        parentItemId,
        parentQuantity,
        purchaseCost,
        additionalCost,
        sourceWarehouseId,
        sourceShelfId,
        targetWarehouseId,
        targetShelfId,
        notes,
        parts,
    } = parsed.data;

    const materials = await getMaterialsRuntime();
    const parent = materials.find((entry) => String(entry.id || '').trim() === String(parentItemId || '').trim());
    if (!parent) {
        return { error: 'Parent item not found.' };
    }

    if (parent.isDisassemblable !== true) {
        return { error: 'This item is not configured as disassemblable.' };
    }

    const normalizedParentQuantity = Number(parentQuantity || 0);
    if (!Number.isFinite(normalizedParentQuantity) || normalizedParentQuantity <= 0) {
        return { error: 'Parent quantity must be greater than zero.' };
    }

    const normalizedPurchaseCost = Math.max(0, Number(purchaseCost || 0));
    const normalizedAdditionalCost = Math.max(0, Number(additionalCost || 0));
    const totalCostBasis = normalizedPurchaseCost + normalizedAdditionalCost;

    const normalizedParts = parts
        .map((entry) => ({
            partItemId: String(entry.partItemId || '').trim(),
            quantity: Number(entry.quantity || 0),
            expectedSalePrice: Math.max(0, Number(entry.expectedSalePrice || 0)),
            notes: String(entry.notes || '').trim() || undefined,
        }))
        .filter((entry) => entry.partItemId && Number.isFinite(entry.quantity) && entry.quantity > 0);

    if (normalizedParts.length === 0) {
        return { error: 'No valid parts were provided.' };
    }

    const duplicatePartIds = new Set<string>();
    for (const entry of normalizedParts) {
        if (duplicatePartIds.has(entry.partItemId)) {
            return { error: 'Each part must appear only once in the disassembly document.' };
        }
        duplicatePartIds.add(entry.partItemId);
    }

    const sourceWarehouse = String(sourceWarehouseId || '').trim();
    const sourceShelf = String(sourceShelfId || '').trim();
    const targetWarehouse = String(targetWarehouseId || sourceWarehouse || '').trim();
    const targetShelf = String(targetShelfId || sourceShelf || '').trim();
    const settings = await getSettingsRuntime();
    const warehousesEnabled = settings?.warehousesEnabled === true || settings?.warehousesEnabled === 'true';

    if (warehousesEnabled) {
        if (!sourceWarehouse || !sourceShelf || !targetWarehouse || !targetShelf) {
            return { error: 'Warehouse and shelf selection is required for disassembly.' };
        }

        const availableParentStock = getAvailableStock(parent.id, sourceWarehouse, sourceShelf);
        if (availableParentStock < normalizedParentQuantity) {
            return { error: `Insufficient stock for parent item ${parent.name}.` };
        }
    }

    const missingPart = normalizedParts.find((entry) => !materials.some((material) => String(material.id || '').trim() === entry.partItemId));
    if (missingPart) {
        return { error: `Part item ${missingPart.partItemId} not found.` };
    }

    const saleValueTotal = normalizedParts.reduce((sum, entry) => sum + (entry.expectedSalePrice * entry.quantity), 0);
    if (!Number.isFinite(saleValueTotal) || saleValueTotal <= 0) {
        return { error: 'Expected sale prices are required to allocate the cost proportionally.' };
    }

    const disassemblyRecords = await getDisassemblyRecordsRuntime();
    const effectiveDate = String(date || new Date().toISOString()).trim();
    const fiscalYear = new Date(effectiveDate).getFullYear() || new Date().getFullYear();
    const sequence = disassemblyRecords.filter((record) => String(record.recordNumber || '').includes(`/${fiscalYear}/`)).length + 1;
    const recordId = nextPrefixedId('disassembly');
    const recordNumber = `DIS/${fiscalYear}/${String(sequence).padStart(4, '0')}`;

    let remainingAllocatedCost = totalCostBasis;
    const recordParts = normalizedParts.map((entry, index) => {
        const partMaterial = materials.find((material) => String(material.id || '').trim() === entry.partItemId);
        if (!partMaterial) {
            throw new Error(`Part item ${entry.partItemId} not found.`);
        }

        const saleValue = entry.expectedSalePrice * entry.quantity;
        const isLast = index === normalizedParts.length - 1;
        const allocatedCost = isLast
            ? remainingAllocatedCost
            : Math.round(((saleValue / saleValueTotal) * totalCostBasis) * 100) / 100;
        remainingAllocatedCost = Math.round((remainingAllocatedCost - allocatedCost) * 100) / 100;
        const costPerUnit = entry.quantity > 0 ? Math.round((allocatedCost / entry.quantity) * 100) / 100 : 0;

        return {
            partItemId: entry.partItemId,
            partName: partMaterial.name,
            quantity: entry.quantity,
            expectedSalePrice: entry.expectedSalePrice,
            allocatedCost,
            costPerUnit,
            sourceParentItemId: parent.id,
            notes: entry.notes,
        };
    });

    const createdAt = new Date().toISOString();
    const record: DisassemblyRecord = {
        id: recordId,
        recordNumber,
        date: effectiveDate,
        parentItemId: parent.id,
        parentItemName: parent.name,
        parentQuantity: normalizedParentQuantity,
        sourceWarehouseId: sourceWarehouse || undefined,
        sourceShelfId: sourceShelf || undefined,
        targetWarehouseId: targetWarehouse || undefined,
        targetShelfId: targetShelf || undefined,
        purchaseCost: normalizedPurchaseCost,
        additionalCost: normalizedAdditionalCost || undefined,
        totalCostAllocated: totalCostBasis,
        parts: recordParts,
        notes: String(notes || '').trim() || undefined,
        createdBy: session.user.name || session.user.username || 'system',
        createdAt,
    };

    const movementDate = effectiveDate || createdAt;
    const movementEntries: Array<Omit<InventoryMovement, 'id'>> = [
        {
            date: movementDate,
            materialId: parent.id,
            warehouseId: sourceWarehouse,
            shelfId: sourceShelf,
            quantityIn: 0,
            quantityOut: normalizedParentQuantity,
            referenceType: 'disassembly',
            referenceId: record.id,
            costPerUnitOriginal: normalizedParentQuantity > 0 ? Math.round((totalCostBasis / normalizedParentQuantity) * 100) / 100 : undefined,
            sourceParentItemId: parent.id,
            sourceParentRecordId: record.id,
            note: record.notes,
        },
        ...record.parts.map((part) => ({
            date: movementDate,
            materialId: part.partItemId,
            warehouseId: targetWarehouse,
            shelfId: targetShelf,
            quantityIn: part.quantity,
            quantityOut: 0,
            referenceType: 'disassembly',
            referenceId: record.id,
            costPerUnitOriginal: part.costPerUnit,
            sourceParentItemId: parent.id,
            sourceParentRecordId: record.id,
            note: part.notes,
        })),
    ];

    if (isPostgresProviderEnabled()) {
        const pgMovements = movementEntries.map((entry) => ({
            ...entry,
            id: nextPrefixedId('inv-move'),
        }));
        await pgSaveInventoryMovements(pgMovements as Array<Record<string, unknown>>);
    } else {
        addInventoryMovements(movementEntries);
    }

    for (const part of record.parts) {
        const existing = materials.find((entry) => String(entry.id || '').trim() === part.partItemId);
        if (!existing) continue;

        const updates = {
            ...existing,
            purchasePrice: part.costPerUnit,
            salePrice: Number(existing.salePrice || 0) > 0 ? existing.salePrice : part.expectedSalePrice,
        };

        if (isPostgresProviderEnabled()) {
            await pgUpdateMaterial(existing.id, updates as any);
        } else {
            updateMaterial(existing.id, updates as any);
        }
    }

    await saveDisassemblyRecordsRuntime([record, ...disassemblyRecords]);

    revalidatePath('/admin/data/disassembly');
    revalidatePath('/admin/data/materials');
    revalidatePath('/admin/data/material-movements');

    return { success: true, record };
}

export async function handleUpdateGeneralSettings(values: z.infer<typeof generalSettingsSchema>) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const parsed = generalSettingsSchema.safeParse(values);
    if (!parsed.success) {
      const firstError = parsed.error.errors[0];
      const errorMsg = firstError ? `حقل "${firstError.path.join('.')}" — ${firstError.message}` : 'Invalid data submitted.';
      console.error('[handleUpdateGeneralSettings] validation failed:', parsed.error.flatten());
      return { error: errorMsg };
    }

    const currentSettings = await getSettingsRuntime();

    const businessMode = parsed.data.businessMode || 'inventory';
    const realEstateModeEnabled = businessMode === 'real-estate' || businessMode === 'hybrid';
    const inventoryOnlyMode = businessMode === 'real-estate';
    const inventoryFeaturesEnabled = businessMode === 'inventory' || businessMode === 'hybrid';

    const normalizedValues = inventoryOnlyMode
      ? {
          ...parsed.data,
          businessMode,
          realEstateEnabled: realEstateModeEnabled,
          warehousesEnabled: false,
          allowOutOfStockSales: false,
          purchaseShelfTaskEnabled: false,
          salesShipmentWorkflowEnabled: false,
          defaultSalesWarehouseId: '',
          defaultSalesShelfId: '',
          defaultPurchaseWarehouseId: '',
          defaultPurchaseShelfId: '',
          scaleMode: 'manual' as const,
          scaleReadRegex: '([0-9]+(?:[\\.,][0-9]+)?)',
          scaleDecimalSeparator: 'auto' as const,
          scaleHidMinLength: 3,
          scaleSerialBaudRate: 9600,
          scaleSerialDataBits: 8,
          scaleSerialStopBits: 1,
          scaleSerialParity: 'none' as const,
          scaleSerialAutoConnect: false,
        }
      : inventoryFeaturesEnabled && parsed.data.warehousesEnabled
        ? {
            ...parsed.data,
            businessMode,
            realEstateEnabled: realEstateModeEnabled,
          }
        : {
            ...parsed.data,
            businessMode,
            realEstateEnabled: realEstateModeEnabled,
            warehousesEnabled: inventoryFeaturesEnabled ? parsed.data.warehousesEnabled : false,
            allowOutOfStockSales: false,
            purchaseShelfTaskEnabled: false,
            salesShipmentWorkflowEnabled: false,
            defaultSalesWarehouseId: '',
            defaultSalesShelfId: '',
            defaultPurchaseWarehouseId: '',
            defaultPurchaseShelfId: '',
          };

    // Prevent changing base/app currency when lock is enabled and purchase orders exist
    const requestedCurrency = normalizedValues.appCurrency;
    const currentCurrency = currentSettings.appCurrency;
    const lockBase = normalizedValues.fxLockBaseCurrency === true;
    if (lockBase && requestedCurrency && requestedCurrency !== currentCurrency) {
        const existingPo = await getPurchaseOrdersRuntime();
        if (existingPo.length > 0) {
            return { error: 'BASE_CURRENCY_LOCKED' };
        }
    }

    const newSettings = { ...currentSettings, ...normalizedValues };
    
    await saveSettingsRuntime(newSettings);

    revalidatePath('/admin/general-settings');
    revalidatePath('/settings');
    revalidatePath('/admin/sales/pos');
    revalidatePath('/'); // Revalidate root layout for app name/logo changes
    
    return { success: true, message: "Settings updated." };
}

// Sales Invoice Edit and Delete Actions
export async function handleUpdateInvoice(invoiceId: string, updates: z.infer<typeof saleInvoiceSchema>) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };
    if (!acquireMutationWindow(`update-invoice:${session.user.id}:${invoiceId}`)) {
        return { error: 'REQUEST_DEBOUNCED' };
    }

    const parsed = saleInvoiceSchema.safeParse(updates);
    if (!parsed.success) {
        console.error(parsed.error.flatten());
        return { error: 'Invalid data submitted.' };
    }

    const { customerId, amountPaid, discountAmount, items: formItems } = parsed.data;

    // Get current invoice
    const invoices = getInvoices();
    const currentInvoice = invoices.find(inv => inv.id === invoiceId);
    if (!currentInvoice) {
        return { error: 'Invoice not found.' };
    }

    // Get customer info
    const allCustomers = await getCustomersRuntime();
    const customer = allCustomers.find(c => c.id === customerId);
    if (!customer) return { error: 'Customer not found.' };
    const salesRepId = customer.salesRepId || '';

    // Recalculate items with pricing
    const materials = await getMaterialsRuntime();
    const allPricing = await getCustomerPricingForCalc();
    const customerPricing = allPricing.find(p => p.category === (customer.category || 'general'));

    const calculatedItems: SalesInvoiceItem[] = formItems.map(item => {
        const material = materials.find(m => m.id === item.materialId);
        if (!material) throw new Error(`Material with ID ${item.materialId} not found`);

        const unitPrice = item.unitPrice;
        const lineSubtotal = item.quantity * unitPrice;
        const lineDiscount = Math.min(Math.max(Number(item.discount || 0), 0), lineSubtotal);
        const normalizedDescription = (item.description || '').trim();

        let bonus = 0;
        const bonusRule = customerPricing?.bonus;
        if (bonusRule && bonusRule.materialId === item.materialId && bonusRule.buyQuantity > 0 && item.quantity > 0) {
            bonus = Math.floor(item.quantity / bonusRule.buyQuantity) * bonusRule.bonusQuantity;
        }

        return {
            materialId: item.materialId,
            name: material.name,
            description: normalizedDescription || undefined,
            quantity: item.quantity,
            unitPrice,
            bonus,
            discount: lineDiscount,
            total: lineSubtotal - lineDiscount,
            warehouseId: (item.warehouseId || '').trim() || undefined,
            shelfId: (item.shelfId || '').trim() || undefined,
        };
    });

    const itemsSubTotal = calculatedItems.reduce((sum, item) => sum + item.total, 0);
    const bonusAmount = calculatedItems.reduce((sum, item) => sum + (item.bonus ? item.bonus * item.unitPrice : 0), 0);
    const safeDiscountAmount = Math.min(Math.max(Number(discountAmount || 0), 0), itemsSubTotal);
    const grandTotal = itemsSubTotal - safeDiscountAmount;
    const subTotal = itemsSubTotal;
    const amountDue = grandTotal - amountPaid;

    // Update customer balance (adjust the difference)
    const oldAmountDue = currentInvoice.amountDue;
    const balanceDifference = amountDue - oldAmountDue;
    customer.balance += balanceDifference;
    await saveCustomersRuntime(allCustomers);

    // Create reversing journal entry for the old invoice, then create new entry
    try {
        const journalEntries = await getJournalEntriesRuntime();
        const originalEntry = journalEntries.find(je => je.referenceId === currentInvoice.invoiceNumber && je.referenceType === 'sales_invoice');
        
        if (originalEntry) {
            // Step 1: Create a reversing entry for the old invoice
            const reversingEntry: JournalEntry = {
                id: nextPrefixedId('je-reverse'),
                date: new Date().toISOString(),
                description: `تحويل عكسي لتعديل الفاتورة ${currentInvoice.invoiceNumber}`,
                referenceType: 'sales_invoice',
                referenceId: currentInvoice.invoiceNumber,
                lines: originalEntry.lines.map(line => ({
                    ...line,
                    debit: line.credit,
                    credit: line.debit,
                })),
                createdBy: session.user.name || 'admin',
                createdAt: new Date().toISOString(),
            };
            
            journalEntries.push(reversingEntry);
            await saveJournalEntriesRuntime(journalEntries);
        }

        // Step 2: Create new journal entry with updated values
        const accounts = await getChartOfAccountsRuntime();
        const salesDiscountAccounting = await ensureSalesDiscountAccountingSetup();
        const grossRevenueTotal = Math.abs(grandTotal) + safeDiscountAmount + bonusAmount;
        const revenueBreakdown = buildRevenueBreakdownForSalesInvoice({
            items: calculatedItems,
            materials: materials as Array<Record<string, any>>,
            accounts: accounts as Array<Record<string, any>>,
            grossTotal: grossRevenueTotal,
        });
        const customerArCode = String((customer as any)?.accountCode || '').trim();
        const customerArAccount = customerArCode
            ? (accounts as Array<Record<string, any>>).find((acc) => String(acc?.code || '').trim() === customerArCode)
            : null;
        const employeeCashCode = String((session.user as any)?.employeeCashAccountCode || '').trim();
        const employeeCashAccount = employeeCashCode
            ? (accounts as Array<Record<string, any>>).find((acc) => String(acc?.code || '').trim() === employeeCashCode)
            : null;

        const newEntry = await buildSalesInvoiceJournalEntryRecord({
            entryId: nextPrefixedId('je'),
            invoiceId: currentInvoice.invoiceNumber,
            customerName: customer.name,
            customerAccountCode: customerArCode || undefined,
            customerAccountName: customerArAccount ? String(customerArAccount.nameAr || customerArAccount.nameEn || '') : undefined,
            cashAccountCode: employeeCashCode || undefined,
            cashAccountName: employeeCashAccount ? String(employeeCashAccount.nameAr || employeeCashAccount.nameEn || '') : undefined,
            grandTotal,
            discountAmount: safeDiscountAmount,
            campaignDiscountAmount: 0,
            bonusAmount,
            amountPaid,
            createdBy: session.user.name || 'admin',
            isReturn: false,
            paymentBreakdown: [],
            revenueBreakdown,
            salesDiscountAccountCode: salesDiscountAccounting.salesDiscountAccountCode,
            salesDiscountAccountName: salesDiscountAccounting.salesDiscountAccountName,
            campaignDiscountAccountCode: salesDiscountAccounting.campaignDiscountAccountCode,
            campaignDiscountAccountName: salesDiscountAccounting.campaignDiscountAccountName,
            bonusDiscountAccountCode: salesDiscountAccounting.bonusDiscountAccountCode,
            bonusDiscountAccountName: salesDiscountAccounting.bonusDiscountAccountName,
            salesReturnAccountCode: salesDiscountAccounting.salesReturnAccountCode,
            salesReturnAccountName: salesDiscountAccounting.salesReturnAccountName,
        });
        journalEntries.push(newEntry);
        await saveJournalEntriesRuntime(journalEntries);
    } catch (error) {
        console.error('Failed to create journal entries for invoice update:', error);
        // Continue anyway - invoice was updated successfully
    }

    // Update invoice with lock checking
    const result = updateInvoice(invoiceId, {
        customerId,
        customerName: customer.name,
        salesRepId,
        items: calculatedItems,
        subTotal,
        grandTotal,
        discountAmount: safeDiscountAmount,
        amountPaid,
        amountDue,
    }, session.user.id);

    if (!result.success) {
        return { error: result.error || 'Failed to update invoice.' };
    }

    try {
        await syncRealEstateUnitSaleAccountingEntry({
            invoice: {
                ...currentInvoice,
                customerId,
                customerName: customer.name,
                salesRepId,
                items: calculatedItems,
                subTotal,
                grandTotal,
                discountAmount: safeDiscountAmount,
                amountPaid,
                amountDue,
                status: currentInvoice.status || 'active',
            } as SalesInvoice,
            previousInvoice: currentInvoice,
            customerName: customer.name,
            createdBy: session.user.name || 'admin',
        });
    } catch (error) {
        console.error('Failed to sync real-estate sale accounting for invoice update:', error);
    }

    revalidatePath('/admin/sales');
    revalidatePath('/admin/sales/history');
    revalidatePath('/admin/data/customers');
    
    return { success: true };
}

export async function handleLockInvoice(invoiceId: string) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const invoices = getInvoices();
    const invoice = invoices.find(inv => inv.id === invoiceId);
    if (!invoice) {
        return { error: 'Invoice not found.' };
    }

    // Check if already locked by another user
    if (invoice.lockedBy && invoice.lockedBy !== session.user.id) {
        return {
            error: 'INVOICE_LOCKED',
            lockedBy: invoice.lockedBy,
        };
    }

    const success = lockInvoice(invoiceId, session.user.id);
    if (!success) {
        return { error: 'Failed to lock invoice.' };
    }

    revalidatePath('/admin/sales');
    revalidatePath('/admin/sales/history');
    
    return { success: true };
}

export async function handleUnlockInvoice(invoiceId: string) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const success = unlockInvoice(invoiceId);
    if (!success) {
        return { error: 'Failed to unlock invoice.' };
    }

    revalidatePath('/admin/sales');
    revalidatePath('/admin/sales/history');
    
    return { success: true };
}

export async function handleAcquirePurchaseOrderLock(orderId: string) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const order = getPurchaseOrderById(orderId);
    if (!order) return { error: 'ORDER_NOT_FOUND' };
    if (order.status === 'cancelled') {
        return { error: 'ORDER_CANCELLED' };
    }

    const result = lockPurchaseOrder(orderId, session.user.id, session.user.name || session.user.id);
    if (!result.success) {
        return {
            error: 'PURCHASE_ORDER_LOCKED',
            lockedBy: result.lockedBy || order.lockedByName || order.lockedById || 'مستخدم آخر',
        };
    }

    revalidatePath('/admin/purchases/history');
    revalidatePath(`/admin/purchases/edit/${orderId}`);
    return { success: true };
}

export async function handleReleasePurchaseOrderLock(orderId: string) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const success = unlockPurchaseOrder(orderId, session.user.id);
    if (!success) return { error: 'LOCK_RELEASE_FAILED' };

    revalidatePath('/admin/purchases/history');
    revalidatePath(`/admin/purchases/edit/${orderId}`);
    return { success: true };
}

export async function checkCancelInvoicePermission(): Promise<boolean> {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') {
        return false;
    }

    try {
        const settings = await getSettingsRuntime();
        return hasEmployeePermission(session.user, settings, 'admin.cancel-invoices');
    } catch {
        return false;
    }
}

export async function handleCancelInvoice(invoiceId: string, reason?: string) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') {
        return { error: 'Unauthorized' };
    }

    // Get settings and check for cancel-invoices permission
    const settings = await getSettingsRuntime();
    if (!hasEmployeePermission(session.user, settings, 'admin.cancel-invoices')) {
        return { error: 'You do not have permission to cancel invoices. Only system administrators can cancel invoices.' };
    }

    // Get invoice details before cancellation
    const invoices = getInvoices();
    const invoice = invoices.find(inv => inv.id === invoiceId);
    if (!invoice) {
        return { error: 'Invoice not found.' };
    }

    if (invoice.status !== 'active') {
        return { error: 'Only active invoices can be cancelled.' };
    }

    // Update customer balance (reverse the amount due)
    const allCustomers = await getCustomersRuntime();
    const customer = allCustomers.find(c => c.id === invoice.customerId);
    if (customer) {
        customer.balance -= invoice.amountDue;
        await saveCustomersRuntime(allCustomers);
    }

    // Create reversing journal entry
    try {
        const journalEntries = await getJournalEntriesRuntime();
        const originalEntry = journalEntries.find(je => je.referenceId === invoice.invoiceNumber && je.referenceType === 'sales_invoice');
        
        if (originalEntry) {
            // Create a reversing entry with opposite debit/credit
            const reversingEntry: JournalEntry = {
                id: nextPrefixedId('je-reverse'),
                date: new Date().toISOString(),
                description: `تحويل عكسي لإلغاء الفاتورة ${invoice.invoiceNumber}`,
                referenceType: 'sales_invoice',
                referenceId: invoice.invoiceNumber,
                lines: originalEntry.lines.map(line => ({
                    ...line,
                    debit: line.credit,
                    credit: line.debit,
                })),
                createdBy: session.user.name || 'admin',
                createdAt: new Date().toISOString(),
            };
            
            journalEntries.push(reversingEntry);
            await saveJournalEntriesRuntime(journalEntries);
        }
    } catch (error) {
        console.error('Failed to create reversing journal entry:', error);
        // Continue anyway - invoice cancellation should not fail
    }

    // Cancel invoice
    const success = cancelInvoice(invoiceId, session.user.id, reason);
    if (!success) {
        return { error: 'Failed to cancel invoice.' };
    }

    try {
        await syncRealEstateUnitSaleAccountingEntry({
            invoice: {
                ...invoice,
                status: 'cancelled',
            } as SalesInvoice,
            previousInvoice: invoice,
            customerName: invoice.customerName,
            createdBy: session.user.name || 'admin',
        });
    } catch (error) {
        console.error('Failed to sync real-estate sale accounting for invoice cancellation:', error);
    }

    revalidatePath('/admin/sales');
    revalidatePath('/admin/sales/history');
    revalidatePath('/admin/data/customers');
    
    return { success: true };
}

// ===== PURCHASES =====

// Helper function to get tax rate for an item with priority: item > group > default
function getTaxRateForItem(
  materialId: string,
  itemGroupMap: Map<string, any>,
  defaultTaxRate: number
): number {
  // Try to find material and check for item-level tax
  const materials = getMaterials();
  const material = materials.find((m: any) => m.id === materialId);
  
  if (material?.taxRate !== undefined && material.taxRate > 0) {
    return material.taxRate;
  }
  
  // Check group-level tax
  if (material?.groupId) {
    const group = itemGroupMap.get(material.groupId);
    if (group?.taxRate !== undefined && group.taxRate > 0) {
      return group.taxRate;
    }
  }
  
  // Fall back to default
  return defaultTaxRate;
}

function syncMaterialPricesFromPurchase(
    processedItems: Array<any>,
    taxMethod: 'tax-inclusive' | 'invoice-level' | 'line-level' | 'tax-exempt',
    calculatedTaxAmount: number,
    discountedSubTotal: number,
) {
    try {
        const materialCostAggregation = new Map<string, { totalQty: number; totalCostInclTax: number }>();

        processedItems.forEach((item) => {
            const quantity = Number(item.quantity || 0);
            if (!Number.isFinite(quantity) || quantity <= 0) return;

            const lineNet = Number(item.total || 0);
            if (!Number.isFinite(lineNet) || lineNet < 0) return;

            let lineTax = 0;
            if (taxMethod === 'line-level') {
                lineTax = Number(item.taxAmount || 0);
            } else if (taxMethod === 'invoice-level') {
                lineTax = discountedSubTotal > 0
                    ? (calculatedTaxAmount * (lineNet / discountedSubTotal))
                    : 0;
            }

            const lineGross = lineNet + (Number.isFinite(lineTax) && lineTax > 0 ? lineTax : 0);
            const current = materialCostAggregation.get(item.materialId) || { totalQty: 0, totalCostInclTax: 0 };
            current.totalQty += quantity;
            current.totalCostInclTax += lineGross;
            materialCostAggregation.set(item.materialId, current);
        });

        const materials = getMaterials();
        const materialsById = new Map(materials.map((m) => [m.id, m]));
        const roundTo2 = (value: number) => Math.round(value * 100) / 100;

        materialCostAggregation.forEach((aggregate, materialId) => {
            if (!Number.isFinite(aggregate.totalQty) || aggregate.totalQty <= 0) return;
            const avgUnitCostInclTax = aggregate.totalCostInclTax / aggregate.totalQty;
            if (!Number.isFinite(avgUnitCostInclTax) || avgUnitCostInclTax <= 0) return;

            const material = materialsById.get(materialId);
            const updates: any = { purchasePrice: avgUnitCostInclTax };

            if (material?.enableProfitMargin) {
                const margin = Number(material.profitMargin || 0);
                const nextSalePrice = roundTo2(avgUnitCostInclTax * (1 + ((Number.isFinite(margin) ? margin : 0) / 100)));
                updates.salePrice = Math.max(0.01, nextSalePrice);
            }

            updateMaterial(materialId, updates);
        });
    } catch (error) {
        console.error('Failed to sync material prices from purchase order:', error);
    }
}

const purchaseOrderSchema = z.object({
  supplierId: z.string().min(1),
  supplierName: z.string().min(1),
  supplierInvoiceNumber: z.string().optional().default(''),
  supplierInvoiceDate: z.string().optional().default(''),
    currencyCode: z.string().min(1),
    baseCurrencyCode: z.string().optional(),
    exchangeRate: z.coerce.number().min(0.0001),
    rateDate: z.string().min(1),
    rateSource: z.string().optional(),
    isAutoRate: z.coerce.boolean().optional().default(true),
  warehouseId: z.string().optional(),
  realEstateLinkMode: z.enum(['none', 'order', 'line-items']).optional().default('none'),
  realEstateProjectId: z.string().optional().default(''),
  realEstateProjectName: z.string().optional().default(''),
  realEstateScope: z.enum(['project', 'floor', 'part']).optional().default('project'),
  realEstateFloorLabel: z.string().optional().default(''),
  realEstatePartLabel: z.string().optional().default(''),
  realEstateAllocationMethod: z.enum(['area', 'sale-value', 'manual-share']).optional().default('area'),
  allowDuplicateInvoice: z.coerce.boolean().optional().default(false),
    documents: z.array(z.object({
        id: z.string().min(1),
        name: z.string().min(1),
        filePath: z.string().min(1),
        mimeType: z.string().optional(),
        size: z.coerce.number().min(0).optional(),
        uploadedAt: z.string().min(1),
        uploadedBy: z.string().optional(),
    })).optional().default([]),
  items: z.array(z.object({
    materialId: z.string().min(1),
    name: z.string().min(1),
    quantity: z.coerce.number().min(1),
    unitPrice: z.coerce.number().min(0),
    total: z.coerce.number().min(0),
    lineDiscountPercent: z.coerce.number().min(0).max(100).optional().default(0),
    lineDiscountAmount: z.coerce.number().min(0).optional().default(0),
    lineDiscount: z.coerce.number().min(0).optional().default(0),
    bonus: z.coerce.number().min(0).optional().default(0),
    warehouseId: z.string().optional().default(''),
    shelfId: z.string().optional().default(''),
    taxRate: z.coerce.number().min(0).max(100).optional(), // Tax rate for this line (0-100 %)
    taxAmount: z.coerce.number().min(0).optional(),
    realEstateProjectId: z.string().optional().default(''),
    realEstateProjectName: z.string().optional().default(''),
    realEstateScope: z.enum(['project', 'floor', 'part']).optional(),
    realEstateFloorLabel: z.string().optional().default(''),
    realEstatePartLabel: z.string().optional().default(''),
    realEstateAllocationMethod: z.enum(['area', 'sale-value', 'manual-share']).optional().default('area'),
  })).min(1),
  subTotal: z.coerce.number().min(0),
    invoiceDiscountPercent: z.coerce.number().min(0).max(100).optional().default(0),
    invoiceDiscountAmount: z.coerce.number().min(0).optional().default(0),
        taxMethod: z.enum(['tax-inclusive', 'invoice-level', 'line-level', 'tax-exempt']).optional().default('tax-inclusive'),
    postingType: z.enum(['draft', 'saved', 'posted']).optional().default('posted'),
    purchaseTransferCreationMode: z.enum(['direct_internal_transfer', 'work_task', 'none']).optional(),
  invoiceTaxRate: z.coerce.number().min(0).max(100).optional().default(0), // For invoice-level tax
  taxAmount: z.coerce.number().min(0).optional().default(0), // Total tax amount
  grandTotal: z.coerce.number().min(0),
  amountPaid: z.coerce.number().min(0),
        notes: z.string().optional().default(''),
    paymentMethods: z.array(z.object({
      id: z.string().optional(),
      method: z.enum(['cash', 'check', 'bank_transfer', 'credit']),
            amount: z.coerce.number().min(0),
      currencyCode: z.string().optional(),
      checkSource: z.enum(['issued', 'incoming']).optional(),
      incomingCheckIds: z.array(z.string()).optional(),
      checkNumber: z.string().optional(),
      checkDate: z.string().optional(),
      bankId: z.string().optional(),
      bankName: z.string().optional(),
      reference: z.string().optional(),
    })).optional().default([]),
  amountDue: z.coerce.number().min(0),
});

function getPurchasePostingStatusLabel(status: 'draft' | 'saved' | 'posted') {
    if (status === 'draft') return 'مسودة';
    if (status === 'saved') return 'محفوظ';
    return 'مرحل';
}

function createPurchaseOrderLogEntry(
    action: PurchaseOrderLogEntry['action'],
    message: string,
    by?: string
): PurchaseOrderLogEntry {
    return {
        id: nextPrefixedId('po-log'),
        at: new Date().toISOString(),
        action,
        message,
        by,
    };
}

function buildPurchaseOrderUpdateLogMessage(beforeSnapshot: Record<string, unknown>, afterSnapshot: Record<string, unknown>) {
    const changedFields = Object.keys(afterSnapshot).filter((key) => {
        return JSON.stringify(beforeSnapshot[key]) !== JSON.stringify(afterSnapshot[key]);
    });

    const changedFieldsLabel = changedFields.length > 0
        ? changedFields.join(', ')
        : 'لا توجد فروقات';

    return [
        'تم تحديث الفاتورة بالتفصيل.',
        `عدد الحقول المتغيرة: ${changedFields.length}`,
        `الحقول المتغيرة: ${changedFieldsLabel}`,
        '',
        'قبل التحديث:',
        JSON.stringify(beforeSnapshot, null, 2),
        '',
        'بعد التحديث:',
        JSON.stringify(afterSnapshot, null, 2),
    ].join('\n');
}

const internalTransferSchema = z.object({
        materialId: z.string().min(1),
        quantity: z.coerce.number().min(0.0001),
        fromWarehouseId: z.string().min(1),
        fromShelfId: z.string().min(1),
        toWarehouseId: z.string().min(1),
        toShelfId: z.string().min(1),
        date: z.string().optional(),
        note: z.string().optional(),
}).refine((data) => {
        return !(data.fromWarehouseId === data.toWarehouseId && data.fromShelfId === data.toShelfId);
}, { message: 'Source and destination cannot be the same.' });

const updateInternalTransferSchema = internalTransferSchema;

const transferLockSchema = z.object({
    materialId: z.string().min(1),
});

const internalTransferItemSchema = z.object({
    lineId: z.string().optional(),
    materialId: z.string().min(1),
    quantity: z.coerce.number().min(0.0001),
    receivedQuantity: z.coerce.number().min(0).optional(),
    rejectedQuantity: z.coerce.number().min(0).optional(),
    overReceivedQuantity: z.coerce.number().min(0).optional(),
    overApprovedQuantity: z.coerce.number().min(0).optional(),
    overageStatus: z.enum(['pending', 'approved', 'rejected']).optional(),
    fromWarehouseId: z.string().min(1),
    fromShelfId: z.string().min(1),
    toWarehouseId: z.string().min(1),
    toShelfId: z.string().min(1),
    note: z.string().optional(),
});

const internalTransferDocumentSchema = z.object({
    date: z.string().optional(),
    enableWarehouseTransfer: z.coerce.boolean().default(true),
    enableShelfTransfer: z.coerce.boolean().default(true),
    allowZeroItems: z.coerce.boolean().default(false),
    supplierId: z.string().optional(),
    supplierName: z.string().optional(),
    sourcePurchaseOrderId: z.string().optional(),
    sourcePurchaseOrderNumber: z.string().optional(),
    items: z.array(internalTransferItemSchema).min(1),
    note: z.string().optional(),
});

function normalizeInternalTransferItems(
    items: z.infer<typeof internalTransferItemSchema>[],
    enableWarehouseTransfer: boolean,
    enableShelfTransfer: boolean
) {
    return items.map((item) => ({
        ...item,
        toWarehouseId: enableWarehouseTransfer ? item.toWarehouseId : item.fromWarehouseId,
        toShelfId: enableShelfTransfer ? item.toShelfId : item.fromShelfId,
    }));
}

function ensureLineIds(items: z.infer<typeof internalTransferItemSchema>[]) {
    return items.map((item, index) => ({
        ...item,
        lineId: item.lineId || `${nextPrefixedId('line')}-${index}`,
        receivedQuantity: item.receivedQuantity ?? 0,
    }));
}

function mergeReceivedQuantities(
    items: z.infer<typeof internalTransferItemSchema>[],
    existingItems: z.infer<typeof internalTransferItemSchema>[]
) {
    const existingByLineId = new Map<string, z.infer<typeof internalTransferItemSchema>>();
    existingItems.forEach((item) => {
        if (item.lineId) {
            existingByLineId.set(item.lineId, item);
        }
    });

    return items.map((item, index) => {
        const existing = item.lineId ? existingByLineId.get(item.lineId) : existingItems[index];
        return {
            ...item,
            lineId: item.lineId || existing?.lineId || `${nextPrefixedId('line')}-${index}`,
            receivedQuantity: item.receivedQuantity ?? existing?.receivedQuantity ?? 0,
        };
    });
}

function ensureTransferLocks(materialIds: string[], userId: string, userName: string): { success: boolean; lockedBy?: string } {
    const uniqueIds = Array.from(new Set(materialIds));
    const acquired: string[] = [];

    for (const materialId of uniqueIds) {
        const result = acquireTransferLock(materialId, userId, userName);
        if (!result.success) {
            acquired.forEach((id) => releaseTransferLock(id, userId));
            return { success: false, lockedBy: result.lockedBy };
        }
        acquired.push(materialId);
    }

    return { success: true };
}

export async function handleCreatePurchaseOrder(values: any) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };
    if (!acquireMutationWindow(`create-purchase-order:${session.user.id}`)) {
        return { error: 'REQUEST_DEBOUNCED' };
    }

    const parsed = purchaseOrderSchema.safeParse(values);
    if (!parsed.success) {
        const flattened = parsed.error.flatten();
        const firstIssue = parsed.error.issues[0];
        const validationSummary = firstIssue
            ? `${firstIssue.path.join('.') || 'form'}: ${firstIssue.message}`
            : undefined;
        console.error(flattened);
        return {
            error: 'Invalid data submitted.',
            validationErrors: flattened.fieldErrors,
            formErrors: flattened.formErrors,
            validationSummary,
        };
    }

    // Validate incoming check selection before creating order
    const paymentMethods = Array.isArray(parsed.data.paymentMethods) ? parsed.data.paymentMethods : [];
    const incomingCheckMethod = paymentMethods.find((m: any) => m.method === 'check' && m.checkSource === 'incoming');
    if (incomingCheckMethod?.incomingCheckIds?.length > 0) {
        const checkValidation = await validateIncomingCheckSelection('', incomingCheckMethod.incomingCheckIds);
        if (!checkValidation.valid) {
            return { error: checkValidation.error };
        }
    }

    const command = mapPurchaseCreateDtoToCommand(parsed.data, getDefaultCurrency()?.code || 'USD');
    const purchaseService = PurchaseApplicationService.createDefault();
    const result = await purchaseService.createPurchaseOrder(command, {
        id: session.user.id,
        name: session.user.name || session.user.id,
    });

    if ('error' in result) {
        return result;
    }

    // Reserve checks when PO is created (regardless of posting status)
    if (incomingCheckMethod?.incomingCheckIds?.length > 0) {
        await reserveChecksForPurchaseOrder(
            result.orderId,
            result.orderNumber,
            incomingCheckMethod.incomingCheckIds,
            parsed.data.supplierId,
            parsed.data.supplierName,
            session.user.name || session.user.id
        );
    }

    if (result.revalidateInternalTransfers) {
        revalidatePath('/employee/work-tasks');
        revalidatePath('/admin/data/internal-transfers');
    }

    revalidatePath('/admin/purchases');
    return {
        success: true,
        orderNumber: result.orderNumber,
        stockReport: result.stockReport,
        postingStatus: result.postingStatus,
    };
}

const purchaseOrderUpdateSchema = purchaseOrderSchema.extend({
    id: z.string().min(1),
});

const purchaseReturnItemSchema = z.object({
    materialId: z.string().min(1),
    warehouseId: z.string().optional(),
    shelfId: z.string().optional(),
    quantity: z.number().positive(),
    unitPrice: z.number().nonnegative().optional(),
    priceIncludesTax: z.boolean().optional(),
});

const purchaseReturnSchema = z.object({
    purchaseOrderId: z.string().min(1),
    expectedCurrencyCode: z.string().optional(),
    items: z.array(purchaseReturnItemSchema).min(1),
    reasonCode: z.enum(['normal', 'employee_error', 'natural_loss']).optional(),
    returnMode: z.enum(['physical', 'financial_only']).optional(),
    date: z.string().optional(),
    postNow: z.boolean().optional(),
});

export async function handleUpdatePurchaseOrder(values: any) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };
    if (!acquireMutationWindow(`update-purchase-order:${session.user.id}:${String(values?.id || '')}`)) {
        return { error: 'REQUEST_DEBOUNCED' };
    }

    const parsed = purchaseOrderUpdateSchema.safeParse(values);
    if (!parsed.success) {
        const flattened = parsed.error.flatten();
        const firstIssue = parsed.error.issues[0];
        const validationSummary = firstIssue
            ? `${firstIssue.path.join('.') || 'form'}: ${firstIssue.message}`
            : undefined;
        console.error(flattened);
        return {
            error: 'Invalid data submitted.',
            validationErrors: flattened.fieldErrors,
            formErrors: flattened.formErrors,
            validationSummary,
        };
    }

    const {
        id,
        supplierId,
        supplierName,
        supplierInvoiceNumber,
        supplierInvoiceDate,
        warehouseId,
        realEstateLinkMode,
        realEstateProjectId,
        realEstateProjectName,
        realEstateScope,
        realEstateFloorLabel,
        realEstatePartLabel,
        realEstateAllocationMethod,
        allowDuplicateInvoice,
        documents,
        items,
        taxMethod,
        postingType,
        invoiceTaxRate,
        invoiceDiscountPercent,
        invoiceDiscountAmount,
        amountPaid,
        notes,
        paymentMethods,
        currencyCode,
        baseCurrencyCode,
        exchangeRate,
        rateDate,
        rateSource,
        isAutoRate,
        purchaseTransferCreationMode,
    } = parsed.data;
    const normalizedDocuments: PurchaseOrderDocument[] = (documents || [])
        .map((doc) => ({
            id: String(doc.id || '').trim(),
            name: String(doc.name || '').trim(),
            filePath: String(doc.filePath || '').trim(),
            mimeType: doc.mimeType ? String(doc.mimeType).trim() : undefined,
            size: typeof doc.size === 'number' ? doc.size : undefined,
            uploadedAt: String(doc.uploadedAt || '').trim(),
            uploadedBy: doc.uploadedBy ? String(doc.uploadedBy).trim() : undefined,
        }))
        .filter((doc) => doc.id && doc.name && doc.filePath && doc.uploadedAt);

    const existingOrder = getPurchaseOrderById(id);
    if (!existingOrder) {
        return { error: 'Purchase invoice not found.' };
    }

    if ((existingOrder.postingStatus || 'posted') === 'posted') {
        return { error: 'POSTED_ORDER_EDIT_LOCKED' };
    }

    if (existingOrder.lockedById && existingOrder.lockedById !== session.user.id) {
        return {
            error: 'PURCHASE_ORDER_LOCKED',
            lockedBy: existingOrder.lockedByName || existingOrder.lockedById || 'مستخدم آخر',
        };
    }

    const existingPostingStatus: 'draft' | 'saved' | 'posted' = existingOrder.postingStatus || 'posted';
    const wasPosted = existingPostingStatus === 'posted';
    const nextPostingStatus: 'draft' | 'saved' | 'posted' = postingType === 'posted' ? 'posted' : postingType;
    const willPost = nextPostingStatus === 'posted';

    if (wasPosted && !willPost) {
        return { error: 'POSTED_ORDER_MODE_LOCKED' };
    }

    // --- Calculate taxes based on method ---
    const itemGroups = await getItemGroupsForTaxCalc();
    const itemGroupMap = new Map(itemGroups.map(g => [g.id, g]));

    const settings = await getSettingsRuntime();
    const defaultTaxRate = taxMethod === 'line-level' ? (settings.defaultLineTaxRate || 0) : 0;

    let calculatedTaxAmount = 0;
    let lineDiscountTotal = 0;
    const processedItems = items.map(item => {
        const lineSubtotal = item.quantity * item.unitPrice;
        const percentDiscount = Number(item.lineDiscountPercent || 0);
        const amountDiscount = Number(item.lineDiscountAmount || 0);
        const discountFromPercent = percentDiscount > 0 ? (lineSubtotal * percentDiscount) / 100 : 0;
        const lineDiscount = Math.min(lineSubtotal, discountFromPercent > 0 ? discountFromPercent : amountDiscount);
        const lineTotal = Math.max(0, lineSubtotal - lineDiscount);
        let itemTaxRate = 0;
        let itemTaxAmount = 0;

        if (taxMethod === 'line-level') {
            itemTaxRate = item.taxRate !== undefined && item.taxRate > 0
                ? item.taxRate
                : getTaxRateForItem(item.materialId, itemGroupMap, defaultTaxRate);
            itemTaxAmount = (lineTotal * itemTaxRate) / 100;
            calculatedTaxAmount += itemTaxAmount;
        }

        lineDiscountTotal += lineDiscount;

        const resolvedItemScope = item.realEstateScope || realEstateScope || undefined;
        return {
            materialId: item.materialId,
            name: item.name,
            quantity: item.quantity,
            unitPrice: item.unitPrice,
            total: lineTotal,
            lineDiscountPercent: percentDiscount || undefined,
            lineDiscountAmount: amountDiscount || undefined,
            lineDiscount: lineDiscount > 0 ? lineDiscount : undefined,
            bonus: item.bonus ?? 0,
            warehouseId: (item.warehouseId || '').trim() || undefined,
            shelfId: (item.shelfId || '').trim() || undefined,
            taxRate: itemTaxRate || undefined,
            taxAmount: itemTaxAmount > 0 ? itemTaxAmount : undefined,
            realEstateProjectId: String(item.realEstateProjectId || realEstateProjectId || '').trim() || undefined,
            realEstateProjectName: String(item.realEstateProjectName || realEstateProjectName || '').trim() || undefined,
            realEstateScope: resolvedItemScope,
            realEstateFloorLabel: String(item.realEstateFloorLabel || realEstateFloorLabel || '').trim() || undefined,
            realEstatePartLabel: String(item.realEstatePartLabel || realEstatePartLabel || '').trim() || undefined,
            realEstateAllocationMethod: resolvedItemScope === 'project'
                ? ((item.realEstateAllocationMethod || realEstateAllocationMethod || 'area') as 'area' | 'sale-value' | 'manual-share')
                : undefined,
        };
    });

    const subTotal = processedItems.reduce((sum, item) => sum + (item.total || 0), 0);
    const invoiceDiscountPercentValue = Number(invoiceDiscountPercent || 0);
    const invoiceDiscountFromPercent = invoiceDiscountPercentValue > 0
        ? (subTotal * invoiceDiscountPercentValue) / 100
        : 0;
    const invoiceDiscount = Math.min(
        subTotal,
        invoiceDiscountFromPercent > 0 ? invoiceDiscountFromPercent : Number(invoiceDiscountAmount || 0)
    );
    const discountedSubTotal = Math.max(0, subTotal - invoiceDiscount);
    const totalDiscount = lineDiscountTotal + invoiceDiscount;

    if (taxMethod === 'invoice-level') {
        calculatedTaxAmount = (discountedSubTotal * invoiceTaxRate) / 100;
    }
    if (taxMethod === 'tax-inclusive' || taxMethod === 'tax-exempt') {
        calculatedTaxAmount = 0;
    }

    // --- Get suppliers and ensure supplier exists ---
    const { getInvoicesPurchase, updatePurchaseOrder, getShipments, createShipment, addInventoryMovements } = await import('./data');
    const suppliers = await getSuppliersRuntime();
    let supplier = suppliers.find(s => s.id === supplierId);

    if (!supplier) {
        const customers = await getCustomersRuntime();
        const customerMatch = customers.find((c) => c.id === supplierId);
        if (customerMatch) {
            supplier = {
                id: supplierId,
                supplierNumber: customerMatch.customerNumber || supplierId,
                name: customerMatch.name,
                balance: 0,
                phone: customerMatch.phone || '',
                address: customerMatch.address || '',
                paymentTerms: 30,
                taxNumber: '',
            };
            suppliers.push(supplier);
            await saveSuppliersRuntime(suppliers);
        }
    }

    if (!supplier) return { error: 'Supplier not found.' };

    // Duplicate invoice check (excluding this order)
    const normalizedInvoice = String(supplierInvoiceNumber || '').trim().toLowerCase();
    if (normalizedInvoice) {
        const existingOrders = await getPurchaseOrdersRuntime();
        const duplicate = existingOrders.find(
            (order) =>
                order.id !== id &&
                order.supplierId === supplierId &&
                String(order.supplierInvoiceNumber || '').trim().toLowerCase() === normalizedInvoice
        );
        if (duplicate && !allowDuplicateInvoice) {
            return {
                error: 'DUPLICATE_SUPPLIER_INVOICE',
                existing: {
                    orderNumber: duplicate.orderNumber,
                    date: duplicate.date,
                    grandTotal: duplicate.grandTotal,
                    amountDue: duplicate.amountDue,
                },
            };
        }
    }

    const normalizedBaseCurrency = existingOrder.baseCurrencyCode || baseCurrencyCode || getDefaultCurrency()?.code || 'USD';
    const normalizedCurrency = existingOrder.currencyCode || currencyCode || normalizedBaseCurrency;
    const normalizedExchangeRate = existingOrder.exchangeRate || (normalizedCurrency === normalizedBaseCurrency ? 1 : exchangeRate);

    const finalGrandTotal = discountedSubTotal + calculatedTaxAmount;
    const finalAmountDue = Math.max(0, finalGrandTotal - amountPaid);

    // --- Validate multiple payment methods ---
    const paymentMethodsInput = paymentMethods;
    const paymentMethodsList = Array.isArray(paymentMethodsInput) ? paymentMethodsInput : [];

    const totalPaymentMethods = paymentMethodsList.reduce((sum, method) => sum + (Number(method.amount) || 0), 0);
    const epsilon = 0.01;
    if (Math.abs(totalPaymentMethods - amountPaid) > epsilon) {
        return { error: 'Total payment methods must equal the amount paid.' };
    }

    const incomingChecks = await getIncomingChecksRuntime();
    for (const method of paymentMethodsList) {
        if (method.method === 'check' && method.checkSource === 'incoming' && Number(method.amount || 0) > 0) {
            const selectedIncomingCheckIds = Array.isArray(method.incomingCheckIds) ? method.incomingCheckIds : [];
            if (selectedIncomingCheckIds.length === 0) {
                return { error: 'At least one incoming check must be selected for incoming check payment methods.' };
            }

            const selectedIncomingChecks = incomingChecks.filter((entry) => selectedIncomingCheckIds.includes(entry.id));
            if (selectedIncomingChecks.length !== selectedIncomingCheckIds.length) {
                return { error: 'One or more selected incoming checks were not found.' };
            }

            const blockedCheck = selectedIncomingChecks.find((entry) => entry.status !== 'pending' || (entry.endorsementStatus && entry.endorsementStatus !== 'none'));
            if (blockedCheck) {
                return { error: `Incoming check ${blockedCheck.checkNumber} is not available for payment.` };
            }

            const totalIncomingInOrderCurrency = selectedIncomingChecks.reduce((sum, entry) => {
                const checkCurrency = entry.currency || normalizedBaseCurrency;
                const checkAmount = Number(entry.amount || 0);
                if (checkCurrency === normalizedCurrency) return sum + checkAmount;
                return sum + convertCurrency(checkAmount, checkCurrency, normalizedCurrency);
            }, 0);

            if (Math.abs(totalIncomingInOrderCurrency - (Number(method.amount) || 0)) > epsilon) {
                return { error: `For method ${method.method} with source ${method.checkSource}, total selected checks must equal the method amount.` };
            }
        }
    }

    const fxRate = normalizedExchangeRate || 1;
    const netPurchasesBase = discountedSubTotal * fxRate;
    const taxAmountBase = calculatedTaxAmount * fxRate;
    const grandTotalBase = finalGrandTotal * fxRate;
    const amountPaidBase = amountPaid * fxRate;
    const amountDueBase = finalAmountDue * fxRate;

    if (willPost) {
        if (wasPosted) {
            const oldAmountDueBase = existingOrder.amountDueBase ?? existingOrder.amountDue ?? 0;
            if (existingOrder.supplierId === supplierId) {
                supplier.balance += amountDueBase - oldAmountDueBase;
            } else {
                const oldSupplier = suppliers.find((s) => s.id === existingOrder.supplierId);
                if (oldSupplier) {
                    oldSupplier.balance -= oldAmountDueBase;
                }
                supplier.balance += amountDueBase;
            }
        } else {
            supplier.balance += amountDueBase;
        }
        await saveSuppliersRuntime(suppliers);
    }

    const previousNotes = String(existingOrder.notes || '').trim();
    const nextNotes = String(notes || '').trim();

    const beforeSnapshot = {
        supplierId: existingOrder.supplierId,
        supplierName: existingOrder.supplierName,
        supplierInvoiceNumber: existingOrder.supplierInvoiceNumber || '',
        supplierInvoiceDate: existingOrder.supplierInvoiceDate || '',
        warehouseId: existingOrder.warehouseId || '',
        realEstateLinkMode: existingOrder.realEstateLinkMode || 'none',
        realEstateProjectId: existingOrder.realEstateProjectId || '',
        realEstateProjectName: existingOrder.realEstateProjectName || '',
        realEstateScope: existingOrder.realEstateScope || 'project',
        realEstateFloorLabel: existingOrder.realEstateFloorLabel || '',
        realEstatePartLabel: existingOrder.realEstatePartLabel || '',
        realEstateAllocationMethod: existingOrder.realEstateAllocationMethod || 'area',
        currencyCode: existingOrder.currencyCode || '',
        baseCurrencyCode: existingOrder.baseCurrencyCode || '',
        exchangeRate: Number(existingOrder.exchangeRate || 1),
        rateDate: existingOrder.rateDate || '',
        rateSource: existingOrder.rateSource || '',
        isAutoRate: existingOrder.isAutoRate ?? true,
        taxMethod: existingOrder.taxMethod || 'tax-inclusive',
        invoiceDiscountPercent: Number(existingOrder.invoiceDiscountPercent || 0),
        invoiceDiscountAmount: Number(existingOrder.invoiceDiscountAmount || 0),
        taxAmount: Number(existingOrder.taxAmount || 0),
        subTotal: Number(existingOrder.subTotal || 0),
        grandTotal: Number(existingOrder.grandTotal || 0),
        amountPaid: Number(existingOrder.amountPaid || 0),
        amountDue: Number(existingOrder.amountDue || 0),
        postingStatus: existingPostingStatus,
        notes: previousNotes,
        items: (existingOrder.items || []).map((item) => ({
            materialId: item.materialId,
            name: item.name,
            quantity: Number(item.quantity || 0),
            unitPrice: Number(item.unitPrice || 0),
            total: Number(item.total || 0),
            lineDiscountPercent: Number(item.lineDiscountPercent || 0),
            lineDiscountAmount: Number(item.lineDiscountAmount || 0),
            bonus: Number(item.bonus || 0),
            warehouseId: item.warehouseId || '',
            shelfId: item.shelfId || '',
            taxRate: Number(item.taxRate || 0),
            taxAmount: Number(item.taxAmount || 0),
            realEstateProjectId: item.realEstateProjectId || '',
            realEstateProjectName: item.realEstateProjectName || '',
            realEstateScope: item.realEstateScope || 'project',
            realEstateFloorLabel: item.realEstateFloorLabel || '',
            realEstatePartLabel: item.realEstatePartLabel || '',
            realEstateAllocationMethod: item.realEstateAllocationMethod || 'area',
        })),
        paymentMethods: (existingOrder.paymentMethods || []).map((method) => ({
            method: method.method,
            amount: Number(method.amount || 0),
            currencyCode: method.currencyCode || '',
            checkSource: method.checkSource || '',
            incomingCheckIds: Array.isArray(method.incomingCheckIds) ? method.incomingCheckIds : [],
            checkNumber: method.checkNumber || '',
            checkDate: method.checkDate || '',
            bankId: method.bankId || '',
            bankName: method.bankName || '',
            reference: method.reference || '',
        })),
        documents: (existingOrder.documents || []).map((doc) => ({
            id: doc.id,
            name: doc.name,
            filePath: doc.filePath,
            mimeType: doc.mimeType || '',
            size: Number(doc.size || 0),
            uploadedAt: doc.uploadedAt,
            uploadedBy: doc.uploadedBy || '',
        })),
    };

    const afterSnapshot = {
        supplierId,
        supplierName,
        supplierInvoiceNumber: supplierInvoiceNumber || '',
        supplierInvoiceDate: supplierInvoiceDate || '',
        warehouseId: warehouseId || existingOrder.warehouseId || '',
        realEstateLinkMode: realEstateLinkMode || 'none',
        realEstateProjectId: String(realEstateProjectId || '').trim(),
        realEstateProjectName: String(realEstateProjectName || '').trim(),
        realEstateScope: realEstateScope || 'project',
        realEstateFloorLabel: String(realEstateFloorLabel || '').trim(),
        realEstatePartLabel: String(realEstatePartLabel || '').trim(),
        realEstateAllocationMethod: realEstateAllocationMethod || 'area',
        currencyCode: normalizedCurrency,
        baseCurrencyCode: normalizedBaseCurrency,
        exchangeRate: Number(normalizedExchangeRate || 1),
        rateDate: existingOrder.rateDate || rateDate || '',
        rateSource: existingOrder.rateSource || rateSource || '',
        isAutoRate: existingOrder.isAutoRate ?? isAutoRate ?? true,
        taxMethod,
        invoiceDiscountPercent: invoiceDiscountPercentValue,
        invoiceDiscountAmount: invoiceDiscount > 0 ? invoiceDiscount : 0,
        taxAmount: calculatedTaxAmount,
        subTotal,
        grandTotal: finalGrandTotal,
        amountPaid,
        amountDue: finalAmountDue,
        postingStatus: nextPostingStatus,
        notes: nextNotes,
        items: processedItems.map((item) => ({
            materialId: item.materialId,
            name: item.name,
            quantity: Number(item.quantity || 0),
            unitPrice: Number(item.unitPrice || 0),
            total: Number(item.total || 0),
            lineDiscountPercent: Number(item.lineDiscountPercent || 0),
            lineDiscountAmount: Number(item.lineDiscountAmount || 0),
            bonus: Number(item.bonus || 0),
            warehouseId: item.warehouseId || '',
            shelfId: item.shelfId || '',
            taxRate: Number(item.taxRate || 0),
            taxAmount: Number(item.taxAmount || 0),
            realEstateProjectId: item.realEstateProjectId || '',
            realEstateProjectName: item.realEstateProjectName || '',
            realEstateScope: item.realEstateScope || 'project',
            realEstateFloorLabel: item.realEstateFloorLabel || '',
            realEstatePartLabel: item.realEstatePartLabel || '',
            realEstateAllocationMethod: item.realEstateAllocationMethod || 'area',
        })),
        paymentMethods: paymentMethodsList.map((method) => ({
            method: method.method,
            amount: Number(method.amount || 0),
            currencyCode: method.currencyCode || normalizedCurrency,
            checkSource: method.checkSource || '',
            incomingCheckIds: Array.isArray(method.incomingCheckIds) ? method.incomingCheckIds : [],
            checkNumber: method.checkNumber || '',
            checkDate: method.checkDate || '',
            bankId: method.bankId || '',
            bankName: method.bankName || '',
            reference: method.reference || '',
        })),
        documents: normalizedDocuments.map((doc) => ({
            id: doc.id,
            name: doc.name,
            filePath: doc.filePath,
            mimeType: doc.mimeType || '',
            size: Number(doc.size || 0),
            uploadedAt: doc.uploadedAt,
            uploadedBy: doc.uploadedBy || '',
        })),
    };

    const detailedUpdateMessage = buildPurchaseOrderUpdateLogMessage(beforeSnapshot, afterSnapshot);

    const previousLogs = Array.isArray(existingOrder.activityLog) ? existingOrder.activityLog : [];
    const updateLogs: PurchaseOrderLogEntry[] = [
        createPurchaseOrderLogEntry(
            'updated',
            detailedUpdateMessage,
            session.user.name || session.user.id
        ),
    ];

    if (existingPostingStatus !== nextPostingStatus) {
        updateLogs.push(
            createPurchaseOrderLogEntry(
                'posting-status',
                `تم تغيير حالة الفاتورة من ${getPurchasePostingStatusLabel(existingPostingStatus)} إلى ${getPurchasePostingStatusLabel(nextPostingStatus)}.`,
                session.user.name || session.user.id
            )
        );
    }

    if (previousNotes !== nextNotes) {
        updateLogs.push(
            createPurchaseOrderLogEntry(
                'notes',
                nextNotes ? 'تم تحديث الملاحظات.' : 'تم حذف الملاحظات.',
                session.user.name || session.user.id
            )
        );
    }

    assertNotLockedByPeriod(new Date().toISOString(), settings.periodCloseDate, settings.inventoryCloseDate);

    // --- Handle check reservation state transitions ---
    // Release old check reservations if payment methods changed
    const oldPaymentMethods = Array.isArray(existingOrder.paymentMethods) ? existingOrder.paymentMethods : [];
    const oldIncomingCheckMethod = oldPaymentMethods.find((m: any) => m.method === 'check' && m.checkSource === 'incoming');
    const oldIncomingCheckIds = oldIncomingCheckMethod?.incomingCheckIds || [];
    const newPaymentMethods = Array.isArray(paymentMethods) ? paymentMethods : [];
    const newIncomingCheckMethod = newPaymentMethods.find((m: any) => m.method === 'check' && m.checkSource === 'incoming');
    const newIncomingCheckIds = newIncomingCheckMethod?.incomingCheckIds || [];

    // Release checks that are no longer in the new selection
    const checksToRelease = oldIncomingCheckIds.filter((cid: string) => !newIncomingCheckIds.includes(cid));
    if (checksToRelease.length > 0) {
        const allChecks = await getIncomingChecksRuntime();
        const checksToUpdateRelease = allChecks
            .filter((c: any) => checksToRelease.includes(c.id) && c.reservedByPurchaseOrderId === id)
            .map((c: any) => ({
                ...c,
                reservationStatus: 'available' as const,
                reservedAt: undefined,
                reservedByPurchaseOrderId: undefined,
                updatedAt: new Date().toISOString(),
            }));
        if (checksToUpdateRelease.length > 0) {
            if (isPostgresProviderEnabled()) {
                const { pgSaveChecksReceived } = await import('./postgres/data-access');
                await pgSaveChecksReceived(checksToUpdateRelease);
            } else {
                const { saveIncomingChecks } = await import('./data');
                saveIncomingChecks(checksToUpdateRelease);
            }
        }
    }

    // Validate and reserve new checks
    const checksToAdd = newIncomingCheckIds.filter((cid: string) => !oldIncomingCheckIds.includes(cid));
    if (checksToAdd.length > 0) {
        const checkValidation = await validateIncomingCheckSelection(id, checksToAdd);
        if (!checkValidation.valid) {
            return { error: checkValidation.error };
        }
        await reserveChecksForPurchaseOrder(
            id,
            existingOrder.orderNumber,
            checksToAdd,
            supplierId,
            supplierName,
            session.user.name || session.user.id
        );
    }

    let reconcileResult: { movements: InventoryMovement[]; shipmentId?: string } = { movements: [], shipmentId: undefined };
    if (willPost && wasPosted) {
        try {
            // reconcilePurchaseOrderInventory computes diffs and (in JSON mode) persists them.
            // In Postgres mode, writeData is guarded for these files, so the JSON writes are no-ops.
            reconcileResult = reconcilePurchaseOrderInventory(existingOrder.items || [], processedItems, {
                orderId: existingOrder.id,
                date: new Date().toISOString(),
                periodCloseDate: settings.periodCloseDate,
                inventoryCloseDate: settings.inventoryCloseDate,
            });

            // In Postgres mode, persist the reconcile shipment + movements to Postgres explicitly.
            if (isPostgresProviderEnabled() && reconcileResult.movements.length) {
                const adjustShipment = await createShipmentRuntime({
                    shipmentType: 'adjustment',
                    date: new Date().toISOString(),
                    invoiceId: existingOrder.id,
                    hasInventoryMovement: true,
                    periodCloseDate: settings.periodCloseDate,
                    inventoryCloseDate: settings.inventoryCloseDate,
                });
                const pgReconcileMoves = reconcileResult.movements.map((m) => ({
                    ...m,
                    shipmentId: adjustShipment.id,
                }));
                await pgSaveInventoryMovements(pgReconcileMoves as Array<Record<string, unknown>>);
                reconcileResult = { movements: pgReconcileMoves, shipmentId: adjustShipment.id };
            }
        } catch (error: any) {
            return { error: error?.message || 'INVENTORY_RECONCILE_FAILED' };
        }
    }

    updatePurchaseOrder(id, {
        supplierId,
        supplierName,
        notes: nextNotes || undefined,
        activityLog: [...updateLogs, ...previousLogs],
        documents: normalizedDocuments,
        supplierInvoiceNumber: supplierInvoiceNumber || undefined,
        supplierInvoiceDate: supplierInvoiceDate || undefined,
        warehouseId: warehouseId || existingOrder.warehouseId,
        realEstateLinkMode: realEstateLinkMode || 'none',
        realEstateProjectId: String(realEstateProjectId || '').trim() || undefined,
        realEstateProjectName: String(realEstateProjectName || '').trim() || undefined,
        realEstateScope: realEstateScope || 'project',
        realEstateFloorLabel: String(realEstateFloorLabel || '').trim() || undefined,
        realEstatePartLabel: String(realEstatePartLabel || '').trim() || undefined,
        realEstateAllocationMethod: realEstateAllocationMethod || 'area',
        items: processedItems,
        subTotal,
        invoiceDiscountPercent: invoiceDiscountPercentValue || undefined,
        invoiceDiscountAmount: invoiceDiscount > 0 ? invoiceDiscount : undefined,
        lineDiscountTotal: lineDiscountTotal > 0 ? lineDiscountTotal : undefined,
        totalDiscount: totalDiscount > 0 ? totalDiscount : undefined,
        taxMethod,
        taxAmount: calculatedTaxAmount,
        grandTotal: finalGrandTotal,
        amountPaid,
        paymentMethods: paymentMethodsList.map((m) => ({
            id: String((m as any).id || nextPrefixedId('pom')),
            method: m.method,
            amount: Number(m.amount) || 0,
            currencyCode: m.currencyCode || normalizedCurrency,
            checkSource: m.method === 'check' ? (m.checkSource || undefined) : undefined,
            incomingCheckIds: m.method === 'check' && m.checkSource === 'incoming' ? (Array.isArray(m.incomingCheckIds) ? m.incomingCheckIds : []) : [],
            checkNumber: m.method === 'check' && m.checkSource === 'issued' ? (m.checkNumber || undefined) : undefined,
            checkDate: m.method === 'check' && m.checkSource === 'issued' ? (m.checkDate || undefined) : undefined,
            bankId: m.bankId || undefined,
            bankName: m.bankName || undefined,
            reference: m.reference || undefined,
        })),
        amountDue: finalAmountDue,
        postingStatus: nextPostingStatus,
        purchaseTransferCreationMode,
        currencyCode: normalizedCurrency,
        baseCurrencyCode: normalizedBaseCurrency,
        exchangeRate: normalizedExchangeRate || 1,
        rateDate: existingOrder.rateDate || rateDate || new Date().toISOString(),
        rateSource: existingOrder.rateSource || rateSource || 'manual',
        isAutoRate: existingOrder.isAutoRate ?? isAutoRate ?? true,
        grandTotalBase,
        amountPaidBase,
        amountDueBase,
    });

    if (willPost && !wasPosted) {
        for (const method of paymentMethodsList) {
            if (method.method === 'check' && method.checkSource === 'incoming' && Number(method.amount || 0) > 0) {
                const selectedIncomingCheckIds = Array.isArray(method.incomingCheckIds) ? method.incomingCheckIds : [];
                for (const checkId of selectedIncomingCheckIds) {
                    const done = endorseIncomingCheck(
                        checkId,
                        'endorsed-to-party',
                        supplierId,
                        supplierName,
                        'supplier',
                        `Purchase Invoice #${existingOrder.orderNumber}`
                    );
                    if (!done) {
                        return { error: 'Failed to endorse incoming check to supplier.' };
                    }
                }
            }
        }
    }

    let linkedShipment: { id: string; shipmentType: ShipmentType } | null = null;
    if (willPost) {
        try {
            const shipments = await getShipmentsRuntime();
            linkedShipment = shipments.find((s) => s.invoiceId === existingOrder.id && s.shipmentType === 'internal') || null;
            if (!linkedShipment) {
                linkedShipment = await createShipmentRuntime({
                    shipmentType: 'internal',
                    date: new Date().toISOString(),
                    invoiceId: existingOrder.id,
                    hasInventoryMovement: true,
                    periodCloseDate: settings.periodCloseDate,
                    inventoryCloseDate: settings.inventoryCloseDate,
                });
            }
        } catch (error) {
            console.error('Failed to ensure linked shipment for purchase order update:', error);
        }

        if (!wasPosted) {
            try {
                const movEntries = processedItems.map((item) => ({
                    date: new Date().toISOString(),
                    materialId: item.materialId,
                    warehouseId: item.warehouseId || '',
                    shelfId: item.shelfId || '',
                    quantityIn: item.quantity,
                    quantityOut: 0,
                    referenceType: 'purchase_order',
                    referenceId: existingOrder.id,
                    shipmentId: linkedShipment?.id,
                    invoiceId: existingOrder.id,
                }));
                if (isPostgresProviderEnabled()) {
                    const pgMovs = movEntries.map((e) => ({ ...e, id: `${e.referenceType}-${Date.now()}-${Math.random().toString(36).slice(2,7)}` }));
                    await pgSaveInventoryMovements(pgMovs as Array<Record<string, unknown>>);
                } else {
                    addInventoryMovements(movEntries);
                }
            } catch (error) {
                console.error('Failed to record inventory movements for PO update post:', error);
            }

            try {
                const purchaseSideEffects = createDefaultPurchaseSideEffectsPort();
                await purchaseSideEffects.createShelfDistributionTask({
                    order: { id: existingOrder.id, orderNumber: existingOrder.orderNumber },
                    items: processedItems,
                    supplierId,
                    supplierName,
                    warehouseId: warehouseId || existingOrder.warehouseId,
                    settings,
                    createdBy: session.user.name || session.user.id,
                    transferCreationMode: purchaseTransferCreationMode,
                });
            } catch (error) {
                console.error('Failed to create shelf distribution task for PO update:', error);
            }
        }

        try {
            await createPurchaseOrderJournalEntry(
                existingOrder.orderNumber,
                supplierId,
                supplierName,
                netPurchasesBase,
                taxAmountBase,
                totalDiscount * fxRate,
                amountPaidBase,
                session.user.name || 'admin',
                {
                    invoiceId: existingOrder.id,
                    shipmentId: linkedShipment?.id,
                    shipmentType: linkedShipment?.shipmentType,
                    paymentMethods: paymentMethodsList,
                    fxRate,
                }
            );

            if (reconcileResult.movements.length) {
                const periodLocked = !!settings.periodCloseDate && reconcileResult.movements.some((mv) => {
                    if (!mv.date) return false;
                    return new Date(mv.date) <= new Date(settings.periodCloseDate);
                });
                generateJournalForInventoryAdjustment(reconcileResult.movements, {
                    shipmentType: 'adjustment',
                    invoiceType: 'purchase',
                    supplierId,
                    periodLocked,
                });
            }
        } catch (error) {
            console.error('Failed to create journal entry for update:', error);
        }
    }

    if (nextPostingStatus !== 'draft') {
        syncMaterialPricesFromPurchase(processedItems, taxMethod, calculatedTaxAmount, discountedSubTotal);
    }

    // --- Endorse reserved checks when advancing to posted ---
    if (willPost && !wasPosted) {
        const incomingCheckMethod = newPaymentMethods.find((m: any) => m.method === 'check' && m.checkSource === 'incoming');
        if (incomingCheckMethod?.incomingCheckIds?.length > 0) {
            await endorseReservedChecks(
                id,
                existingOrder.orderNumber,
                supplierId,
                supplierName,
                session.user.name || session.user.id
            );
        }
    }

    revalidatePath('/admin/purchases');
    revalidatePath('/admin/purchases/history');
    return { success: true, orderNumber: existingOrder.orderNumber, postingStatus: nextPostingStatus };
}

export async function handleCancelPurchaseOrder(orderId: string, reason?: string) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') {
        return { error: 'Unauthorized' };
    }

    const allOrders = await getPurchaseOrdersRuntime();
    const order = allOrders.find((entry) => String(entry?.id || '').trim() === String(orderId || '').trim());
    if (!order) return { error: 'ORDER_NOT_FOUND' };
    if (order.status === 'cancelled') return { success: true, alreadyCancelled: true };
    if (order.status !== 'active') return { error: 'ORDER_NOT_ACTIVE' };

    const transferDocs = getInternalTransferDocuments().filter(
        (doc) => doc.status === 'active' && doc.sourcePurchaseOrderId === orderId
    );
    if (transferDocs.length > 0) {
        return { error: 'ORDER_HAS_TRANSFER_DOCS' };
    }

    const hasSupplierPayments = getSupplierPayments().some((payment) =>
        (payment.allocations || []).some((allocation) => allocation.purchaseOrderId === orderId && Number(allocation.amount || 0) > 0)
    );
    if (hasSupplierPayments) {
        return { error: 'ORDER_HAS_SUPPLIER_PAYMENTS' };
    }

    const activeReturns = getPurchaseReturnsByOrder(orderId).filter((ret) => ret.status !== 'cancelled');
    if (activeReturns.length > 0) {
        return { error: 'ORDER_HAS_PURCHASE_RETURNS' };
    }

    const allMovements = await getInventoryMovementsRuntime();
    const hasOtherInventoryMovements = allMovements.some(
        (movement: any) => movement.invoiceId === orderId && movement.referenceType !== 'purchase_order'
    );
    if (hasOtherInventoryMovements) {
        return { error: 'ORDER_HAS_OTHER_MOVEMENTS' };
    }

    const hasOtherJournalEntries = (await getJournalEntriesRuntime()).some(
        (entry) => entry.referenceId === orderId && entry.referenceType !== 'purchase_order'
    );
    if (hasOtherJournalEntries) {
        return { error: 'ORDER_HAS_OTHER_MOVEMENTS' };
    }

    const isPosted = (order.postingStatus || 'posted') === 'posted';
    const settings = await getSettingsRuntime();
    
    // Check for cancel-invoices permission
    if (!hasEmployeePermission(session.user, settings, 'admin.cancel-invoices')) {
        return { error: 'You do not have permission to cancel invoices. Only system administrators can cancel invoices.' };
    }
    
    const now = new Date().toISOString();

    if (isPosted) {
        try {
            assertNotLockedByPeriod(now, settings.periodCloseDate, settings.inventoryCloseDate);
        } catch (error: any) {
            return { error: error?.message || 'LOCKED' };
        }

        const reverseDate = new Date().toISOString();
        const reverseShipment = await createShipmentRuntime({
            shipmentType: 'reverse',
            date: reverseDate,
            invoiceId: order.id,
            hasInventoryMovement: true,
            periodCloseDate: settings.periodCloseDate,
            inventoryCloseDate: settings.inventoryCloseDate,
        });

        const reverseEntries = order.items
            .map((item) => {
                const quantity = Number(item.quantity || 0);
                if (quantity <= 0) return null;
                const warehouseId = (item.warehouseId || order.warehouseId || '').trim();
                const shelfId = (item.shelfId || '').trim();

                assertReverseQuantity(item.materialId, warehouseId, shelfId, quantity);

                return {
                    date: reverseDate,
                    materialId: item.materialId,
                    warehouseId,
                    shelfId,
                    quantityIn: 0,
                    quantityOut: quantity,
                    referenceType: 'purchase_order_cancel',
                    referenceId: order.id,
                    shipmentId: reverseShipment.id,
                    invoiceId: order.id,
                    costPerUnitOriginal: Number(item.unitPrice || 0),
                };
            })
            .filter(Boolean) as Array<Omit<InventoryMovement, 'id'>>;

        if (reverseEntries.length > 0) {
            try {
                if (isPostgresProviderEnabled()) {
                    const pgRevMovs = reverseEntries.map((e) => ({ ...e, id: `${e.referenceType}-${Date.now()}-${Math.random().toString(36).slice(2,7)}` }));
                    await pgSaveInventoryMovements(pgRevMovs as Array<Record<string, unknown>>);
                } else {
                    addInventoryMovements(reverseEntries);
                }
            } catch (error: any) {
                return { error: error?.message || 'INVENTORY_REVERSE_FAILED' };
            }
        }

        try {
            const journalEntries = await getJournalEntriesRuntime();
            const originalEntry = journalEntries
                .filter(
                    (entry) =>
                        entry.referenceType === 'purchase_order' &&
                        (
                            entry.invoiceId === order.id ||
                            entry.referenceId === order.id ||
                            entry.referenceId === order.orderNumber
                        )
                )
                .sort((a, b) => new Date(b.createdAt || b.date).getTime() - new Date(a.createdAt || a.date).getTime())[0];

            if (originalEntry) {
                const reversingEntry: JournalEntry = {
                    id: nextPrefixedId('je-reverse'),
                    date: reverseDate,
                    description: `قيد عكسي لإلغاء فاتورة الشراء ${order.orderNumber}`,
                    referenceType: 'purchase_order',
                    referenceId: order.orderNumber,
                    invoiceId: order.id,
                    shipmentId: reverseShipment.id,
                    shipmentType: reverseShipment.shipmentType,
                    lines: originalEntry.lines.map((line) => ({
                        ...line,
                        debit: line.credit,
                        credit: line.debit,
                    })),
                    createdBy: session.user.name || 'admin',
                    createdAt: reverseDate,
                };

                journalEntries.push(reversingEntry);
                await saveJournalEntriesRuntime(journalEntries);
            }
        } catch (error) {
            console.error('Failed to create reversing purchase journal:', error);
        }

        try {
            const suppliers = await getSuppliersRuntime();
            const supplier = suppliers.find((s) => s.id === order.supplierId);
            if (supplier) {
                const amountDueBase = Number(order.amountDueBase ?? order.amountDue ?? 0);
                supplier.balance -= amountDueBase;
                await saveSuppliersRuntime(suppliers);
            }
        } catch (error) {
            console.error('Failed to reverse supplier balance on purchase cancellation:', error);
        }
    }

    // --- Release only reserved checks on cancellation (NOT endorsed checks) ---
    // Endorsed checks remain endorsed as they represent a financial commitment already made
    const allChecks = await getIncomingChecksRuntime();
    const checksToReleaseOnCancel = allChecks
        .filter((c: any) => c.reservedByPurchaseOrderId === orderId && c.reservationStatus === 'reserved')
        .map((c: any) => ({
            ...c,
            reservationStatus: 'available' as const,
            reservedAt: undefined,
            reservedByPurchaseOrderId: undefined,
            updatedAt: new Date().toISOString(),
        }));
    if (checksToReleaseOnCancel.length > 0) {
        if (isPostgresProviderEnabled()) {
            const { pgSaveChecksReceived } = await import('./postgres/data-access');
            await pgSaveChecksReceived(checksToReleaseOnCancel);
        } else {
            const { saveIncomingChecks } = await import('./data');
            saveIncomingChecks(checksToReleaseOnCancel);
        }
    }

    if (isPostgresProviderEnabled()) {
        const cancelledAt = new Date().toISOString();
        await pgSavePurchaseOrders([
            {
                ...order,
                status: 'cancelled',
                cancelledAt,
                cancelledBy: session.user.id,
                cancelledReason: reason,
            } as Record<string, unknown>,
        ]);
    } else {
        const success = cancelPurchaseOrder(orderId, session.user.id, reason);
        if (!success) return { error: 'CANCEL_FAILED' };
    }

    revalidatePath('/admin/purchases');
    revalidatePath('/admin/purchases/history');
    revalidatePath(`/admin/purchases/view/${orderId}`);
    revalidatePath('/admin/purchases/statement');
    revalidatePath('/admin/purchases/balances');
    revalidatePath('/admin/accounting/entries');

    return { success: true };
}

export async function handleRestorePurchaseOrder(orderId: string) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const sourceOrder = getPurchaseOrderById(orderId);
    if (!sourceOrder) return { error: 'ORDER_NOT_FOUND' };
    if (sourceOrder.status !== 'cancelled') return { error: 'ORDER_NOT_CANCELLED' };

    const now = new Date().toISOString();
    const baseCode = sourceOrder.baseCurrencyCode || getDefaultCurrency()?.code || 'USD';
    const currencyCode = sourceOrder.currencyCode || baseCode;
    const exchangeRate = currencyCode === baseCode ? 1 : Number(sourceOrder.exchangeRate || 1);

    const restoredOrder = addPurchaseOrder({
        id: nextPrefixedId('po'),
        date: now,
        currencyCode,
        baseCurrencyCode: baseCode,
        exchangeRate,
        rateDate: sourceOrder.rateDate || now,
        rateSource: sourceOrder.rateSource || 'manual',
        isAutoRate: sourceOrder.isAutoRate ?? false,
        supplierId: sourceOrder.supplierId,
        supplierName: sourceOrder.supplierName,
        supplierInvoiceNumber: sourceOrder.supplierInvoiceNumber,
        supplierInvoiceDate: sourceOrder.supplierInvoiceDate,
        warehouseId: sourceOrder.warehouseId,
        items: (sourceOrder.items || []).map((item) => ({
            materialId: item.materialId,
            name: item.name,
            quantity: Number(item.quantity || 0),
            unitPrice: Number(item.unitPrice || 0),
            total: Number(item.total || 0),
            lineDiscountPercent: item.lineDiscountPercent,
            lineDiscountAmount: item.lineDiscountAmount,
            lineDiscount: item.lineDiscount,
            bonus: item.bonus,
            warehouseId: item.warehouseId || sourceOrder.warehouseId,
            shelfId: item.shelfId,
            taxRate: item.taxRate,
            taxAmount: item.taxAmount,
        })),
        subTotal: Number(sourceOrder.subTotal || 0),
        invoiceDiscountPercent: sourceOrder.invoiceDiscountPercent,
        invoiceDiscountAmount: sourceOrder.invoiceDiscountAmount,
        lineDiscountTotal: sourceOrder.lineDiscountTotal,
        totalDiscount: sourceOrder.totalDiscount,
        taxMethod: sourceOrder.taxMethod || 'tax-inclusive',
        taxAmount: Number(sourceOrder.taxAmount || 0),
        grandTotal: Number(sourceOrder.grandTotal || 0),
        amountPaid: Number(sourceOrder.amountPaid || 0),
        amountDue: Number(sourceOrder.amountDue || 0),
        postingStatus: 'draft',
        grandTotalBase: Number(sourceOrder.grandTotalBase ?? sourceOrder.grandTotal ?? 0),
        amountPaidBase: Number(sourceOrder.amountPaidBase ?? sourceOrder.amountPaid ?? 0),
        amountDueBase: Number(sourceOrder.amountDueBase ?? sourceOrder.amountDue ?? 0),
        createdBy: session.user.name || 'admin',
    });

    revalidatePath('/admin/purchases');
    revalidatePath('/admin/purchases/history');

    return {
        success: true,
        orderId: restoredOrder.id,
        orderNumber: restoredOrder.orderNumber,
    };
}

export async function handleAdvancePurchasePostingStatus(orderId: string) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const order = getPurchaseOrderById(orderId);
    if (!order) return { error: 'ORDER_NOT_FOUND' };
    if (order.status !== 'active') return { error: 'ORDER_NOT_ACTIVE' };

    const currentPosting: 'draft' | 'saved' | 'posted' = order.postingStatus || 'posted';
    if (currentPosting === 'posted') {
        return { error: 'ALREADY_POSTED' };
    }

    const nextPosting: 'saved' | 'posted' = currentPosting === 'draft' ? 'saved' : 'posted';
    const invoiceDiscountAmount = Number(order.invoiceDiscountAmount || 0);
    const taxableBase = Math.max(0, Number(order.subTotal || 0) - invoiceDiscountAmount);
    const inferredInvoiceTaxRate = taxableBase > 0
        ? ((Number(order.taxAmount || 0) / taxableBase) * 100)
        : 0;

    return handleUpdatePurchaseOrder({
        id: order.id,
        supplierId: order.supplierId,
        supplierName: order.supplierName,
        supplierInvoiceNumber: order.supplierInvoiceNumber || '',
        supplierInvoiceDate: order.supplierInvoiceDate || '',
        warehouseId: order.warehouseId || '',
        allowDuplicateInvoice: true,
        currencyCode: order.currencyCode || order.baseCurrencyCode || 'USD',
        baseCurrencyCode: order.baseCurrencyCode || getDefaultCurrency()?.code || 'USD',
        exchangeRate: Number(order.exchangeRate || 1),
        rateDate: order.rateDate || new Date().toISOString().slice(0, 10),
        rateSource: order.rateSource || 'manual',
        isAutoRate: order.isAutoRate ?? false,
        taxMethod: order.taxMethod || 'tax-inclusive',
        postingType: nextPosting,
        invoiceTaxRate: inferredInvoiceTaxRate,
        invoiceDiscountPercent: Number(order.invoiceDiscountPercent || 0),
        invoiceDiscountAmount: Number(order.invoiceDiscountAmount || 0),
        amountPaid: Number(order.amountPaid || 0),
        items: (order.items || []).map((item) => ({
            materialId: item.materialId,
            name: item.name || item.materialId,
            quantity: Number(item.quantity || 0),
            unitPrice: Number(item.unitPrice || 0),
            total: Number(item.total || (Number(item.quantity || 0) * Number(item.unitPrice || 0))),
            lineDiscountPercent: Number(item.lineDiscountPercent || 0),
            lineDiscountAmount: Number(item.lineDiscountAmount || 0),
            lineDiscount: Number(item.lineDiscount || 0),
            bonus: Number(item.bonus || 0),
            warehouseId: item.warehouseId || order.warehouseId || '',
            shelfId: item.shelfId || '',
            taxRate: typeof item.taxRate === 'number' ? item.taxRate : undefined,
            taxAmount: typeof item.taxAmount === 'number' ? item.taxAmount : undefined,
        })),
        subTotal: Number(order.subTotal || 0),
        taxAmount: Number(order.taxAmount || 0),
        grandTotal: Number(order.grandTotal || 0),
        amountDue: Number(order.amountDue || 0),
    });
}

export async function handleCreatePurchaseReturn(values: any) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const parsed = purchaseReturnSchema.safeParse(values);
    if (!parsed.success) {
        console.error(parsed.error.flatten());
        return { error: 'INVALID_DATA' };
    }

    const { purchaseOrderId, expectedCurrencyCode, items, reasonCode, returnMode, date, postNow } = parsed.data;
    const shouldPostNow = postNow !== false;
    const normalizedReturnMode: 'physical' | 'financial_only' = returnMode === 'financial_only' ? 'financial_only' : 'physical';
    const settings = await getSettingsRuntime();
    const returnDate = date || new Date().toISOString();

    try {
        assertNotLockedByPeriod(returnDate, settings.periodCloseDate, settings.inventoryCloseDate);
    } catch (err: any) {
        return { error: err?.message || 'LOCKED' };
    }

    const order = getPurchaseOrderById(purchaseOrderId);
    if (!order) return { error: 'ORDER_NOT_FOUND' };
    if (order.status === 'cancelled') return { error: 'ORDER_CANCELLED' };

    const normalizedOrderCurrency = String(order.currencyCode || order.baseCurrencyCode || 'USD').trim().toUpperCase();
    const normalizedExpectedCurrency = String(expectedCurrencyCode || normalizedOrderCurrency).trim().toUpperCase();
    if (normalizedExpectedCurrency !== normalizedOrderCurrency) {
        return { error: 'MIXED_CURRENCY_NOT_ALLOWED' };
    }

    const allowedWarehouseIds = session.user.role === 'admin'
        ? null
        : new Set((session.user.warehouseIds || []).map((warehouseId) => String(warehouseId || '').trim()).filter(Boolean));

    const normalizeReturnKey = (materialId: string, warehouseId?: string, shelfId?: string) => {
        return `${materialId}||${String(warehouseId || '').trim()}||${String(shelfId || '').trim()}`;
    };

    const resolveOrderItemKey = (item: { materialId: string; warehouseId?: string; shelfId?: string }) => {
        return normalizeReturnKey(item.materialId, item.warehouseId || order.warehouseId || '', item.shelfId || '');
    };

    const alreadyReturned = getPurchaseReturnsByOrder(purchaseOrderId)
        .filter((ret) => ret.status !== 'cancelled')
        .flatMap((ret) => ret.items || [])
        .reduce((map, item) => {
            const key = normalizeReturnKey(item.materialId, item.warehouseId || '', item.shelfId || '');
            map.set(key, (map.get(key) || 0) + Number(item.quantity || 0));
            return map;
        }, new Map<string, number>());

    const alreadyReturnedByMaterial = getPurchaseReturnsByOrder(purchaseOrderId)
        .filter((ret) => ret.status !== 'cancelled')
        .flatMap((ret) => ret.items || [])
        .reduce((map, item) => {
            map.set(item.materialId, (map.get(item.materialId) || 0) + Number(item.quantity || 0));
            return map;
        }, new Map<string, number>());

    const orderItemIndex = new Map(order.items.map((it, idx) => [resolveOrderItemKey(it), idx]));
    const orderedQtyByKey = order.items.reduce((map, it) => {
        const key = resolveOrderItemKey(it);
        map.set(key, (map.get(key) || 0) + Number(it.quantity || 0));
        return map;
    }, new Map<string, number>());

    const orderedQtyByMaterial = order.items.reduce((map, it) => {
        map.set(it.materialId, (map.get(it.materialId) || 0) + Number(it.quantity || 0));
        return map;
    }, new Map<string, number>());

    const invoiceDiscountAmount = Number(order.invoiceDiscountAmount || 0);
    const orderSubTotal = Number(order.subTotal || 0);
    const orderTaxAmount = Number(order.taxAmount || 0);
    const invoiceTaxableBase = Math.max(0, orderSubTotal - invoiceDiscountAmount);
    const explicitInvoiceTaxRate = Number((order as any).invoiceTaxRate || 0);
    const invoiceLevelTaxRate = invoiceTaxableBase > 0
        ? (orderTaxAmount / invoiceTaxableBase)
        : (explicitInvoiceTaxRate > 0 ? explicitInvoiceTaxRate / 100 : 0);

    const effectiveTaxMethod: 'line-level' | 'invoice-level' | 'tax-inclusive' | 'tax-exempt' = (() => {
        if (order.taxMethod === 'line-level' || order.taxMethod === 'invoice-level' || order.taxMethod === 'tax-inclusive' || order.taxMethod === 'tax-exempt') {
            return order.taxMethod;
        }
        if (orderTaxAmount > 0 || explicitInvoiceTaxRate > 0) {
            return 'invoice-level';
        }
        return 'tax-inclusive';
    })();

    let preparedItems: PurchaseReturnItem[] = [];
    try {
        preparedItems = items.map((item) => {
            const key = normalizeReturnKey(item.materialId, item.warehouseId || order.warehouseId || '', item.shelfId || '');
            const idx = orderItemIndex.get(key);
            const orderItem = idx !== undefined ? order.items[idx] : order.items.find((it) => it.materialId === item.materialId);
            if (!orderItem) {
                throw new Error('ITEM_NOT_FOUND_IN_ORDER');
            }
            const selectedUnitPrice = Number(item.unitPrice);
            const costPerUnit = Number.isFinite(selectedUnitPrice) && selectedUnitPrice >= 0
                ? selectedUnitPrice
                : Number(orderItem.unitPrice || 0);
            const priceIncludesTax = Boolean(item.priceIncludesTax);

            let lineBaseAmount = item.quantity * costPerUnit;
            let lineTaxAmount = 0;

            let effectiveTaxRate = 0;
            if (effectiveTaxMethod === 'line-level') {
                const lineTaxRate = Number(orderItem.taxRate || 0);
                effectiveTaxRate = lineTaxRate > 0 ? lineTaxRate : invoiceLevelTaxRate;
            } else if (effectiveTaxMethod === 'invoice-level') {
                effectiveTaxRate = invoiceLevelTaxRate;
            }

            if ((effectiveTaxMethod === 'line-level' || effectiveTaxMethod === 'invoice-level') && effectiveTaxRate > 0) {
                if (priceIncludesTax) {
                    const grossAmount = item.quantity * costPerUnit;
                    lineBaseAmount = grossAmount / (1 + (effectiveTaxRate / 100));
                    lineTaxAmount = grossAmount - lineBaseAmount;
                } else {
                    lineBaseAmount = item.quantity * costPerUnit;
                    lineTaxAmount = (lineBaseAmount * effectiveTaxRate) / 100;
                }
            }

            const orderedQtyForKey = orderedQtyByKey.get(key) || Number(orderItem.quantity || 0);
            const returnedSoFar = alreadyReturned.get(key) || 0;
            const orderedQtyForMaterial = orderedQtyByMaterial.get(item.materialId) || 0;
            const returnedSoFarForMaterial = alreadyReturnedByMaterial.get(item.materialId) || 0;
            const exceedsByKey = item.quantity + returnedSoFar > orderedQtyForKey + 1e-9;
            const exceedsByMaterial = item.quantity + returnedSoFarForMaterial > orderedQtyForMaterial + 1e-9;
            if (exceedsByKey && exceedsByMaterial) {
                throw new Error('RETURN_QTY_EXCEEDS_ORDER');
            }
            const warehouseId = (item.warehouseId || orderItem.warehouseId || order.warehouseId || '').trim();
            const shelfId = (item.shelfId || orderItem.shelfId || '').trim();

            if (allowedWarehouseIds && warehouseId && !allowedWarehouseIds.has(warehouseId)) {
                throw new Error('WAREHOUSE_NOT_ALLOWED_FOR_USER');
            }

            if (normalizedReturnMode === 'physical') {
                assertReverseQuantity(item.materialId, warehouseId, shelfId, item.quantity);
            }
            const amount = lineBaseAmount + lineTaxAmount;
            return {
                id: nextPrefixedId('pri'),
                purchaseOrderId,
                materialId: item.materialId,
                quantity: item.quantity,
                warehouseId,
                shelfId,
                costPerUnitOriginal: item.quantity > 0 ? (lineBaseAmount / item.quantity) : costPerUnit,
                currencyCode: order.currencyCode,
                baseCurrencyCode: order.baseCurrencyCode,
                fxRateInvoice: order.exchangeRate,
                amount,
                amountBase: amount * order.exchangeRate,
            } as PurchaseReturnItem;
        });
    } catch (error: any) {
        return { error: error?.message || 'FAILED_TO_PREPARE_ITEMS' };
    }

    const totalAmount = preparedItems.reduce((sum, it) => sum + it.amount, 0);
    const totalAmountBase = preparedItems.reduce((sum, it) => sum + it.amountBase, 0);

    const createdReturn = addPurchaseReturn({
        purchaseOrderId,
        supplierId: order.supplierId,
        currencyCode: order.currencyCode,
        baseCurrencyCode: order.baseCurrencyCode,
        fxRateInvoice: order.exchangeRate,
        rateDate: order.rateDate,
        totalAmount,
        totalAmountBase,
        reasonCode,
        settlementMode: normalizedReturnMode,
        createdBy: session.user.name || 'admin',
        items: preparedItems,
    });

    let shipmentId: string | undefined;
    let journalEntryId: string | undefined;

    if (shouldPostNow) {
        if (normalizedReturnMode === 'financial_only') {
            const chart = await getChartOfAccountsRuntime();
            const findAccount = (code: string) => chart.find((acc) => acc.code === code && acc.type === 'account');

            const apAccount = findAccount('2100');
            const adjustmentAccount = findAccount(reasonCode === 'employee_error' ? '5140' : '5150');

            if (!apAccount || !adjustmentAccount) {
                return { error: 'ACCOUNT_NOT_FOUND_FOR_FINANCIAL_RETURN' };
            }

            const journal = addJournalEntry({
                date: returnDate,
                description: `Purchase return (financial only): ${createdReturn.returnNumber}`,
                referenceType: 'purchase_return',
                referenceId: createdReturn.id,
                lines: [
                    {
                        accountId: apAccount.id,
                        accountCode: apAccount.code,
                        accountName: apAccount.nameAr || apAccount.nameEn || 'Accounts Payable',
                        debit: totalAmountBase,
                        credit: 0,
                        description: createdReturn.returnNumber,
                    },
                    {
                        accountId: adjustmentAccount.id,
                        accountCode: adjustmentAccount.code,
                        accountName: adjustmentAccount.nameAr || adjustmentAccount.nameEn || 'Purchase Returns',
                        debit: 0,
                        credit: totalAmountBase,
                        description: createdReturn.returnNumber,
                    },
                ],
                createdBy: session.user.name || 'admin',
            });

            journalEntryId = journal.id;

            updatePurchaseReturn(createdReturn.id, {
                status: 'posted',
                journalEntryId,
            });

            try {
                updateSupplierBalance(order.supplierId, -totalAmountBase);
            } catch (error) {
                console.error('Failed to update supplier balance for financial-only return:', error);
            }
        } else {
        const shipment = await createShipmentRuntime({
            shipmentType: 'reverse',
            date: returnDate,
            invoiceId: order.id,
            hasInventoryMovement: true,
            periodCloseDate: settings.periodCloseDate,
            inventoryCloseDate: settings.inventoryCloseDate,
        });
        shipmentId = shipment.id;

        const movements = preparedItems.map((it) => ({
            date: returnDate,
            materialId: it.materialId,
            warehouseId: it.warehouseId,
            shelfId: it.shelfId,
            quantityIn: 0,
            quantityOut: it.quantity,
            referenceType: 'purchase_return',
            referenceId: createdReturn.id,
            shipmentId: shipment.id,
            invoiceId: order.id,
            costPerUnitOriginal: it.costPerUnitOriginal,
        }));

        let createdMovements: any[];
        if (isPostgresProviderEnabled()) {
            const pgMovements = movements.map((m: any) => ({ ...m, id: nextPrefixedId('inv-move') }));
            await pgSaveInventoryMovements(pgMovements as Array<Record<string, unknown>>);
            createdMovements = pgMovements;
        } else {
            createdMovements = addInventoryMovements(movements);
        }

        try {
            const journal = generateJournalForInventoryAdjustment(createdMovements, {
                shipmentType: 'reverse',
                invoiceType: 'purchase',
                supplierId: order.supplierId,
                periodLocked: !!(settings.periodCloseDate && new Date(returnDate) <= new Date(settings.periodCloseDate)),
                reasonCode: reasonCode || 'normal',
                referenceType: 'purchase_return',
                referenceId: createdReturn.id,
                createdBy: session.user.name || 'admin',
            });
            journalEntryId = journal?.id;
        } catch (error: any) {
            console.error('Failed to create purchase return journal:', error);
            return { error: error?.message || 'JOURNAL_FAILED' };
        }

        updatePurchaseReturn(createdReturn.id, {
            status: 'posted',
            shipmentId: shipment.id,
            journalEntryId,
        });

        try {
            updateSupplierBalance(order.supplierId, -totalAmountBase);
        } catch (error) {
            console.error('Failed to update supplier balance for return:', error);
        }
        }
    } else {
        updatePurchaseReturn(createdReturn.id, {
            status: 'draft',
        });
    }

    revalidatePath('/admin/purchases');
    revalidatePath('/admin/purchases/returns');
    revalidatePath('/admin/purchases/balances');
    revalidatePath('/admin/purchases/statement');

    return { success: true, returnNumber: createdReturn.returnNumber, shipmentId, journalEntryId, status: shouldPostNow ? 'posted' : 'draft' };
}

export async function handleCancelPurchaseReturn(returnId: string) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const settings = await getSettingsRuntime();
    const now = new Date().toISOString();

    const ret = getPurchaseReturnById(returnId);
    if (!ret) return { error: 'RETURN_NOT_FOUND' };
    if (ret.status === 'cancelled') return { error: 'ALREADY_CANCELLED' };

    const order = getPurchaseOrderById(ret.purchaseOrderId);
    if (!order) return { error: 'ORDER_NOT_FOUND' };

    try {
        assertNotLockedByPeriod(now, settings.periodCloseDate, settings.inventoryCloseDate);
    } catch (err: any) {
        return { error: err?.message || 'LOCKED' };
    }

    let cancelJournalId: string | undefined;
    let cancelShipmentId: string | undefined;

    if ((ret.settlementMode || 'physical') === 'financial_only') {
        const journalEntries = await getJournalEntriesRuntime();
        const originalEntry = ret.journalEntryId
            ? journalEntries.find((entry) => entry.id === ret.journalEntryId)
            : null;

        if (originalEntry) {
            const reversingLines = originalEntry.lines.map((line) => ({
                ...line,
                debit: Number(line.credit || 0),
                credit: Number(line.debit || 0),
            }));

            const reverseEntry = addJournalEntry({
                date: now,
                description: `Cancel purchase return (financial only): ${ret.returnNumber}`,
                referenceType: 'purchase_return_cancel',
                referenceId: ret.id,
                lines: reversingLines,
                createdBy: session.user.name || 'admin',
            });
            cancelJournalId = reverseEntry.id;
        }
    } else {
        // Re-add stock that was previously removed by the return
        const shipment = await createShipmentRuntime({
            shipmentType: 'adjustment',
            date: now,
            invoiceId: order.id,
            hasInventoryMovement: true,
            periodCloseDate: settings.periodCloseDate,
            inventoryCloseDate: settings.inventoryCloseDate,
        });
        cancelShipmentId = shipment.id;

        const movements = (ret.items || []).map((it) => ({
            date: now,
            materialId: it.materialId,
            warehouseId: it.warehouseId,
            shelfId: it.shelfId,
            quantityIn: it.quantity,
            quantityOut: 0,
            referenceType: 'purchase_return_cancel',
            referenceId: ret.id,
            shipmentId: shipment.id,
            invoiceId: order.id,
            costPerUnitOriginal: it.costPerUnitOriginal,
        }));

        let createdMovements: any[];
        if (isPostgresProviderEnabled()) {
            const pgMovements = movements.map((m: any) => ({ ...m, id: nextPrefixedId('inv-move') }));
            await pgSaveInventoryMovements(pgMovements as Array<Record<string, unknown>>);
            createdMovements = pgMovements;
        } else {
            createdMovements = addInventoryMovements(movements);
        }

        try {
            const journal = generateJournalForInventoryAdjustment(createdMovements, {
                shipmentType: 'adjustment',
                invoiceType: 'purchase',
                supplierId: order.supplierId,
                periodLocked: !!(settings.periodCloseDate && new Date(now) <= new Date(settings.periodCloseDate)),
                reasonCode: ret.reasonCode || 'normal',
                referenceType: 'purchase_return_cancel',
                referenceId: ret.id,
                createdBy: session.user.name || 'admin',
            });
            cancelJournalId = journal?.id;
        } catch (error: any) {
            console.error('Failed to create cancel journal for purchase return:', error);
            return { error: error?.message || 'JOURNAL_FAILED' };
        }
    }

    // Restore supplier balance
    try {
        updateSupplierBalance(ret.supplierId, ret.totalAmountBase);
    } catch (error) {
        console.error('Failed to restore supplier balance on cancel:', error);
    }

    updatePurchaseReturn(ret.id, {
        status: 'cancelled',
        journalEntryId: ret.journalEntryId || cancelJournalId,
        shipmentId: ret.shipmentId || cancelShipmentId,
    });

    revalidatePath('/admin/purchases');
    revalidatePath('/admin/purchases/returns');
    revalidatePath('/admin/purchases/balances');
    revalidatePath('/admin/purchases/statement');

    return { success: true, journalEntryId: cancelJournalId, shipmentId: cancelShipmentId };
}

export async function handleCreateInternalTransfer(values: z.infer<typeof internalTransferSchema>) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const parsed = internalTransferSchema.safeParse(values);
    if (!parsed.success) {
        return { error: 'Invalid data', details: parsed.error.flatten() };
    }

    const { addInternalTransfer, getAvailableStock, addInventoryMovements } = await import('./data');
    const payload = {
        ...parsed.data,
        date: parsed.data.date || new Date().toISOString(),
        createdBy: session.user.name || 'admin',
    };

    try {
        const settings = await getSettingsRuntime();
        assertNotLockedByPeriod(payload.date, settings.periodCloseDate, settings.inventoryCloseDate);
    } catch (error: any) {
        return { error: error?.message || 'PERIOD_LOCKED' };
    }

    try {
        const available = getAvailableStock(payload.materialId, payload.fromWarehouseId, payload.fromShelfId);
        if (available - payload.quantity < 0) {
            return { error: 'INSUFFICIENT_STOCK_FOR_TRANSFER', available };
        }
    } catch (error) {
        console.error('Failed stock check for internal transfer:', error);
    }

    const transfer = addInternalTransfer(payload as any);

    try {
        const transferMovements = [
            {
                date: payload.date,
                materialId: payload.materialId,
                warehouseId: payload.fromWarehouseId,
                shelfId: payload.fromShelfId,
                quantityIn: 0,
                quantityOut: payload.quantity,
                referenceType: 'internal_transfer',
                referenceId: transfer.id,
                shipmentId: undefined,
                invoiceId: undefined,
            },
            {
                date: payload.date,
                materialId: payload.materialId,
                warehouseId: payload.toWarehouseId,
                shelfId: payload.toShelfId,
                quantityIn: payload.quantity,
                quantityOut: 0,
                referenceType: 'internal_transfer',
                referenceId: transfer.id,
                shipmentId: undefined,
                invoiceId: undefined,
            },
        ];
        if (isPostgresProviderEnabled()) {
            const pgTransferMovs = transferMovements.map((m) => ({ ...m, id: nextPrefixedId('inv-move') }));
            await pgSaveInventoryMovements(pgTransferMovs as Array<Record<string, unknown>>);
        } else {
            addInventoryMovements(transferMovements);
        }
    } catch (error) {
        console.error('Failed to record inventory movements for internal transfer:', error);
    }

    revalidatePath('/admin/data/materials');
    revalidatePath('/admin/data/internal-transfers');
    return { success: true, transferId: transfer.id };
}

export async function handleCreateInternalTransferDocument(values: z.infer<typeof internalTransferDocumentSchema>) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const parsed = internalTransferDocumentSchema.safeParse(values);
    if (!parsed.success) {
        return { error: 'Invalid data', details: parsed.error.flatten() };
    }

    const enableWarehouseTransfer = parsed.data.enableWarehouseTransfer ?? true;
    const enableShelfTransfer = parsed.data.enableShelfTransfer ?? true;
    const normalizedItems = ensureLineIds(
        normalizeInternalTransferItems(parsed.data.items, enableWarehouseTransfer, enableShelfTransfer)
    );

    if (enableWarehouseTransfer || enableShelfTransfer) {
        const lockResult = ensureTransferLocks(
            normalizedItems.map((item) => item.materialId),
            session.user.id,
            session.user.name || 'admin'
        );
        if (!lockResult.success) {
            return { success: false, lockedBy: lockResult.lockedBy || 'unknown' };
        }
    }

    const payload = {
        date: parsed.data.date || new Date().toISOString(),
        enableWarehouseTransfer,
        enableShelfTransfer,
        allowZeroItems: parsed.data.allowZeroItems ?? false,
        supplierId: parsed.data.supplierId || undefined,
        supplierName: parsed.data.supplierName || undefined,
        sourcePurchaseOrderId: parsed.data.sourcePurchaseOrderId || undefined,
        sourcePurchaseOrderNumber: parsed.data.sourcePurchaseOrderNumber || undefined,
        items: normalizedItems,
        note: parsed.data.note || undefined,
        receiptStatus: 'pending' as const,
        createdBy: session.user.name || 'admin',
    };

    try {
        const settings = await getSettingsRuntime();
        assertNotLockedByPeriod(payload.date, settings.periodCloseDate, settings.inventoryCloseDate);
    } catch (error: any) {
        return { error: error?.message || 'PERIOD_LOCKED' };
    }

    // تحقق من توفر الكميات قبل إنشاء الإرسالية (لا نسمح بسالب)
    try {
        const { getAvailableStock } = await import('./data');
        for (const item of payload.items) {
            const fromWh = item.fromWarehouseId;
            const fromShelf = item.fromShelfId;
            const available = getAvailableStock(item.materialId, fromWh, fromShelf);
            if (available - item.quantity < 0) {
                return { error: 'INSUFFICIENT_STOCK_FOR_TRANSFER_DOC', materialId: item.materialId, available };
            }
        }
    } catch (error) {
        console.error('Failed stock check for transfer document:', error);
    }

    const doc = addInternalTransferDocument(payload as any);

    if (isPostgresProviderEnabled()) {
        try {
            await pgSaveInternalTransfers([doc as unknown as Record<string, unknown>]);
        } catch (error) {
            console.error('Failed to mirror transfer document to PostgreSQL:', error);
        }
    }

    // سجل حركات المخزون (خروج من الرف الأصلي ودخول للوجهة)
    try {
        const movementEntries = payload.items.flatMap((item, index) => {
            const outEntry = {
                id: `${doc.id}-out-${index + 1}`,
                date: payload.date,
                materialId: item.materialId,
                warehouseId: item.fromWarehouseId,
                shelfId: item.fromShelfId,
                quantityIn: 0,
                quantityOut: item.quantity,
                referenceType: 'transfer_document',
                referenceId: doc.id,
                shipmentId: undefined,
                invoiceId: payload.sourcePurchaseOrderId,
            };
            const toWarehouseId = enableWarehouseTransfer ? item.toWarehouseId : item.fromWarehouseId;
            const toShelfId = enableShelfTransfer ? item.toShelfId : item.fromShelfId;
            const inEntry = {
                id: `${doc.id}-in-${index + 1}`,
                date: payload.date,
                materialId: item.materialId,
                warehouseId: toWarehouseId,
                shelfId: toShelfId,
                quantityIn: item.quantity,
                quantityOut: 0,
                referenceType: 'transfer_document',
                referenceId: doc.id,
                shipmentId: undefined,
                invoiceId: payload.sourcePurchaseOrderId,
            };
            return [outEntry, inEntry];
        });

        if (isPostgresProviderEnabled()) {
            await pgSaveInventoryMovements(movementEntries as Array<Record<string, unknown>>);
        } else {
            addInventoryMovements(movementEntries.map(({ id, ...rest }) => rest));
        }
    } catch (error) {
        console.error('Failed to record inventory movements for transfer document:', error);
    }

    normalizedItems.forEach((item) => releaseTransferLock(item.materialId, session.user.id));

    revalidatePath('/admin/data/internal-transfers');
    revalidatePath('/admin/data/materials');
    return { success: true, transferId: doc.id, transferNumber: doc.transferNumber };
}

export async function handleUpdateInternalTransferDocument(id: string, values: z.infer<typeof internalTransferDocumentSchema>) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const parsed = internalTransferDocumentSchema.safeParse(values);
    if (!parsed.success) {
        return { error: 'Invalid data', details: parsed.error.flatten() };
    }

    const enableWarehouseTransfer = parsed.data.enableWarehouseTransfer ?? true;
    const enableShelfTransfer = parsed.data.enableShelfTransfer ?? true;
    const normalizedItems = ensureLineIds(
        normalizeInternalTransferItems(parsed.data.items, enableWarehouseTransfer, enableShelfTransfer)
    );

    if (enableWarehouseTransfer || enableShelfTransfer) {
        const lockResult = ensureTransferLocks(
            normalizedItems.map((item) => item.materialId),
            session.user.id,
            session.user.name || 'admin'
        );
        if (!lockResult.success) {
            return { success: false, lockedBy: lockResult.lockedBy || 'unknown' };
        }
    }

    const { getInternalTransferDocumentById } = await import('./data');
    const existingDoc = getInternalTransferDocumentById(id);
    const mergedItems = mergeReceivedQuantities(normalizedItems, existingDoc?.items ?? []);

    const updated = updateInternalTransferDocument(id, {
        date: parsed.data.date || new Date().toISOString(),
        enableWarehouseTransfer,
        enableShelfTransfer,
        allowZeroItems: parsed.data.allowZeroItems ?? false,
        supplierId: parsed.data.supplierId || existingDoc?.supplierId,
        supplierName: parsed.data.supplierName || existingDoc?.supplierName,
        sourcePurchaseOrderId: parsed.data.sourcePurchaseOrderId || existingDoc?.sourcePurchaseOrderId,
        sourcePurchaseOrderNumber: parsed.data.sourcePurchaseOrderNumber || existingDoc?.sourcePurchaseOrderNumber,
        items: mergedItems as any,
        note: parsed.data.note || undefined,
    });

    mergedItems.forEach((item) => releaseTransferLock(item.materialId, session.user.id));

    if (!updated) return { error: 'Not found' };

    if (isPostgresProviderEnabled()) {
        try {
            await pgSaveInternalTransfers([updated as unknown as Record<string, unknown>]);
        } catch (error) {
            console.error('Failed to mirror updated transfer document to PostgreSQL:', error);
        }
    }

    revalidatePath('/admin/data/internal-transfers');
    revalidatePath('/admin/data/materials');
    return { success: true };
}

const internalTransferReceiptItemSchema = z.object({
    lineId: z.string().optional(),
    receivedQuantity: z.coerce.number().min(0),
    toShelfId: z.string().optional(),
    receiptDistributions: z
        .array(
            z.object({
                shelfId: z.string().min(1),
                quantity: z.coerce.number().gt(0),
            })
        )
        .optional(),
});

const internalTransferReceiptSchema = z.object({
    items: z.array(internalTransferReceiptItemSchema).min(1),
    note: z.string().optional(),
});

function isQuarantineShelfLabel(name: string) {
    const normalized = String(name || '').trim().toLowerCase();
    if (!normalized) return false;
    return normalized.includes('حجر') || normalized.includes('quarantine') || normalized.includes('hold');
}

const internalTransferReceiptLineSchema = z.object({
    lineId: z.string().min(1),
    receivedQuantity: z.coerce.number().min(0),
    toShelfId: z.string().optional(),
    receiptDistributions: z
        .array(
            z.object({
                shelfId: z.string().min(1),
                quantity: z.coerce.number().gt(0),
            })
        )
        .optional(),
    note: z.string().optional(),
});

function applyReceiptToTransferDoc(
    doc: any,
    data: {
        items: Array<{
            lineId?: string;
            receivedQuantity: number;
            toShelfId?: string;
            receiptDistributions?: Array<{ shelfId: string; quantity: number }>;
        }>;
        receivedBy: string;
        receiptNote?: string;
    }
) {
    const itemByLineId = new Map<
        string,
        {
            receivedQuantity: number;
            toShelfId?: string;
            receiptDistributions?: Array<{ shelfId: string; quantity: number }>;
        }
    >();

    data.items.forEach((item) => {
        if (!item.lineId) return;
        itemByLineId.set(item.lineId, {
            receivedQuantity: Math.max(0, Number(item.receivedQuantity || 0)),
            toShelfId: item.toShelfId,
            receiptDistributions: (item.receiptDistributions || [])
                .map((entry) => ({
                    shelfId: String(entry.shelfId || '').trim(),
                    quantity: Number(entry.quantity || 0),
                }))
                .filter((entry) => entry.shelfId && Number.isFinite(entry.quantity) && entry.quantity > 0),
        });
    });

    const nextItems = (doc?.items || []).map((item: any, itemIndex: number) => {
        const lineId = item.lineId || `line-${itemIndex + 1}`;
        const incoming = itemByLineId.get(lineId);
        const reported = incoming ? Number(incoming.receivedQuantity || 0) : Number(item.receivedQuantity || 0);
        const baseReceived = Math.max(0, Math.min(Number(item.quantity || 0), reported));
        const overReceivedQuantity = Math.max(0, reported - Number(item.quantity || 0));
        const rejectedQuantity = Math.max(0, Number(item.quantity || 0) - baseReceived);
        const overageStatus = overReceivedQuantity > 0 ? ('pending' as const) : undefined;
        const overApprovedQuantity = overReceivedQuantity > 0 ? Number(item.overApprovedQuantity || 0) : 0;
        const receiptDistributions = incoming?.receiptDistributions || [];
        const nextToShelfId = receiptDistributions[0]?.shelfId || incoming?.toShelfId || item.toShelfId;

        return {
            ...item,
            lineId,
            toShelfId: nextToShelfId,
            receiptDistributions,
            receivedQuantity: baseReceived,
            rejectedQuantity,
            overReceivedQuantity,
            overApprovedQuantity,
            overageStatus,
        };
    });

    const hasPendingOverage = nextItems.some((item: any) => item.overageStatus === 'pending');
    const hasShortage = nextItems.some((item: any) => Number(item.rejectedQuantity || 0) > 0);
    const receiptStatus = hasPendingOverage ? 'pending-approval' : hasShortage ? 'partial' : 'received';

    return {
        ...doc,
        items: nextItems,
        receiptStatus,
        receivedBy: data.receivedBy,
        receivedAt: new Date().toISOString(),
        receiptNote: data.receiptNote,
    };
}

function applyReceiptDraftToTransferDoc(
    doc: any,
    data: {
        items: Array<{
            lineId?: string;
            receivedQuantity: number;
            toShelfId?: string;
            receiptDistributions?: Array<{ shelfId: string; quantity: number }>;
        }>;
        receiptNote?: string;
    }
) {
    const itemByLineId = new Map<
        string,
        {
            receivedQuantity: number;
            toShelfId?: string;
            receiptDistributions?: Array<{ shelfId: string; quantity: number }>;
        }
    >();

    data.items.forEach((item) => {
        if (!item.lineId) return;
        itemByLineId.set(item.lineId, {
            receivedQuantity: Math.max(0, Number(item.receivedQuantity || 0)),
            toShelfId: item.toShelfId,
            receiptDistributions: (item.receiptDistributions || [])
                .map((entry) => ({
                    shelfId: String(entry.shelfId || '').trim(),
                    quantity: Number(entry.quantity || 0),
                }))
                .filter((entry) => entry.shelfId && Number.isFinite(entry.quantity) && entry.quantity > 0),
        });
    });

    const nextItems = (doc?.items || []).map((item: any, itemIndex: number) => {
        const lineId = item.lineId || `line-${itemIndex + 1}`;
        const incoming = itemByLineId.get(lineId);
        const reported = incoming ? Number(incoming.receivedQuantity || 0) : Math.max(0, Number(item.receivedQuantity || 0));
        const receiptDistributions = incoming?.receiptDistributions || item.receiptDistributions || [];
        const nextToShelfId = receiptDistributions[0]?.shelfId || incoming?.toShelfId || item.toShelfId;

        return {
            ...item,
            lineId,
            toShelfId: nextToShelfId,
            receiptDistributions,
            receivedQuantity: reported,
            rejectedQuantity: Math.max(0, Number(item.quantity || 0) - reported),
            overReceivedQuantity: Math.max(0, reported - Number(item.quantity || 0)),
            overApprovedQuantity: Number(item.overApprovedQuantity || 0),
            // حفظ السطر هو مسودة فقط، لذلك لا ننقل السند لمسار الاعتماد قبل تأكيد الاستلام الكامل
            overageStatus: undefined,
        };
    });

    return {
        ...doc,
        items: nextItems,
        receiptStatus: 'pending',
        receiptNote: data.receiptNote ?? doc?.receiptNote,
    };
}

async function persistInternalTransferRuntimeDoc(updatedDoc: any) {
    const docId = String(updatedDoc?.id || '').trim();
    if (!docId) return;

    if (isPostgresProviderEnabled()) {
        try {
            await pgSaveInternalTransfers([updatedDoc as Record<string, unknown>]);
        } catch (error) {
            console.error('Failed to persist internal transfer document to PostgreSQL:', error);
        }
    }

    const legacyDocs = getInternalTransferDocuments() || [];
    const nextDocs = legacyDocs.map((entry: any) => (String(entry?.id || '').trim() === docId ? updatedDoc : entry));
    const hasDoc = legacyDocs.some((entry: any) => String(entry?.id || '').trim() === docId);
    if (!hasDoc) {
        nextDocs.push(updatedDoc);
    }
    writeData('internal_transfer_docs.json', nextDocs);
}

const internalTransferOverageApprovalSchema = z.object({
    approved: z.boolean(),
    items: z
        .array(
            z.object({
                lineId: z.string().min(1),
                sourceShelfId: z.string().optional(),
            })
        )
        .optional(),
});

export async function handleConfirmInternalTransferReceipt(
    id: string,
    values: z.infer<typeof internalTransferReceiptSchema>
) {
    const session = await getSession();
    if (!session?.user) return { error: 'Unauthorized' };

    const parsed = internalTransferReceiptSchema.safeParse(values);
    if (!parsed.success) {
        return { error: 'Invalid data', details: parsed.error.flatten() };
    }

    const doc = await getInternalTransferDocumentByIdRuntime(id);
    if (!doc || doc.status !== 'active') {
        return { error: 'Document not found or inactive.' };
    }

    ensureInternalTransferLegacyMirror(doc);
    const { approveInternalTransferOverage } = await import('./data');

    const allowedWarehouseIds = session.user.role === 'admin' ? null : (session.user.warehouseIds ?? []);
    if (allowedWarehouseIds && allowedWarehouseIds.length > 0) {
        const allowedSet = new Set(allowedWarehouseIds);
        const hasUnauthorized = doc.items.some((item) => !allowedSet.has(item.toWarehouseId));
        if (hasUnauthorized) {
            return { error: 'Unauthorized warehouse.' };
        }
    }

    const requestedByLineId = new Map<
        string,
        { receivedQuantity: number; toShelfId?: string; receiptDistributions?: Array<{ shelfId: string; quantity: number }> }
    >();
    parsed.data.items.forEach((item) => {
        if (item.lineId) {
            requestedByLineId.set(item.lineId, {
                receivedQuantity: item.receivedQuantity,
                toShelfId: item.toShelfId,
                receiptDistributions: (item.receiptDistributions || [])
                    .map((entry) => ({
                        shelfId: String(entry?.shelfId || '').trim(),
                        quantity: Number(entry?.quantity || 0),
                    }))
                    .filter((entry) => entry.shelfId && Number.isFinite(entry.quantity) && entry.quantity > 0) as Array<{
                        shelfId: string;
                        quantity: number;
                    }>,
            });
        }
    });

    const receiptItems = doc.items.map((item, index) => {
        const lineId = item.lineId || `line-${index + 1}`;
        const requested = requestedByLineId.get(lineId);
        const receivedQuantity = Math.max(0, requested?.receivedQuantity ?? item.receivedQuantity ?? 0);
        const toShelfId = requested?.toShelfId || item.toShelfId;
        const receiptDistributions = (requested?.receiptDistributions || item.receiptDistributions || [])
            .map((entry) => ({
                shelfId: String(entry?.shelfId || '').trim(),
                quantity: Number(entry?.quantity || 0),
            }))
            .filter((entry) => entry.shelfId && Number.isFinite(entry.quantity) && entry.quantity > 0);
        return { lineId, receivedQuantity, toShelfId, receiptDistributions };
    });

    if (doc.enableShelfTransfer) {
        const { getWarehouses } = await import('./data');
        const warehouseById = new Map(getWarehouses().map((warehouse) => [warehouse.id, warehouse]));

        const overageWithoutQuarantine = doc.items.some((item, index) => {
            const lineId = item.lineId || `line-${index + 1}`;
            const incoming = receiptItems.find((entry) => entry.lineId === lineId);
            if (!incoming) return false;
            const hasOverage = Number(incoming.receivedQuantity || 0) > Number(item.quantity || 0);
            if (!hasOverage) return false;
            const shelfId = String(incoming.toShelfId || '').trim();
            const shelf = warehouseById
                .get(item.toWarehouseId)
                ?.shelves?.find((entry) => String(entry.id || '') === shelfId);
            return !shelf || !isQuarantineShelfLabel(String(shelf.name || ''));
        });

        if (overageWithoutQuarantine) {
            return { error: 'OVERAGE_REQUIRES_QUARANTINE_SHELF' };
        }
    }

    const updated = isPostgresProviderEnabled()
        ? applyReceiptToTransferDoc(doc, {
            items: receiptItems,
            receivedBy: session.user.name || session.user.id,
            receiptNote: parsed.data.note || undefined,
        })
        : confirmInternalTransferReceipt(id, {
            items: receiptItems,
            receivedBy: session.user.name || session.user.id,
            receiptNote: parsed.data.note || undefined,
        });

    if (!updated) {
        return { error: 'Failed to update receipt.' };
    }

    if (isPostgresProviderEnabled()) {
        try {
            await pgSaveInternalTransfers([updated as unknown as Record<string, unknown>]);
        } catch (error) {
            console.error('Failed to mirror receipt confirmation to PostgreSQL:', error);
        }
    }

    // إنشاء ارسالية نقص وإشعار المصدر عند استلام كمية أقل من المرسلة
    const shortages = updated.items
        .filter((item) => (item.rejectedQuantity ?? 0) > 0)
        .map((item) => ({
            materialId: item.materialId,
            missingQuantity: item.rejectedQuantity ?? 0,
            fromWarehouseId: item.fromWarehouseId,
            toWarehouseId: item.toWarehouseId,
            fromShelfId: item.fromShelfId,
            toShelfId: item.toShelfId,
            lineId: item.lineId,
        }));

    let shortageNotice: { transferNumber: string; id: string; items: typeof shortages } | undefined;

    if (shortages.length > 0) {
        const shortageDoc = addInternalTransferDocument({
            date: new Date().toISOString(),
            enableWarehouseTransfer: updated.enableWarehouseTransfer ?? true,
            enableShelfTransfer: updated.enableShelfTransfer ?? false,
            allowZeroItems: false,
            createdBy: session.user.id,
            receiptStatus: 'pending',
            note: `نقص مستلم من الارسالية ${doc.transferNumber}`,
            supplierId: doc.supplierId,
            supplierName: doc.supplierName,
            sourcePurchaseOrderId: doc.sourcePurchaseOrderId,
            sourcePurchaseOrderNumber: doc.sourcePurchaseOrderNumber,
            items: shortages.map((item, index) => ({
                lineId: item.lineId || `short-${index + 1}`,
                materialId: item.materialId,
                quantity: item.missingQuantity,
                fromWarehouseId: item.fromWarehouseId,
                fromShelfId: item.fromShelfId,
                toWarehouseId: item.toWarehouseId,
                toShelfId: item.toShelfId,
            })),
        });

        if (isPostgresProviderEnabled()) {
            try {
                await pgSaveInternalTransfers([shortageDoc as unknown as Record<string, unknown>]);
            } catch (error) {
                console.error('Failed to mirror shortage transfer document to PostgreSQL:', error);
            }
        }

        shortageNotice = {
            transferNumber: shortageDoc.transferNumber,
            id: shortageDoc.id,
            items: shortages,
        };
    }

    revalidatePath('/employee/work-tasks');
    revalidatePath('/employee/dashboard');
    revalidatePath('/admin/data/internal-transfers');
    return { success: true, receiptStatus: updated.receiptStatus, shortageNotice };
}

export async function handleSaveInternalTransferReceiptLine(
    id: string,
    values: z.infer<typeof internalTransferReceiptLineSchema>
) {
    const session = await getSession();
    if (!session?.user) return { error: 'Unauthorized' };

    const parsed = internalTransferReceiptLineSchema.safeParse(values);
    if (!parsed.success) {
        return { error: 'Invalid data', details: parsed.error.flatten() };
    }

    const doc = await getInternalTransferDocumentByIdRuntime(id);
    if (!doc || doc.status !== 'active') {
        return { error: 'Document not found or inactive.' };
    }

    ensureInternalTransferLegacyMirror(doc);

    const allowedWarehouseIds = session.user.role === 'admin' ? null : (session.user.warehouseIds ?? []);
    if (allowedWarehouseIds && allowedWarehouseIds.length > 0) {
        const allowedSet = new Set(allowedWarehouseIds);
        const hasUnauthorized = doc.items.some((item) => !allowedSet.has(item.toWarehouseId));
        if (hasUnauthorized) {
            return { error: 'Unauthorized warehouse.' };
        }
    }

    const receiptItems = doc.items.map((item, index) => {
        const lineId = item.lineId || `line-${index + 1}`;
        const isTarget = lineId === parsed.data.lineId;
        const receivedQuantity = isTarget
            ? Math.max(0, Number(parsed.data.receivedQuantity || 0))
            : Math.max(0, Number(item.receivedQuantity || 0));
        const toShelfId = isTarget
            ? (parsed.data.toShelfId || item.toShelfId)
            : item.toShelfId;
        const receiptDistributions = isTarget
            ? (parsed.data.receiptDistributions || item.receiptDistributions || [])
            : (item.receiptDistributions || []);
        return { lineId, receivedQuantity, toShelfId, receiptDistributions };
    });

    const exists = receiptItems.some((item) => item.lineId === parsed.data.lineId);
    if (!exists) {
        return { error: 'Line not found.' };
    }

    if (doc.enableShelfTransfer) {
        const targetIndex = doc.items.findIndex((item, index) => (item.lineId || `line-${index + 1}`) === parsed.data.lineId);
        if (targetIndex !== -1) {
            const targetItem = doc.items[targetIndex];
            const selectedReceived = Number(receiptItems[targetIndex]?.receivedQuantity || 0);
            const hasOverage = selectedReceived > Number(targetItem.quantity || 0);
            if (hasOverage) {
                const selectedShelfId = String(receiptItems[targetIndex]?.toShelfId || '').trim();
                const { getWarehouses } = await import('./data');
                const warehouse = getWarehouses().find((entry) => entry.id === targetItem.toWarehouseId);
                const selectedShelf = warehouse?.shelves?.find((shelf) => String(shelf.id || '') === selectedShelfId);
                if (!selectedShelf || !isQuarantineShelfLabel(String(selectedShelf.name || ''))) {
                    return { error: 'OVERAGE_REQUIRES_QUARANTINE_SHELF' };
                }
            }
        }
    }

    const updated = applyReceiptDraftToTransferDoc(doc, {
        items: receiptItems,
        receiptNote: parsed.data.note || undefined,
    });

    if (!updated) {
        return { error: 'Failed to update receipt line.' };
    }

    await persistInternalTransferRuntimeDoc(updated);

    revalidatePath('/employee/work-tasks');
    revalidatePath('/employee/dashboard');
    revalidatePath('/admin/data/internal-transfers');
    return { success: true, receiptStatus: 'pending' };
}

export async function handleApproveInternalTransferOverage(
    id: string,
    values: z.infer<typeof internalTransferOverageApprovalSchema>
) {
    const session = await getSession();
    if (!session?.user) return { error: 'Unauthorized' };

    const parsed = internalTransferOverageApprovalSchema.safeParse(values);
    if (!parsed.success) {
        return { error: 'Invalid data', details: parsed.error.flatten() };
    }

    const doc = await getInternalTransferDocumentByIdRuntime(id);
    if (!doc || doc.status !== 'active') {
        return { error: 'Document not found or inactive.' };
    }

    ensureInternalTransferLegacyMirror(doc);
    const { approveInternalTransferOverage } = await import('./data');

    const allowedWarehouseIds = session.user.role === 'admin' ? null : (session.user.warehouseIds ?? []);
    if (allowedWarehouseIds && allowedWarehouseIds.length > 0) {
        const allowedSet = new Set(allowedWarehouseIds);
        const hasUnauthorized = doc.items.some(
            (item) => item.overageStatus === 'pending' && !allowedSet.has(item.fromWarehouseId)
        );
        if (hasUnauthorized) {
            return { error: 'Unauthorized warehouse.' };
        }
    }

    let lineItems: Array<{ lineId?: string; sourceShelfId?: string }> | undefined;
    if (parsed.data.approved) {
        const lineItemMap = new Map(parsed.data.items?.map((item) => [item.lineId, item.sourceShelfId]));
        const missingShelf = doc.items.some(
            (item) => item.overageStatus === 'pending' && (!item.lineId || !lineItemMap.get(item.lineId))
        );
        if (missingShelf) {
            return { error: 'Missing source shelf selection.' };
        }
        lineItems = doc.items
            .filter((item) => item.overageStatus === 'pending')
            .map((item) => ({
                lineId: item.lineId,
                sourceShelfId: item.lineId ? lineItemMap.get(item.lineId) : undefined,
            }));
    }

    const updated = approveInternalTransferOverage(id, {
        approved: parsed.data.approved,
        approvedBy: session.user.name || session.user.id,
        lineItems,
    });

    if (!updated) {
        return { error: 'Failed to approve overage.' };
    }

    revalidatePath('/employee/work-tasks');
    revalidatePath('/admin/data/internal-transfers');
    revalidatePath('/admin/data/materials');
    return { success: true, receiptStatus: updated.receiptStatus };
}

const internalTransferShortageResolutionSchema = z.object({
    resolutionType: z.enum(['supplier', 'employee', 'wastage', 'resend']),
    note: z.string().optional(),
});

export async function handleResolveInternalTransferShortage(
    id: string,
    values: z.infer<typeof internalTransferShortageResolutionSchema>
) {
    const session = await getSession();
    if (!session?.user) return { error: 'Unauthorized' };

    const parsed = internalTransferShortageResolutionSchema.safeParse(values);
    if (!parsed.success) {
        return { error: 'Invalid data', details: parsed.error.flatten() };
    }

    const doc = await getInternalTransferDocumentByIdRuntime(id);
    if (!doc || doc.status !== 'active') {
        return { error: 'Document not found or inactive.' };
    }

    ensureInternalTransferLegacyMirror(doc);

    const result = resolveInternalTransferShortage(id, {
        resolutionType: parsed.data.resolutionType,
        note: parsed.data.note,
        resolvedBy: session.user.name || session.user.id,
    });

    if ('error' in result) {
        return result;
    }

    revalidatePath('/admin/data/internal-transfers');
    revalidatePath('/employee/work-tasks');
    return { success: true, journalEntryId: result.journalEntryId, totalValue: result.totalValue };
}

export async function handleCancelInternalTransferDocument(id: string, reason?: string) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const doc = await getInternalTransferDocumentByIdRuntime(id);
    if (!doc || doc.status !== 'active') return { error: 'Not found' };

    ensureInternalTransferLegacyMirror(doc);

    const { getInternalTransferDocuments } = await import('./data');
    const linkedActiveDocs = getInternalTransferDocuments().filter((candidate) => {
        if (candidate.id === doc.id) return false;
        if (candidate.status === 'cancelled') return false;
        const note = String(candidate.note || '');
        return note.includes(doc.transferNumber);
    });

    if (linkedActiveDocs.length > 0) {
        return { error: 'TRANSFER_DOC_HAS_LINKED_ACTIVE_DOCS' };
    }

    const settings = await getSettingsRuntime();
    const now = new Date().toISOString();

    try {
        assertNotLockedByPeriod(now, settings.periodCloseDate, settings.inventoryCloseDate);
    } catch (error: any) {
        return { error: error?.message || 'PERIOD_LOCKED' };
    }

    try {
        const originalMovements = (await getInventoryMovementsRuntime()).filter(
            (mv) => mv.referenceType === 'transfer_document' && mv.referenceId === doc.id
        );

        if (originalMovements.length > 0) {
            const reverseEntries = originalMovements.map((mv, index) => ({
                id: `${doc.id}-cancel-${index + 1}-${Date.now()}`,
                date: now,
                materialId: (mv as any).materialId,
                warehouseId: (mv as any).warehouseId,
                shelfId: (mv as any).shelfId,
                quantityIn: (mv as any).quantityOut || 0,
                quantityOut: (mv as any).quantityIn || 0,
                referenceType: 'transfer_document_cancel',
                referenceId: doc.id,
                shipmentId: (mv as any).shipmentId,
                invoiceId: (mv as any).invoiceId,
                costPerUnitOriginal: (mv as any).costPerUnitOriginal,
            }));

            if (isPostgresProviderEnabled()) {
                await pgSaveInventoryMovements(reverseEntries as Array<Record<string, unknown>>);
            } else {
                addInventoryMovements(reverseEntries.map(({ id, ...rest }) => rest));
            }
        }
    } catch (error: any) {
        return { error: error?.message || 'TRANSFER_DOC_REVERSE_FAILED' };
    }

    try {
        if (doc.shortageJournalEntryId) {
            const journalEntries = await getJournalEntriesRuntime();
            const shortageEntry = journalEntries.find((entry) => entry.id === doc.shortageJournalEntryId);
            if (shortageEntry) {
                const reversingEntry: JournalEntry = {
                    id: nextPrefixedId('je-reverse'),
                    date: now,
                    description: `قيد عكسي لإلغاء سند التحويل ${doc.transferNumber}`,
                    referenceType: 'manual',
                    referenceId: doc.id,
                    lines: shortageEntry.lines.map((line) => ({
                        ...line,
                        debit: line.credit,
                        credit: line.debit,
                    })),
                    createdBy: session.user.name || session.user.id,
                    createdAt: now,
                };
                journalEntries.push(reversingEntry);
                await saveJournalEntriesRuntime(journalEntries);
            }
        }
    } catch (error) {
        console.error('Failed to reverse shortage journal on transfer doc cancel:', error);
    }

    const cancelled = cancelInternalTransferDocument(id, session.user.id, reason);
    if (!cancelled) return { error: 'Not found' };

    if (isPostgresProviderEnabled()) {
        try {
            const cancelledDoc = getInternalTransferDocumentById(id);
            if (cancelledDoc) {
                await pgSaveInternalTransfers([cancelledDoc as unknown as Record<string, unknown>]);
            }
        } catch (error) {
            console.error('Failed to mirror cancelled transfer document to PostgreSQL:', error);
        }
    }

    revalidatePath('/admin/data/internal-transfers');
    revalidatePath('/admin/data/materials');
    return { success: true };
}

export async function handleAcquireTransferLock(values: z.infer<typeof transferLockSchema>) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const parsed = transferLockSchema.safeParse(values);
    if (!parsed.success) {
        return { error: 'Invalid data', details: parsed.error.flatten() };
    }

    const result = acquireTransferLock(
        parsed.data.materialId,
        session.user.id,
        session.user.name || 'admin'
    );

    return result.success
        ? { success: true }
        : { success: false, lockedBy: result.lockedBy || 'unknown' };
}

export async function handleReleaseTransferLock(values: z.infer<typeof transferLockSchema>) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const parsed = transferLockSchema.safeParse(values);
    if (!parsed.success) {
        return { error: 'Invalid data', details: parsed.error.flatten() };
    }

    releaseTransferLock(parsed.data.materialId, session.user.id);
    return { success: true };
}

export async function handleUpdateInternalTransfer(id: string, values: z.infer<typeof updateInternalTransferSchema>) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const parsed = updateInternalTransferSchema.safeParse(values);
    if (!parsed.success) {
        return { error: 'Invalid data', details: parsed.error.flatten() };
    }

    const updated = updateInternalTransfer(id, parsed.data);
    if (!updated) return { error: 'Not found' };

    revalidatePath('/admin/data/internal-transfers');
    revalidatePath('/admin/data/materials');
    return { success: true };
}

export async function handleDeleteInternalTransfer(id: string) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const deleted = deleteInternalTransfer(id);
    if (!deleted) return { error: 'Not found' };

    revalidatePath('/admin/data/internal-transfers');
    revalidatePath('/admin/data/materials');
    return { success: true };
}

const enqueueLargeReportJobSchema = z.object({
    reportName: z.string().min(1),
    filters: z.record(z.any()).optional(),
});

const enqueueArchiveInvoicesJobSchema = z.object({
    months: z.coerce.number().int().min(1).max(120).default(24),
});

export async function handleEnqueueLargeReportJob(values: z.infer<typeof enqueueLargeReportJobSchema>) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const parsed = enqueueLargeReportJobSchema.safeParse(values);
    if (!parsed.success) {
        return { error: 'Invalid data', details: parsed.error.flatten() };
    }

    const job = enqueueBackgroundJob('generate-large-report', {
        reportName: parsed.data.reportName,
        filters: parsed.data.filters || {},
        requestedBy: session.user.name || session.user.id,
    });

    return { success: true, job };
}

export async function handleEnqueueArchiveOldInvoicesJob(values: z.infer<typeof enqueueArchiveInvoicesJobSchema>) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const parsed = enqueueArchiveInvoicesJobSchema.safeParse(values);
    if (!parsed.success) {
        return { error: 'Invalid data', details: parsed.error.flatten() };
    }

    const job = enqueueBackgroundJob('archive-old-invoices', {
        months: parsed.data.months,
        requestedBy: session.user.name || session.user.id,
    });

    return { success: true, job };
}

export async function handleGetBackgroundJobs() {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };
    return { success: true, jobs: getBackgroundJobs() };
}

export async function handleProcessNextBackgroundJob() {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };
    const processed = processNextBackgroundJob();
    return { success: true, processed };
}

type DbMaintenancePayload = {
    files: string[];
    password?: string;
};

const dbRoot = path.join(process.cwd(), 'db');
const backupRoot = path.join(dbRoot, 'backups');

function ensureBackupDir(): string {
    if (!fs.existsSync(backupRoot)) {
        fs.mkdirSync(backupRoot, { recursive: true });
    }
    const stamp = new Date().toISOString().replace(/[:.]/g, '-');
    const dir = path.join(backupRoot, stamp);
    fs.mkdirSync(dir, { recursive: true });
    return dir;
}

function readJsonSafe(fullPath: string): any {
    try {
        const content = fs.readFileSync(fullPath, 'utf-8');
        return content.trim() ? JSON.parse(content) : [];
    } catch {
        return [];
    }
}

const addChartAccountSchema = z.object({
    code: z.string().min(1),
    nameAr: z.string().min(1),
    nameEn: z.string().min(1),
    parentId: z.string().optional(),
    type: z.enum(['account', 'header']).default('account'),
    nature: z.enum(['debit', 'credit']).optional(),
});

const updateChartAccountSchema = z.object({
    id: z.string().min(1),
    code: z.string().min(1),
    nameAr: z.string().min(1),
    nameEn: z.string().min(1),
    parentId: z.string().nullable().optional(),
    type: z.enum(['account', 'header']).default('account'),
    nature: z.enum(['debit', 'credit']).optional(),
});

export async function handleAddChartAccount(payload: z.infer<typeof addChartAccountSchema>) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const parsed = addChartAccountSchema.safeParse(payload);
    if (!parsed.success) return { error: 'INVALID_DATA' };

    const { code, nameAr, nameEn, parentId, type, nature } = parsed.data;
    const accounts = await getChartOfAccountsRuntime();
    let normalizedCode = String(code || '').trim();

    const resolvedParentId = parentId && parentId.trim().length > 0 ? parentId.trim() : null;
    if (resolvedParentId && !accounts.some((acc) => acc.id === resolvedParentId)) {
        return { error: 'PARENT_NOT_FOUND' };
    }

    if (resolvedParentId) {
        const parent = accounts.find((acc) => String(acc?.id || '').trim() === resolvedParentId) as any;
        const parentCode = String(parent?.code || '').trim();
        if (parentCode && normalizedCode !== parentCode && !normalizedCode.startsWith(`${parentCode}-`)) {
            normalizedCode = `${parentCode}-${normalizedCode}`;
        }
    }

    if (accounts.some((acc) => String(acc?.code || '').trim() === normalizedCode)) return { error: 'DUPLICATE_CODE' };

    const accountNature = type === 'account' ? nature || 'debit' : undefined;
    const newAccount = {
        id: normalizedCode,
        code: normalizedCode,
        nameAr,
        nameEn,
        type,
        parentId: resolvedParentId,
        nature: accountNature,
    };

    accounts.push(newAccount as any);
    await saveChartOfAccountsRuntime(accounts);
    revalidatePath('/admin/accounting/chart');
    return { success: true };
}

export async function handleUpdateChartAccount(payload: z.infer<typeof updateChartAccountSchema>) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const parsed = updateChartAccountSchema.safeParse(payload);
    if (!parsed.success) return { error: 'INVALID_DATA' };

    const { id, code, nameAr, nameEn, parentId, type, nature } = parsed.data;
    const normalizedId = String(id || '').trim();
    let normalizedCode = String(code || '').trim();
    const normalizedNameAr = String(nameAr || '').trim();
    const normalizedNameEn = String(nameEn || '').trim();
    const normalizedParentId = parentId && String(parentId).trim().length > 0 ? String(parentId).trim() : null;

    if (!normalizedId || !normalizedCode || !normalizedNameAr || !normalizedNameEn) {
        return { error: 'INVALID_DATA' };
    }

    const accounts = await getChartOfAccountsRuntime();
    const index = accounts.findIndex((acc) => String(acc?.id || '').trim() === normalizedId);
    if (index < 0) return { error: 'ACCOUNT_NOT_FOUND' };

    const duplicateCode = accounts.some((acc, idx) => idx !== index && String(acc?.code || '').trim() === normalizedCode);
    if (duplicateCode) return { error: 'DUPLICATE_CODE' };

    if (normalizedParentId) {
        if (normalizedParentId === normalizedId) return { error: 'INVALID_PARENT' };
        const parentExists = accounts.some((acc) => String(acc?.id || '').trim() === normalizedParentId);
        if (!parentExists) return { error: 'PARENT_NOT_FOUND' };

        const parent = accounts.find((acc) => String(acc?.id || '').trim() === normalizedParentId) as any;
        const parentCode = String(parent?.code || '').trim();
        if (parentCode && normalizedCode !== parentCode && !normalizedCode.startsWith(`${parentCode}-`)) {
            normalizedCode = `${parentCode}-${normalizedCode}`;
        }
    }

    const current = accounts[index] as any;
    const updated = {
        ...current,
        code: normalizedCode,
        nameAr: normalizedNameAr,
        nameEn: normalizedNameEn,
        type,
        parentId: normalizedParentId,
        nature: type === 'account' ? (nature || 'debit') : undefined,
    };

    const nextAccounts = accounts.map((acc, idx) => {
        if (idx !== index) return acc;
        return updated as any;
    });

    await saveChartOfAccountsRuntime(nextAccounts as any[]);
    revalidatePath('/admin/accounting/chart');
    return { success: true };
}

function emptyValueFor(data: any): any {
    if (Array.isArray(data)) return [];
    if (data && typeof data === 'object') return {};
    return [];
}

function writeDatabaseBackup(files: string[]): { backupId?: string; error?: string } {
    const normalizedFiles = files.filter(Boolean);
    if (!normalizedFiles.length) return { error: 'NO_FILES_SELECTED' };

    const backupDir = ensureBackupDir();
    try {
        normalizedFiles.forEach((file) => {
            const src = path.join(dbRoot, file);
            if (!fs.existsSync(src)) return;
            const data = readJsonSafe(src);
            const backupTarget = path.join(backupDir, file);
            fs.writeFileSync(backupTarget, JSON.stringify(data, null, 2), 'utf-8');
        });
        return { backupId: path.basename(backupDir) };
    } catch (error: any) {
        return { error: error?.message || 'BACKUP_FAILED' };
    }
}

export async function handleCreateDatabaseBackup(payload: DbMaintenancePayload) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };
    // Backup-only requires no password, only admin session

    const files = (payload.files || []).filter(Boolean);
    const backupResult = writeDatabaseBackup(files);
    if (backupResult.error) return { error: backupResult.error };
    return { success: true, backupId: backupResult.backupId };
}

export async function handleBackupAndWipeDatabases(payload: DbMaintenancePayload) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };
    const current = await getEmployeeByIdRuntime(session.user.id);
    // Destructive wipe requires password for safety
    if (!current || current.password !== payload.password) return { error: 'INVALID_PASSWORD' };

    const files = (payload.files || []).filter(Boolean);
    if (!files.length) return { error: 'NO_FILES_SELECTED' };

    const backupResult = writeDatabaseBackup(files);
    if (backupResult.error) return { error: backupResult.error };

    try {
        files.forEach((file) => {
            const src = path.join(dbRoot, file);
            if (!fs.existsSync(src)) return;
            const data = readJsonSafe(src);
            const cleared = emptyValueFor(data);
            fs.writeFileSync(src, JSON.stringify(cleared, null, 2), 'utf-8');
        });
        return { success: true, backupId: backupResult.backupId };
    } catch (error: any) {
        return { error: error?.message || 'WIPE_FAILED' };
    }
}

export async function handleRestoreDatabases(payload: { backupId: string; files?: string[]; password: string }) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };
    const current = await getEmployeeByIdRuntime(session.user.id);
    if (!current || current.password !== payload.password) return { error: 'INVALID_PASSWORD' };

    const { backupId } = payload;
    if (!backupId) return { error: 'NO_BACKUP_SELECTED' };
    const backupDir = path.join(backupRoot, backupId);
    if (!fs.existsSync(backupDir)) return { error: 'BACKUP_NOT_FOUND' };

    const files = payload.files && payload.files.length > 0
        ? payload.files
        : fs.readdirSync(backupDir).filter((f) => f.endsWith('.json'));

    try {
        files.forEach((file) => {
            const src = path.join(backupDir, file);
            const dest = path.join(dbRoot, file);
            if (!fs.existsSync(src)) return;
            const data = readJsonSafe(src);
            fs.writeFileSync(dest, JSON.stringify(data, null, 2), 'utf-8');
        });
        return { success: true };
    } catch (error: any) {
        return { error: error?.message || 'RESTORE_FAILED' };
    }
}

// ── Storage Configuration ──

const storageConfigSchema = z.object({
    backupPath: z.string().optional(),
    codePath: z.string().optional(),
    documentsPath: z.string().optional(),
    autoBackupEnabled: z.boolean().optional(),
    autoBackupIntervalHours: z.number().min(1).max(24).optional(),
});

export async function handleGetStorageConfig() {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    try {
        const { readStorageConfig } = await import('./backup-config');
        const config = readStorageConfig();
        return { success: true, config };
    } catch (error: any) {
        return { error: error?.message || 'Failed to read config' };
    }
}

export async function handleUpdateStorageConfig(payload: z.infer<typeof storageConfigSchema>) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { error: 'Unauthorized' };

    const parsed = storageConfigSchema.safeParse(payload);
    if (!parsed.success) return { error: 'INVALID_DATA' };

    try {
        const { updateStorageConfig } = await import('./backup-config');
        const result = updateStorageConfig(parsed.data);
        if (!result.success) return { error: result.error };
        return { success: true, config: result.config };
    } catch (error: any) {
        return { error: error?.message || 'Failed to update config' };
    }
}

async function createPurchaseOrderJournalEntry(
    orderNumber: string,
    supplierId: string,
    supplierName: string,
    totalAmountBase: number,
    taxAmountBase: number,
    discountAmountBase: number,
    amountPaidBase: number,
    createdBy: string,
    opts?: { invoiceId?: string; shipmentId?: string; shipmentType?: ShipmentType; paymentMethods?: any[]; fxRate?: number }
) {
    const accounts = await getChartOfAccountsRuntime();
    const suppliers = await getSuppliersRuntime();
    const { supplier, account: supplierAccount } = await ensureSupplierPostingAccountRuntime({
        supplierId,
        supplierName,
        suppliers: suppliers as Array<Record<string, any>>,
        accounts: accounts as Array<Record<string, any>>,
    });

    // Find relevant accounts
    const purchasesAccount = accounts.find((acc: any) => acc.code === '5110'); // Purchases (مشتريات بضائع)
    const servicePurchasesAccount = accounts.find((acc: any) => acc.code === '5130') || purchasesAccount; // Service purchases
    const nonStockPurchasesAccount = accounts.find((acc: any) => acc.code === '5120') || purchasesAccount; // Non-stock purchases
    const suppliersAccount = supplierAccount;
    const cashAccount = accounts.find((acc: any) => acc.code === '1110'); // الصندوق
    const defaultBankAccount = accounts.find((acc: any) => acc.code === '1120'); // البنك الافتراضي
    const notesReceivableAccount = accounts.find((acc: any) => acc.code === '1140'); // أوراق القبض (شيكات الزبائن)
    const purchaseInputTaxAccount =
        accounts.find((acc: any) => acc.code === '1160')
        || accounts.find((acc: any) => {
            const nameAr = String(acc?.nameAr || '');
            const nameEn = String(acc?.nameEn || '').toLowerCase();
            return acc?.type === 'account' && (
                nameAr.includes('ضريبة مدخلات')
                || nameAr.includes('ضريبة قيمة مضافة مدخلات')
                || nameEn.includes('purchase input vat')
                || nameEn.includes('vat input')
            );
        });

    if (!purchasesAccount || !suppliersAccount) {
        console.warn('Required accounts not found for purchase invoice journal entry');
        return;
    }

    const safeTaxAmountBase = Number.isFinite(taxAmountBase) ? Math.max(0, taxAmountBase) : 0;
    const grossAmountBase = totalAmountBase + safeTaxAmountBase;

    const lines: JournalEntryLine[] = [];

    const pushOrMergeDebitLine = (account: any, amount: number, description: string) => {
        const normalizedAmount = Number(amount || 0);
        if (!Number.isFinite(normalizedAmount) || normalizedAmount <= 0) return;
        const existing = lines.find((line) => line.accountCode === String(account.code || '') && line.description === description);
        if (existing) {
            existing.debit += normalizedAmount;
            return;
        }
        lines.push({
            accountId: account.id,
            accountCode: account.code,
            accountName: account.nameAr,
            debit: normalizedAmount,
            credit: 0,
            description,
        });
    };

    let allocatedBase = 0;
    try {
        const purchaseOrders = await getPurchaseOrdersRuntime();
        const linkedOrder = (purchaseOrders || []).find((entry: any) => (
            String(entry?.id || '') === String(opts?.invoiceId || '')
            || String(entry?.orderNumber || '') === String(orderNumber || '')
        ));

        if (linkedOrder && Array.isArray((linkedOrder as any).items) && (linkedOrder as any).items.length > 0) {
            const materials = await getMaterialsRuntime();
            const materialsById = new Map((materials || []).map((entry: any) => [String(entry.id || ''), entry]));
            const orderItems = (linkedOrder as any).items as Array<Record<string, unknown>>;
            const subTotal = Math.max(0, orderItems.reduce((sum, item) => sum + Math.max(0, Number(item.total || 0)), 0));

            if (subTotal > 0) {
                for (const item of orderItems) {
                    const lineTotal = Math.max(0, Number(item.total || 0));
                    if (!lineTotal) continue;
                    const lineAmountBase = (lineTotal / subTotal) * Math.max(0, Number(totalAmountBase || 0));
                    const material = materialsById.get(String(item.materialId || ''));
                    const itemCategory = String((material as any)?.itemCategory || '').trim();
                    const configuredPurchaseCode = String((material as any)?.purchaseAccountCode || '').trim();
                    const configuredPurchaseAccount = configuredPurchaseCode
                        ? accounts.find((acc: any) => String(acc?.code || '').trim() === configuredPurchaseCode && String(acc?.type || '') === 'account')
                        : null;
                    const targetAccount = configuredPurchaseAccount || (itemCategory === 'service'
                        ? servicePurchasesAccount
                        : itemCategory === 'non_stock'
                            ? nonStockPurchasesAccount
                            : purchasesAccount);
                    pushOrMergeDebitLine(
                        targetAccount,
                        lineAmountBase,
                        configuredPurchaseAccount
                            ? `Purchase Invoice ${orderNumber}`
                            : itemCategory === 'service'
                            ? `Service purchase ${orderNumber}`
                            : itemCategory === 'non_stock'
                                ? `Non-stock purchase ${orderNumber}`
                                : `Purchase Invoice ${orderNumber}`,
                    );
                    allocatedBase += lineAmountBase;
                }
            }
        }
    } catch (error) {
        console.warn('Failed to classify purchase lines by item category, falling back to default account.', error);
    }

    if (lines.length === 0) {
        pushOrMergeDebitLine(purchasesAccount, totalAmountBase, `Purchase Invoice ${orderNumber}`);
        allocatedBase = totalAmountBase;
    }

    const remainderBase = Math.max(0, Number(totalAmountBase || 0) - Number(allocatedBase || 0));
    if (remainderBase > 0.01) {
        pushOrMergeDebitLine(purchasesAccount, remainderBase, `Purchase Invoice ${orderNumber}`);
    }

    if (safeTaxAmountBase > 0) {
        const taxDebitAccount = purchaseInputTaxAccount || purchasesAccount;
        lines.push({
            accountId: taxDebitAccount.id,
            accountCode: taxDebitAccount.code,
            accountName: taxDebitAccount.nameAr,
            debit: safeTaxAmountBase,
            credit: 0,
            description: `Input tax for ${orderNumber}`,
        });
    }

    lines.push({
        accountId: supplierAccount.id,
        accountCode: supplierAccount.code,
        accountName: supplierAccount.nameAr,
        debit: 0,
        credit: grossAmountBase,
        description: `From ${supplierName}`,
    });

    // If there's a payment, break it down by payment method
    if (amountPaidBase > 0) {
        const methodsList: any[] = opts?.paymentMethods || [];
        const fxRate = opts?.fxRate && opts.fxRate > 0 ? opts.fxRate : 1;

        if (methodsList.length > 0) {
            // Process each payment method with its correct settlement account
            for (const method of methodsList) {
                const methodAmount = Number(method.amount || 0);
                if (methodAmount <= 0) continue;
                const methodAmountBase = methodAmount * fxRate;

                // Resolve the settlement (credit) account for this method
                let settlementAccount: any = cashAccount; // default: صندوق 1110

                if (method.method === 'check' && method.checkSource === 'incoming') {
                    // شيك زبون وارد يتم تظهيره للمورد → أوراق القبض 1140
                    if (notesReceivableAccount) {
                        settlementAccount = notesReceivableAccount;
                    }
                } else if (method.method === 'check' || method.method === 'bank_transfer') {
                    // شيك صادر من حساب الشركة أو تحويل بنكي → حساب البنك المحدد في شجرة الحسابات
                    const bankId = method.bankId;
                    if (bankId) {
                        const bank = await getBankByIdForCalc(bankId);
                        if (bank?.accountCode) {
                            const bankAcc = accounts.find((acc: any) => acc.code === bank.accountCode);
                            if (bankAcc) settlementAccount = bankAcc;
                        }
                    }
                    // Fallback to default bank account 1120 if no linked bank account found
                    if (!settlementAccount || settlementAccount?.code === '1110') {
                        if (defaultBankAccount) settlementAccount = defaultBankAccount;
                    }
                }
                // cash → stays with cashAccount 1110

                // Debit supplier to reduce liability
                lines.push({
                    accountId: supplierAccount.id,
                    accountCode: supplierAccount.code,
                    accountName: supplierAccount.nameAr,
                    debit: methodAmountBase,
                    credit: 0,
                    description: `Payment for ${orderNumber}`,
                });

                // Credit settlement account
                if (settlementAccount) {
                    lines.push({
                        accountId: settlementAccount.id,
                        accountCode: settlementAccount.code,
                        accountName: settlementAccount.nameAr,
                        debit: 0,
                        credit: methodAmountBase,
                        description: `Payment for ${orderNumber} (${method.method}${method.checkSource ? ' - ' + (method.checkSource === 'incoming' ? 'شيك زبون' : 'شيك صادر') : ''})`,
                    });
                }
            }
        } else {
            // Fallback: no method details — use cash account for total
            if (cashAccount) {
                lines.push({
                    accountId: supplierAccount.id,
                    accountCode: supplierAccount.code,
                    accountName: supplierAccount.nameAr,
                    debit: amountPaidBase,
                    credit: 0,
                    description: `Payment for ${orderNumber}`,
                });
                lines.push({
                    accountId: cashAccount.id,
                    accountCode: cashAccount.code,
                    accountName: cashAccount.nameAr,
                    debit: 0,
                    credit: amountPaidBase,
                    description: `Payment for ${orderNumber}`,
                });
            }
        }
    }

    const entry: JournalEntry = {
        id: nextPrefixedId('je-purchase'),
        date: new Date().toISOString(),
        description: `Purchase Invoice ${orderNumber} from ${supplierName}`,
        referenceType: 'purchase_order',
        referenceId: orderNumber,
        invoiceId: opts?.invoiceId,
        shipmentId: opts?.shipmentId,
        shipmentType: opts?.shipmentType,
        lines,
        createdBy,
        createdAt: new Date().toISOString(),
    };

    const journalEntries = await getJournalEntriesRuntime();
    journalEntries.unshift(entry);
    await saveJournalEntriesRuntime(journalEntries);
}

// --- Missing exports expected by UI components ---

export async function getUnlinkedPurchaseShipmentsBySupplier(supplierId: string): Promise<any[]> {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return [];

    const allOrders = await getPurchaseOrdersRuntime();
    return allOrders.filter(
        (order: any) =>
            String(order.supplierId || '') === supplierId &&
            order.status === 'active' &&
            !String(order.shipmentId || '').trim()
    );
}

export async function handleGetPurchaseOrderCloneQuantities(poId: string): Promise<
    | {
        success: true;
        orderId: string;
        orderNumber: string;
        supplierId?: string;
        supplierName?: string;
        supplierInvoiceNumber?: string;
                sourcePurchaseDocumentType?: 'shipment' | 'tax_invoice';
        items: Array<{ materialId: string; quantity: number; warehouseId?: string; shelfId?: string }>;
      }
    | { success: false; error: string }
> {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') return { success: false, error: 'Unauthorized' };

    const allOrders = await getPurchaseOrdersRuntime();
    const order = allOrders.find((o: any) => o.id === poId);
    if (!order) return { success: false, error: 'ORDER_NOT_FOUND' };

    const items = ((order as any).items || []).map((item: any) => ({
        materialId: String(item.materialId || ''),
        quantity: Number(item.quantity || 0),
        warehouseId: String(item.warehouseId || '').trim() || undefined,
        shelfId: String(item.shelfId || '').trim() || undefined,
    })).filter((item: any) => item.materialId && item.quantity > 0);

    return {
        success: true,
        orderId: String((order as any).id || poId),
        orderNumber: String((order as any).orderNumber || poId),
        supplierId: String((order as any).supplierId || '').trim() || undefined,
        supplierName: String((order as any).supplierName || '').trim() || undefined,
        supplierInvoiceNumber: String((order as any).supplierInvoiceNumber || '').trim() || undefined,
        sourcePurchaseDocumentType: String((order as any).documentType || 'tax_invoice') === 'shipment' ? 'shipment' : 'tax_invoice',
        items,
    };
}

export async function handleCreateManualPurchaseInventoryEffect(formData: FormData) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') redirect('/login');

    const purchaseOrderId = String(formData.get('purchaseOrderId') || '').trim();
    const returnPath = String(formData.get('returnPath') || '/admin/purchases/history').trim();
    if (!purchaseOrderId) redirect(`${returnPath}?manualInventoryError=missing_order`);

    const allOrders = await getPurchaseOrdersRuntime();
    const order = allOrders.find((o: any) => o.id === purchaseOrderId);
    if (!order) redirect(`${returnPath}?manualInventoryError=not_found`);
    if (String((order as any).status || 'active') !== 'active') {
        redirect(`${returnPath}?manualInventoryError=not_active`);
    }

    const existingMovements = await getInventoryMovementsRuntime();
    const hasPurchaseEffect = existingMovements.some((movement: any) =>
        String(movement?.invoiceId || '').trim() === purchaseOrderId &&
        String(movement?.referenceType || '').trim() === 'purchase_order'
    );
    if (hasPurchaseEffect) redirect(`${returnPath}?manualInventoryError=already_exists`);

    const poItems = ((order as any).items || [])
        .map((item: any) => {
            const materialId = String(item.materialId || '').trim();
            const quantity = Number(item.quantity || 0);
            const warehouseId = String(item.warehouseId || (order as any).warehouseId || '').trim();
            const shelfId = String(item.shelfId || '').trim();
            return {
                materialId,
                quantity,
                warehouseId,
                shelfId,
                unitPrice: Number(item.unitPrice || 0),
            };
        })
        .filter((item: any) => item.materialId && item.quantity > 0 && item.warehouseId);

    if (!poItems.length) redirect(`${returnPath}?manualInventoryError=no_inventory_items`);

    const nowIso = new Date().toISOString();
    const shipment = await createShipmentRuntime({
        shipmentType: 'adjustment',
        date: nowIso,
        invoiceId: purchaseOrderId,
        hasInventoryMovement: true,
    } as any);

    const movements = poItems.map((item: any) => ({
        id: nextPrefixedId('inv-move'),
        date: nowIso,
        materialId: item.materialId,
        warehouseId: item.warehouseId,
        shelfId: item.shelfId || undefined,
        quantityIn: item.quantity,
        quantityOut: 0,
        referenceType: 'purchase_order',
        referenceId: purchaseOrderId,
        shipmentId: shipment.id,
        invoiceId: purchaseOrderId,
        costPerUnitOriginal: item.unitPrice,
    }));

    if (isPostgresProviderEnabled()) {
        await pgSaveInventoryMovements(movements as Array<Record<string, unknown>>);
    } else {
        addInventoryMovements(movements as any);
    }

    revalidatePath('/admin/purchases');
    revalidatePath('/admin/purchases/history');
    revalidatePath(`/admin/purchases/view/${purchaseOrderId}`);
    redirect(`${returnPath}?manualInventoryCreated=1`);
}

const manualJournalEntryLineSchema = z.object({
    accountCode: z.string().trim().min(1),
    debit: z.number().min(0),
    credit: z.number().min(0),
    description: z.string().trim().max(500).optional(),
});

const manualJournalEntrySchema = z.object({
    date: z.string().trim().min(1),
    description: z.string().trim().min(3).max(500),
    lines: z.array(manualJournalEntryLineSchema).min(2),
});

type ManualJournalEntryInput = z.infer<typeof manualJournalEntrySchema>;

export async function handleCreateManualJournalEntry(input: ManualJournalEntryInput) {
    const session = await getSession();
    if (!session?.user) {
        return { success: false, error: 'Unauthorized' as const };
    }

    const settings = await getSettingsRuntime();
    if (!hasEmployeePermission(session.user, settings, 'admin.accounting')) {
        return { success: false, error: 'Unauthorized' as const };
    }

    const parsed = manualJournalEntrySchema.safeParse(input);
    if (!parsed.success) {
        return { success: false, error: 'INVALID_INPUT' as const };
    }

    const chart = await getChartOfAccountsRuntime();
    const activeAccountsByCode = new Map(
        (chart || [])
            .filter((account: any) => String(account?.type || '') === 'account' && !Boolean(account?.inactive))
            .map((account: any) => [String(account.code || '').trim(), account]),
    );

    const normalizedLines: JournalEntryLine[] = [];
    let totalDebit = 0;
    let totalCredit = 0;

    for (const line of parsed.data.lines) {
        const accountCode = String(line.accountCode || '').trim();
        const account = activeAccountsByCode.get(accountCode);
        if (!account) {
            return { success: false, error: `ACCOUNT_NOT_FOUND:${accountCode}` as const };
        }

        const debit = Number(line.debit || 0);
        const credit = Number(line.credit || 0);
        const safeDebit = Number.isFinite(debit) ? Math.max(0, Number(debit.toFixed(6))) : 0;
        const safeCredit = Number.isFinite(credit) ? Math.max(0, Number(credit.toFixed(6))) : 0;

        if (safeDebit <= 0 && safeCredit <= 0) {
            return { success: false, error: 'LINE_AMOUNT_REQUIRED' as const };
        }
        if (safeDebit > 0 && safeCredit > 0) {
            return { success: false, error: 'LINE_DEBIT_AND_CREDIT_NOT_ALLOWED' as const };
        }

        totalDebit += safeDebit;
        totalCredit += safeCredit;

        normalizedLines.push({
            accountId: String(account.id || account.code || '').trim() || accountCode,
            accountCode,
            accountName: String(account.nameAr || account.nameEn || accountCode),
            debit: safeDebit,
            credit: safeCredit,
            description: String(line.description || '').trim() || parsed.data.description,
        });
    }

    if (Math.abs(totalDebit - totalCredit) > 0.01) {
        return { success: false, error: 'ENTRY_NOT_BALANCED' as const };
    }

    const normalizedDate = (() => {
        const raw = String(parsed.data.date || '').trim();
        const dateOnly = raw.match(/^(\d{4})-(\d{2})-(\d{2})$/);
        if (dateOnly) {
            return `${dateOnly[1]}-${dateOnly[2]}-${dateOnly[3]}T12:00:00.000Z`;
        }
        const dt = new Date(raw);
        if (Number.isNaN(dt.getTime())) return new Date().toISOString();
        return dt.toISOString();
    })();

    const now = new Date().toISOString();
    const entry: JournalEntry = {
        id: nextPrefixedId('JED'),
        date: normalizedDate,
        description: parsed.data.description,
        status: 'draft',
        referenceType: 'manual',
        referenceId: `manual-${Date.now()}`,
        lines: normalizedLines,
        createdBy: session.user.name || session.user.id,
        createdAt: now,
    };

    const entries = await getJournalEntriesRuntime();
    entries.unshift(entry);
    await saveJournalEntriesRuntime(entries);

    revalidatePath('/admin/accounting/entries');

    return { success: true as const, entryId: entry.id };
}

export async function handleDuplicatePurchaseOrderFromHistory(formData: FormData) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') redirect('/login');

    const sourceOrderId = String(formData.get('sourceOrderId') || '').trim();
    const returnPath = String(formData.get('returnPath') || '/admin/purchases/history').trim();
    if (!sourceOrderId) redirect(`${returnPath}?duplicateError=missing_source`);

    const allOrders = await getPurchaseOrdersRuntime();
    const source = allOrders.find((o: any) => String(o.id || '').trim() === sourceOrderId);
    if (!source) redirect(`${returnPath}?duplicateError=not_found`);

    const sourceItems = Array.isArray((source as any).items) ? (source as any).items : [];
    if (sourceItems.length === 0) redirect(`${returnPath}?duplicateError=no_items`);

    const copiedItems = sourceItems
        .map((item: any) => {
            const quantity = Number(item.quantity || 0);
            const unitPrice = Number(item.unitPrice || 0);
            const lineDiscountAmount = Number(item.lineDiscountAmount || item.lineDiscount || 0);
            const gross = quantity * unitPrice;
            const total = Number(item.total || Math.max(0, gross - lineDiscountAmount));
            return {
                materialId: String(item.materialId || '').trim(),
                name: String(item.name || item.materialName || item.materialId || '').trim(),
                quantity,
                unitPrice,
                total,
                lineDiscountPercent: Number(item.lineDiscountPercent || 0),
                lineDiscountAmount,
                lineDiscount: lineDiscountAmount,
                bonus: Number(item.bonus || 0),
                warehouseId: String(item.warehouseId || '').trim(),
                shelfId: String(item.shelfId || '').trim(),
                taxRate: Number(item.taxRate || 0),
                taxAmount: Number(item.taxAmount || 0),
                realEstateProjectId: String(item.realEstateProjectId || '').trim(),
                realEstateProjectName: String(item.realEstateProjectName || '').trim(),
                realEstateScope: item.realEstateScope,
                realEstateFloorLabel: String(item.realEstateFloorLabel || '').trim(),
                realEstatePartLabel: String(item.realEstatePartLabel || '').trim(),
                realEstateAllocationMethod: item.realEstateAllocationMethod,
            };
        })
        .filter((item: any) => item.materialId && item.quantity > 0);

    if (copiedItems.length === 0) redirect(`${returnPath}?duplicateError=no_items`);

    const subTotal = copiedItems.reduce((sum: number, item: any) => sum + Number(item.total || 0), 0);
    const taxAmount = Number((source as any).taxAmount || 0);
    const grandTotal = Number((source as any).grandTotal || (subTotal + taxAmount));

    const createResult = await handleCreatePurchaseOrder({
        supplierId: String((source as any).supplierId || '').trim(),
        supplierName: String((source as any).supplierName || '').trim(),
        supplierInvoiceNumber: '',
        supplierInvoiceDate: String((source as any).supplierInvoiceDate || '').trim(),
        currencyCode: String((source as any).currencyCode || 'USD').trim(),
        baseCurrencyCode: String((source as any).baseCurrencyCode || (source as any).currencyCode || 'USD').trim(),
        exchangeRate: Number((source as any).exchangeRate || 1),
        rateDate: String((source as any).rateDate || (source as any).date || new Date().toISOString().slice(0, 10)).trim(),
        rateSource: String((source as any).rateSource || '').trim(),
        isAutoRate: Boolean((source as any).isAutoRate ?? true),
        warehouseId: String((source as any).warehouseId || '').trim(),
        realEstateLinkMode: (source as any).realEstateLinkMode || 'none',
        realEstateProjectId: String((source as any).realEstateProjectId || '').trim(),
        realEstateProjectName: String((source as any).realEstateProjectName || '').trim(),
        realEstateScope: (source as any).realEstateScope || 'project',
        realEstateFloorLabel: String((source as any).realEstateFloorLabel || '').trim(),
        realEstatePartLabel: String((source as any).realEstatePartLabel || '').trim(),
        realEstateAllocationMethod: (source as any).realEstateAllocationMethod || 'area',
        allowDuplicateInvoice: true,
        documents: [],
        items: copiedItems,
        subTotal,
        invoiceDiscountPercent: Number((source as any).invoiceDiscountPercent || 0),
        invoiceDiscountAmount: Number((source as any).invoiceDiscountAmount || 0),
        taxMethod: (source as any).taxMethod || 'tax-inclusive',
        postingType: 'draft',
        purchaseTransferCreationMode: 'none',
        invoiceTaxRate: Number((source as any).invoiceTaxRate || 0),
        taxAmount,
        grandTotal,
        amountPaid: 0,
        notes: `نسخة من ${String((source as any).orderNumber || sourceOrderId)}`,
        paymentMethods: [],
        amountDue: grandTotal,
    });

    if (!createResult || (createResult as any).error) {
        redirect(`${returnPath}?duplicateError=${encodeURIComponent(String((createResult as any)?.error || 'create_failed'))}`);
    }

    const createdOrderNumber = String((createResult as any).orderNumber || '').trim();
    if (createdOrderNumber) {
        redirect(`/admin/purchases/history?search=${encodeURIComponent(createdOrderNumber)}`);
    }

    redirect('/admin/purchases/history');
}

export async function handleCreateWorkTaskFromPurchaseOrder(formData: FormData) {
    const session = await getSession();
    if (!session?.user || session.user.role !== 'admin') redirect('/login');

    const purchaseOrderId = String(formData.get('purchaseOrderId') || '').trim();
    const cancelledTransferDocId = String(formData.get('cancelledTransferDocId') || '').trim();
    const returnPath = String(formData.get('returnPath') || '/admin/purchases/history').trim();

    if (!purchaseOrderId) redirect(`${returnPath}?workTaskError=missing_order`);

    const allOrders = await getPurchaseOrdersRuntime();
    const order = allOrders.find((o: any) => o.id === purchaseOrderId);
    if (!order) redirect(`${returnPath}?workTaskError=not_found`);

    const poItems: Array<{ materialId: string; quantity: number; warehouseId?: string; shelfId?: string }> =
        ((order as any).items || [])
            .map((item: any) => ({
                materialId: String(item.materialId || ''),
                quantity: Number(item.quantity || 0),
                warehouseId: String(item.warehouseId || '').trim() || undefined,
                shelfId: String(item.shelfId || '').trim() || undefined,
            }))
            .filter((item: any) => item.materialId && item.quantity > 0);

    if (!poItems.length) redirect(`${returnPath}?workTaskError=no_items`);

    const lockResult = ensureTransferLocks(
        poItems.map((item) => item.materialId),
        session.user.id,
        session.user.name || 'admin'
    );
    if (!lockResult.success) {
        redirect(`${returnPath}?workTaskError=locked&lockedBy=${encodeURIComponent(lockResult.lockedBy || '')}`);
    }

    const cancelledNote = cancelledTransferDocId ? `[source-cancelled:${cancelledTransferDocId}]` : '';
    const noteText = `مهمة عمل لفاتورة مشتريات ${(order as any).orderNumber || purchaseOrderId}${cancelledNote ? ' ' + cancelledNote : ''}`;

    const transferItems = poItems.map((item, index) => ({
        lineId: `po-${(order as any).orderNumber || 'new'}-${index + 1}`,
        materialId: item.materialId,
        quantity: item.quantity,
        fromWarehouseId: item.warehouseId || '',
        fromShelfId: item.shelfId || '',
        toWarehouseId: item.warehouseId || '',
        toShelfId: item.shelfId || '',
        receivedQuantity: 0,
    }));

    const payload = {
        date: new Date().toISOString(),
        enableWarehouseTransfer: false,
        enableShelfTransfer: false,
        allowZeroItems: false,
        supplierId: String((order as any).supplierId || '') || undefined,
        supplierName: String((order as any).supplierName || '') || undefined,
        sourcePurchaseOrderId: purchaseOrderId,
        sourcePurchaseOrderNumber: String((order as any).orderNumber || '') || undefined,
        items: transferItems,
        note: noteText,
        receiptStatus: 'pending' as const,
        createdBy: session.user.name || 'admin',
    };

    try {
        const { addInternalTransferDocument: addDoc } = await import('./data');
        addDoc(payload as any);
    } catch {
        redirect(`${returnPath}?workTaskError=create_failed`);
    }

    revalidatePath('/admin/data/internal-transfers');
    revalidatePath(`/admin/purchases/view/${purchaseOrderId}`);
    redirect(`${returnPath}?workTaskCreated=1`);
}

// ---------------------------------------------------------------------------
// Bulk Material Import — single lock, single JSON read/write for N rows
// ---------------------------------------------------------------------------
type BulkImportRow = {
    rowNumber: number;
    payload: Record<string, unknown>;
    existingItemId?: string;
};

type BulkImportRowResult = {
    rowNumber: number;
    success: boolean;
    itemNumber?: string;
    error?: string;
};

export async function handleBulkImportMaterials(
    rows: BulkImportRow[]
): Promise<{ results: BulkImportRowResult[]; revalidated: boolean }> {
    const session = await getSession();
    const role = session?.user?.role;
    if (!session?.user || (role !== 'admin' && role !== 'pos')) {
        return { results: [], revalidated: false };
    }

    if (!rows || rows.length === 0) {
        return { results: [], revalidated: false };
    }

    // Collect any unit descriptions that need to be ensured before acquiring lock
    const allUnitDescriptions = new Set<string>();
    for (const row of rows) {
        if (row.existingItemId) continue; // updates don't create units
        const parsed = materialItemSchema.safeParse(row.payload);
        if (parsed.success) {
            for (const desc of collectMaterialUnitDescriptions(parsed.data)) {
                allUnitDescriptions.add(desc);
            }
        }
    }
    for (const desc of allUnitDescriptions) {
        await ensureManagedUnitRuntime(desc);
    }

    const results: BulkImportRowResult[] = [];

    if (isPostgresProviderEnabled()) {
        // Postgres: process each row sequentially (no file lock needed)
        for (const row of rows) {
            try {
                if (row.existingItemId) {
                    const parsed = materialItemSchema.safeParse(row.payload);
                    if (!parsed.success) {
                        results.push({ rowNumber: row.rowNumber, success: false, error: 'بيانات غير صالحة.' });
                        continue;
                    }
                    await pgUpdateMaterial(row.existingItemId, normalizeMaterialUnitPayload(parsed.data as any) as any);
                    results.push({ rowNumber: row.rowNumber, success: true, itemNumber: row.existingItemId });
                } else {
                    const parsed = materialItemSchema.safeParse(row.payload);
                    if (!parsed.success) {
                        results.push({ rowNumber: row.rowNumber, success: false, error: 'بيانات غير صالحة.' });
                        continue;
                    }
                    const normalized = normalizeMaterialUnitPayload(parsed.data as any) as any;
                    const nowId = String(normalized.id || normalized.itemNumber || nextPrefixedId('mat'));
                    const created = await pgCreateMaterial({ ...normalized, id: nowId, itemNumber: String(normalized.itemNumber || nowId) });
                    results.push({ rowNumber: row.rowNumber, success: true, itemNumber: String((created as any)?.itemNumber || nowId) });
                }
            } catch (e: any) {
                results.push({ rowNumber: row.rowNumber, success: false, error: e?.message || 'فشل الاستيراد.' });
            }
        }
    } else {
        // JSON file DB: acquire lock ONCE for all rows
        const { addMaterial, updateMaterial } = await import('./data');
        // Use withDbLock via a wrapper that processes all rows inside a single lock context
        const { withDbLock: lockFn } = await import('./data') as any;
        if (typeof lockFn === 'function') {
            lockFn(() => {
                for (const row of rows) {
                    try {
                        if (row.existingItemId) {
                            const parsed = materialItemSchema.safeParse(row.payload);
                            if (!parsed.success) {
                                results.push({ rowNumber: row.rowNumber, success: false, error: 'بيانات غير صالحة.' });
                                continue;
                            }
                            const ok = updateMaterial(row.existingItemId, normalizeMaterialUnitPayload(parsed.data as any) as any);
                            results.push({ rowNumber: row.rowNumber, success: !!ok, itemNumber: ok ? row.existingItemId : undefined });
                        } else {
                            const parsed = materialItemSchema.safeParse(row.payload);
                            if (!parsed.success) {
                                results.push({ rowNumber: row.rowNumber, success: false, error: 'بيانات غير صالحة.' });
                                continue;
                            }
                            const created = addMaterial(normalizeMaterialUnitPayload(parsed.data as any) as any);
                            results.push({ rowNumber: row.rowNumber, success: true, itemNumber: String(created?.itemNumber || created?.id || '') });
                        }
                    } catch (e: any) {
                        results.push({ rowNumber: row.rowNumber, success: false, error: e?.message || 'فشل الاستيراد.' });
                    }
                }
            });
        } else {
            // Fallback: sequential calls (withDbLock not exported — each call acquires own lock)
            for (const row of rows) {
                try {
                    if (row.existingItemId) {
                        const parsed = materialItemSchema.safeParse(row.payload);
                        if (!parsed.success) {
                            results.push({ rowNumber: row.rowNumber, success: false, error: 'بيانات غير صالحة.' });
                            continue;
                        }
                        const ok = updateMaterial(row.existingItemId, normalizeMaterialUnitPayload(parsed.data as any) as any);
                        results.push({ rowNumber: row.rowNumber, success: !!ok, itemNumber: ok ? row.existingItemId : undefined });
                    } else {
                        const parsed = materialItemSchema.safeParse(row.payload);
                        if (!parsed.success) {
                            results.push({ rowNumber: row.rowNumber, success: false, error: 'بيانات غير صالحة.' });
                            continue;
                        }
                        const created = addMaterial(normalizeMaterialUnitPayload(parsed.data as any) as any);
                        results.push({ rowNumber: row.rowNumber, success: true, itemNumber: String(created?.itemNumber || created?.id || '') });
                    }
                } catch (e: any) {
                    results.push({ rowNumber: row.rowNumber, success: false, error: e?.message || 'فشل الاستيراد.' });
                }
            }
        }
    }

    revalidatePath('/admin/data/materials');
    return { results, revalidated: true };
}

type SmartAlternativeSuggestInput = {
    currentItemId?: string;
    name?: string;
    itemSymbolName?: string;
    globalReferenceNumber?: string;
    additionalDetails?: string;
    limit?: number;
};

type SmartAlternativeSuggestion = {
    id: string;
    name: string;
    itemNumber?: string;
    itemSymbolName?: string;
    globalReferenceNumber?: string;
    additionalDetails?: string;
    score: number;
    reason: string;
};

function normalizeSmartAltText(value: string): string {
    return String(value || '')
        .toLowerCase()
        .replace(/[\u064B-\u065F\u0670\u06D6-\u06ED]/g, '')
        .replace(/[إأآٱ]/g, 'ا')
        .replace(/ى/g, 'ي')
        .replace(/ؤ/g, 'و')
        .replace(/ئ/g, 'ي')
        .replace(/ة/g, 'ه')
        .replace(/\s+/g, '')
        .replace(/[^\p{L}\p{N}]+/gu, '');
}

function toSmartAltBigrams(value: string): Set<string> {
    const source = normalizeSmartAltText(value);
    if (source.length < 2) return new Set<string>(source ? [source] : []);
    const grams = new Set<string>();
    for (let index = 0; index < source.length - 1; index += 1) {
        grams.add(source.slice(index, index + 2));
    }
    return grams;
}

function calcSmartAltSimilarity(left: string, right: string): number {
    const a = normalizeSmartAltText(left);
    const b = normalizeSmartAltText(right);
    if (!a || !b) return 0;
    if (a === b) return 1;

    const shorter = a.length <= b.length ? a : b;
    const longer = a.length > b.length ? a : b;
    if (longer.includes(shorter) && shorter.length >= 3) {
        const ratio = shorter.length / longer.length;
        return ratio >= 0.7 ? ratio : 0;
    }

    const gramsA = toSmartAltBigrams(a);
    const gramsB = toSmartAltBigrams(b);
    if (gramsA.size === 0 || gramsB.size === 0) return 0;

    let intersection = 0;
    gramsA.forEach((gram) => {
        if (gramsB.has(gram)) intersection += 1;
    });
    const union = gramsA.size + gramsB.size - intersection;
    return union > 0 ? (intersection / union) : 0;
}

function hasSmartAltDetailsPartMatch(sourceText: string, targetText: string): boolean {
    const source = normalizeSmartAltText(sourceText);
    const target = normalizeSmartAltText(targetText);
    if (!source || !target) return false;
    const tokens = source.split(/\s+/).map((token) => token.trim()).filter((token) => token.length >= 4);
    return tokens.some((token) => target.includes(token));
}

export async function handleSuggestMaterialAlternatives(input: SmartAlternativeSuggestInput): Promise<{ suggestions: SmartAlternativeSuggestion[] }> {
    const session = await getSession();
    if (!session?.user) {
        return { suggestions: [] };
    }

    const currentItemId = String(input.currentItemId || '').trim();
    const currentName = String(input.name || '').trim();
    const currentSymbol = String(input.itemSymbolName || '').trim();
    const currentGlobalReference = String(input.globalReferenceNumber || '').trim();
    const currentDetails = String(input.additionalDetails || '').trim();
    const limit = Math.min(100, Math.max(10, Number(input.limit || 30)));

    const materialRows: Array<Record<string, unknown>> = isPostgresProviderEnabled()
        ? (await pgQuery<{ raw: Record<string, unknown> }>('SELECT raw FROM materials')).rows.map((row) => row.raw)
        : (getMaterials() as unknown as Array<Record<string, unknown>>);

    const suggestions = materialRows
        .filter((candidate) => {
            const id = String(candidate.id || '').trim();
            if (!id) return false;
            if (currentItemId && id === currentItemId) return false;
            return true;
        })
        .map((candidate) => {
            const candidateName = String(candidate.name || '').trim();
            const candidateSymbol = String(candidate.itemSymbolName || '').trim();
            const candidateGlobalReference = String(candidate.globalReferenceNumber || '').trim();
            const candidateDetails = String(candidate.additionalDetails || '').trim();

            const nameScore = calcSmartAltSimilarity(currentName, candidateName);
            const symbolScore = calcSmartAltSimilarity(currentSymbol, candidateSymbol);
            const globalReferenceScore = calcSmartAltSimilarity(currentGlobalReference, candidateGlobalReference);
            let detailsScore = calcSmartAltSimilarity(currentDetails, candidateDetails);
            if (!detailsScore && (
                hasSmartAltDetailsPartMatch(`${currentName} ${currentSymbol} ${currentGlobalReference} ${currentDetails}`, candidateDetails)
                || hasSmartAltDetailsPartMatch(candidateDetails, `${currentName} ${currentSymbol} ${currentGlobalReference} ${currentDetails}`)
            )) {
                detailsScore = 0.7;
            }

            const maxScore = Math.max(nameScore, symbolScore, globalReferenceScore, detailsScore);
            if (maxScore < 0.7) return null;

            const reason = nameScore >= symbolScore && nameScore >= globalReferenceScore && nameScore >= detailsScore
                ? 'تطابق في اسم الصنف'
                : (symbolScore >= globalReferenceScore && symbolScore >= detailsScore
                    ? 'تطابق في اسم الرمز'
                    : (globalReferenceScore >= detailsScore
                        ? 'تطابق في الرقم المرجعي العالمي'
                        : 'تطابق في التفاصيل'));

            return {
                id: String(candidate.id || ''),
                name: candidateName,
                itemNumber: String(candidate.itemNumber || ''),
                itemSymbolName: candidateSymbol,
                globalReferenceNumber: candidateGlobalReference,
                additionalDetails: candidateDetails,
                score: maxScore,
                reason,
            } as SmartAlternativeSuggestion;
        })
        .filter((entry): entry is SmartAlternativeSuggestion => !!entry)
        .sort((a, b) => b.score - a.score)
        .slice(0, limit);

    return { suggestions };
}
