import { NextRequest, NextResponse } from 'next/server';
import { getSession } from '@/lib/auth';
import { randomUUID } from 'crypto';
import { getSalesInvoiceService, createSalesReturnService } from '@/lib/modules/sales';
import {
  pgCreateCustomer,
  pgGetChartOfAccounts,
  pgGetCustomers,
  pgGetInvoices,
  pgGetMaterialStockLocations,
  pgGetMaterials,
  pgNextNamedSequence,
  pgGetSettings,
  pgSaveChartOfAccounts,
  pgSaveCustomers,
  pgSaveInventoryMovements,
  pgSaveInvoices,
} from '@/lib/postgres/data-access';

const VALID_STATUSES = ['pending', 'confirmed', 'shipped', 'delivered', 'cancelled'];

const ALLOWED_TRANSITIONS: Record<string, string[]> = {
  pending: ['confirmed', 'cancelled'],
  confirmed: ['shipped', 'cancelled'],
  shipped: ['delivered', 'cancelled'],
  delivered: ['pending', 'cancelled'],
  cancelled: ['pending'],
};

function parseCustomerFromNotes(notes: string) {
  const result = { name: '', address: '', phone: '' };
  const parts = String(notes || '').split('|').map((part) => part.trim());
  for (const part of parts) {
    if (part.startsWith('اسم:')) result.name = part.replace('اسم:', '').trim();
    else if (part.startsWith('عنوان:')) result.address = part.replace('عنوان:', '').trim();
    else if (part.startsWith('جوال:')) result.phone = part.replace('جوال:', '').trim();
  }
  return result;
}

function normalizePhoneDigits(value: string): string {
  const digits = String(value || '').replace(/\D/g, '');
  if (!digits) return '';
  if (digits.startsWith('00')) return digits.slice(2);
  return digits;
}

function arePhonesEquivalent(left: string, right: string): boolean {
  const a = normalizePhoneDigits(left);
  const b = normalizePhoneDigits(right);
  if (!a || !b) return false;
  if (a === b) return true;

  // Fallback comparison to handle country-code variations.
  if (a.length >= 8 && b.length >= 8) {
    const aTail = a.slice(-8);
    const bTail = b.slice(-8);
    return aTail === bTail;
  }

  return false;
}

function normalizeCustomerName(value: string): string {
  return String(value || '')
    .trim()
    .toLowerCase()
    .replace(/[\u064B-\u065F\u0670]/g, '')
    .replace(/[أإآٱ]/g, 'ا')
    .replace(/[ؤ]/g, 'و')
    .replace(/[ئىئ]/g, 'ي')
    .replace(/[ة]/g, 'ه')
    .replace(/[^a-z0-9\u0600-\u06FF\s]/g, ' ')
    .replace(/\s+/g, ' ')
    .trim();
}

function diceCoefficient(left: string, right: string): number {
  if (!left || !right) return 0;
  if (left === right) return 1;
  if (left.length < 2 || right.length < 2) return 0;

  const leftBigrams = new Map<string, number>();
  for (let i = 0; i < left.length - 1; i += 1) {
    const key = left.slice(i, i + 2);
    leftBigrams.set(key, (leftBigrams.get(key) || 0) + 1);
  }

  let overlap = 0;
  for (let i = 0; i < right.length - 1; i += 1) {
    const key = right.slice(i, i + 2);
    const count = leftBigrams.get(key) || 0;
    if (count > 0) {
      overlap += 1;
      leftBigrams.set(key, count - 1);
    }
  }

  return (2 * overlap) / (left.length + right.length - 2);
}

function areNamesSimilar(leftName: string, rightName: string): boolean {
  const left = normalizeCustomerName(leftName);
  const right = normalizeCustomerName(rightName);
  if (!left || !right) return false;
  if (left === right) return true;

  if (left.length >= 6 && right.length >= 6) {
    if (left.includes(right) || right.includes(left)) return true;
    const similarity = diceCoefficient(left.replace(/\s+/g, ''), right.replace(/\s+/g, ''));
    if (similarity >= 0.88) return true;
  }

  return false;
}

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

  for (const account of accounts) {
    const code = String((account as any)?.code || '').trim();
    const match = code.match(pattern);
    if (!match) continue;
    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 ensureStoreCustomerSubAccountCode(customerName: string): Promise<string> {
  const accountsResult = await pgGetChartOfAccounts({ page: 1, pageSize: 10000 });
  const accounts = ((accountsResult.items || []) as Array<Record<string, unknown>>).map((entry) => ({ ...entry }));
  let changed = false;

  let parent = accounts.find((entry) => String((entry as any)?.code || '').trim() === '1130');
  if (!parent) {
    parent = {
      id: '1130',
      code: '1130',
      nameAr: 'العملاء',
      nameEn: 'Customers',
      type: 'account',
      parentId: '1100',
      nature: 'debit',
    };
    accounts.push(parent);
    changed = true;
  }

  const normalizedName = String(customerName || '').trim() || 'عميل متجر';
  const parentId = String((parent as any)?.id || '1130').trim();
  const existingByName = accounts.find((entry) => {
    if (String((entry as any)?.type || '').trim() !== 'account') return false;
    if (String((entry as any)?.parentId || '').trim() !== parentId) return false;
    return String((entry as any)?.nameAr || '').trim() === normalizedName;
  });

  if (existingByName) {
    if (changed) {
      await pgSaveChartOfAccounts(accounts);
    }
    return String((existingByName as any)?.code || '').trim();
  }

  const usedCodes = new Set(accounts.map((entry) => String((entry as any)?.code || '').trim()).filter(Boolean));
  let candidate = '';
  for (let attempt = 0; attempt < 40; attempt += 1) {
    const nextSequence = await pgNextNamedSequence('coa-customer-sub');
    const nextCode = `1130-${String(nextSequence).padStart(3, '0')}`;
    if (!usedCodes.has(nextCode)) {
      candidate = nextCode;
      break;
    }
  }
  if (!candidate) {
    candidate = allocateChildAccountCode(accounts, '1130');
  }

  accounts.push({
    id: candidate,
    code: candidate,
    nameAr: normalizedName,
    nameEn: normalizedName,
    type: 'account',
    parentId,
    nature: 'debit',
  });

  await pgSaveChartOfAccounts(accounts);
  return candidate;
}

async function ensureStoreCustomer(params: { name: string; phone: string; address: string }) {
  const customersResult = await pgGetCustomers({ page: 1, pageSize: 5000 });
  const customers = (customersResult.items || []) as Array<Record<string, unknown>>;
  const normalizedPhone = String(params.phone || '').trim();
  const normalizedName = String(params.name || '').trim();

  const byPhone = customers.find((entry) =>
    normalizedPhone ? arePhonesEquivalent(String(entry.phone || ''), normalizedPhone) : false
  );

  const byExactName = byPhone
    ? undefined
    : customers.find((entry) =>
        normalizeCustomerName(String(entry.name || '')) === normalizeCustomerName(normalizedName)
      );

  const bySimilarName = byPhone || byExactName
    ? undefined
    : customers.find((entry) =>
        areNamesSimilar(String(entry.name || ''), normalizedName)
      );

  const existing = byPhone || byExactName || bySimilarName;
  if (existing?.id) {
    const existingPhone = String(existing.phone || '').trim();
    const existingAddress = String(existing.address || '').trim();
    const existingAccountCode = String(existing.accountCode || '').trim();
    const incomingPhone = String(params.phone || '').trim();
    const incomingAddress = String(params.address || '').trim();
    const requiresDedicatedAccount = !existingAccountCode || existingAccountCode === '1130';
    const dedicatedAccountCode = requiresDedicatedAccount
      ? await ensureStoreCustomerSubAccountCode(String(existing.name || params.name || '').trim())
      : existingAccountCode;

    // Keep customer master data richer without forcing overwrites.
    if ((!existingPhone && incomingPhone) || (!existingAddress && incomingAddress) || dedicatedAccountCode !== existingAccountCode) {
      await pgSaveCustomers([
        {
          ...existing,
          phone: existingPhone || incomingPhone,
          address: existingAddress || incomingAddress,
          accountCode: dedicatedAccountCode,
          updatedAt: new Date().toISOString(),
        },
      ]);
    }

    return String(existing.id);
  }

  const customerAccountCode = await ensureStoreCustomerSubAccountCode(String(params.name || '').trim());
  const created = await pgCreateCustomer({
    id: `cust-store-${randomUUID()}`,
    customerNumber: `CUS-STORE-${Date.now()}`,
    name: String(params.name || 'عميل متجر').trim() || 'عميل متجر',
    phone: String(params.phone || '').trim(),
    address: String(params.address || '').trim(),
    category: 'store',
    accountCode: customerAccountCode,
    creditLimit: 0,
    createdAt: new Date().toISOString(),
    updatedAt: new Date().toISOString(),
  });

  const customerId = String((created as any)?.id || '').trim();
  if (!customerId) {
    throw new Error('تعذر إنشاء عميل المتجر');
  }
  return customerId;
}

function applyLocationOverrides(
  items: any[],
  locationOverrides?: Array<{ index: number; warehouseId?: string; shelfId?: string }>
) {
  const overridesByIndex = new Map(
    (locationOverrides || [])
      .filter((entry) => Number.isInteger(entry?.index) && entry.index >= 0)
      .map((entry) => [entry.index, entry])
  );

  return items.map((entry, index) => {
    const override = overridesByIndex.get(index);
    if (!override) return entry;
    return {
      ...entry,
      warehouseId: String(override.warehouseId || entry.warehouseId || '').trim(),
      shelfId: String(override.shelfId || entry.shelfId || '').trim(),
    };
  });
}

function applyLineAllocations(
  items: any[],
  lineAllocations?: Array<{
    index: number;
    allocations?: Array<{ warehouseId?: string; shelfId?: string; quantity?: number }>;
  }>
) {
  const allocationsByIndex = new Map(
    (lineAllocations || [])
      .filter((entry) => Number.isInteger(entry?.index) && entry.index >= 0)
      .map((entry) => [entry.index, Array.isArray(entry.allocations) ? entry.allocations : []])
  );

  const expanded: any[] = [];

  items.forEach((item, index) => {
    const allocations = allocationsByIndex.get(index) || [];
    if (allocations.length === 0) {
      expanded.push(item);
      return;
    }

    const cleaned = allocations
      .map((entry) => ({
        warehouseId: String(entry?.warehouseId || '').trim(),
        shelfId: String(entry?.shelfId || '').trim(),
        quantity: Number(entry?.quantity || 0),
      }))
      .filter((entry) => entry.warehouseId && entry.shelfId && Number.isFinite(entry.quantity) && entry.quantity > 0);

    if (cleaned.length === 0) {
      expanded.push(item);
      return;
    }

    const requestedQty = Number(item?.quantity || 0);
    const allocatedQty = cleaned.reduce((sum, entry) => sum + entry.quantity, 0);
    if (Math.abs(allocatedQty - requestedQty) > 0.0001) {
      throw new Error(`مجموع توزيع الرفوف للصنف ${String(item?.materialName || item?.name || item?.materialId || '').trim()} يجب أن يساوي الكمية المطلوبة`);
    }

    for (const entry of cleaned) {
      expanded.push({
        ...item,
        quantity: entry.quantity,
        warehouseId: entry.warehouseId,
        shelfId: entry.shelfId,
      });
    }
  });

  return expanded;
}

async function prepareStoreOrderPosting(params: {
  order: Record<string, any>;
  userId: string;
  userName: string;
  locationOverrides?: Array<{ index: number; warehouseId?: string; shelfId?: string }>;
  lineAllocations?: Array<{ index: number; allocations?: Array<{ warehouseId?: string; shelfId?: string; quantity?: number }> }>;
}) {
  const { order, locationOverrides, lineAllocations } = params;
  const customerParsed = parseCustomerFromNotes(String(order.notes || ''));
  const customerName = String(order.customerName || customerParsed.name || 'عميل متجر').trim() || 'عميل متجر';
  const customerPhone = String(order.storeCustomerPhone || customerParsed.phone || '').trim();
  const customerAddress = String(order.storeCustomerAddress || customerParsed.address || '').trim();
  const customerId = await ensureStoreCustomer({ name: customerName, phone: customerPhone, address: customerAddress });

  const settings = await pgGetSettings();
  const defaultWarehouseId = String((settings as any)?.defaultSalesWarehouseId || '').trim();
  const defaultShelfId = String((settings as any)?.defaultSalesShelfId || '').trim();
  const warehousesEnabled = (settings as any)?.warehousesEnabled === true || (settings as any)?.warehousesEnabled === 'true';

  const materialsResult = await pgGetMaterials({ page: 1, pageSize: 5000 });
  const materials = (materialsResult.items || []) as Array<Record<string, unknown>>;
  const materialsById = new Map(materials.map((entry) => [String(entry.id || ''), entry]));

  const locationPatchedItems = applyLocationOverrides(Array.isArray(order.items) ? order.items : [], locationOverrides);
  const sourceItems = applyLineAllocations(locationPatchedItems, lineAllocations);
  if (sourceItems.length === 0) {
    throw new Error('الطلب لا يحتوي أصنافاً');
  }

  const itemsForSalesInvoice = sourceItems.map((entry: any) => {
    const materialId = String(entry.materialId || '').trim();
    const quantity = Number(entry.quantity || 0);
    const unitPrice = Number(entry.unitPrice || 0);
    const material = materialsById.get(materialId) as Record<string, any> | undefined;
    const warehouseId = String(entry.warehouseId || defaultWarehouseId || '').trim();
    const shelfId = String(entry.shelfId || defaultShelfId || '').trim();

    if (!materialId || !Number.isFinite(quantity) || quantity <= 0) {
      throw new Error('يوجد صنف غير صالح في الطلب');
    }

    const resolvedName = String(
      entry.materialName ||
      entry.name ||
      material?.nameAr ||
      material?.name ||
      materialId
    ).trim();
    const lineDiscount = Number(entry.lineDiscountAmount || 0);
    const lineTotal = quantity * unitPrice - lineDiscount;

    return {
      materialId,
      name: resolvedName,
      quantity,
      unitPrice,
      total: lineTotal,
      warehouseId,
      shelfId,
      taxRate: Number(entry.taxRate || 0),
      realEstateProjectId: undefined,
      realEstateUnitId: undefined,
      realEstateProjectName: undefined,
      realEstateUnitName: undefined,
      lineDiscountPercent: Number(entry.lineDiscountPercent || 0),
      lineDiscountAmount: lineDiscount,
      material,
    };
  });

  if (warehousesEnabled) {
    const inventoryItems = itemsForSalesInvoice.filter((entry) => {
      const category = String((entry.material as any)?.itemCategory || 'inventory').trim().toLowerCase();
      return category === 'inventory';
    });

    const materialIds = Array.from(new Set(inventoryItems.map((entry) => String(entry.materialId || '').trim()).filter(Boolean)));
    const stockLocations = materialIds.length > 0 ? await pgGetMaterialStockLocations(materialIds) : {};

    const availableByKey = new Map<string, number>();
    for (const materialId of Object.keys(stockLocations)) {
      for (const loc of stockLocations[materialId] || []) {
        const key = `${materialId}||${String(loc.warehouseId || '').trim()}||${String(loc.shelfId || '').trim()}`;
        availableByKey.set(key, Number(loc.quantity || 0));
      }
    }

    const requestedByKey = new Map<string, number>();
    for (const entry of inventoryItems) {
      const key = `${String(entry.materialId || '').trim()}||${String(entry.warehouseId || '').trim()}||${String(entry.shelfId || '').trim()}`;
      requestedByKey.set(key, (requestedByKey.get(key) || 0) + Number(entry.quantity || 0));
    }

    for (const [key, requestedQty] of requestedByKey.entries()) {
      const availableQty = Number(availableByKey.get(key) || 0);
      if (requestedQty - availableQty > 0.0001) {
        const [materialId, warehouseId, shelfId] = key.split('||');
        throw new Error(
          `الكمية المطلوبة (${requestedQty}) تتجاوز المتاح (${availableQty}) للصنف ${materialId} في المستودع ${warehouseId} والرف ${shelfId}`
        );
      }
    }
  }

  if (warehousesEnabled) {
    const missingLocation = itemsForSalesInvoice.find((entry) => {
      const category = String((entry.material as any)?.itemCategory || 'inventory').trim().toLowerCase();
      if (category !== 'inventory') return false;
      return !String(entry.warehouseId || '').trim() || !String(entry.shelfId || '').trim();
    });
    if (missingLocation) {
      throw new Error('لا يمكن ترحيل الطلب: إعدادات موقع المخزون غير مكتملة (المستودع/الرف)');
    }
  }

  return {
    customerId,
    customerName,
    itemsForSalesInvoice,
    updatedOrderItems: sourceItems,
  };
}

async function createStoreShipment(params: {
  order: Record<string, any>;
  userId: string;
  userName: string;
  locationOverrides?: Array<{ index: number; warehouseId?: string; shelfId?: string }>;
  lineAllocations?: Array<{ index: number; allocations?: Array<{ warehouseId?: string; shelfId?: string; quantity?: number }> }>;
}) {
  const { order, userId, userName, locationOverrides, lineAllocations } = params;
  const prepared = await prepareStoreOrderPosting({ order, userId, userName, locationOverrides, lineAllocations });

  const service = getSalesInvoiceService();
  const orderRef = String(order.invoiceNumber || order.id || '').trim();
  const createdShipment = await service.create({
    customerId: prepared.customerId,
    date: String(order.date || new Date().toISOString()),
    items: prepared.itemsForSalesInvoice.map((entry) => ({
      materialId: entry.materialId,
      name: entry.name,
      quantity: entry.quantity,
      unitPrice: entry.unitPrice,
      total: entry.total,
      warehouseId: entry.warehouseId,
      shelfId: entry.shelfId,
      taxRate: entry.taxRate,
      lineDiscountPercent: entry.lineDiscountPercent,
      lineDiscountAmount: entry.lineDiscountAmount,
    })),
    amountReceived: 0,
    postingStatus: 'posted',
    shippingStatus: 'shipped',
    documentType: 'shipment',
    customerNotes: `إرسالية طلب متجر رقم ${String(order.invoiceNumber || '')}`,
    internalNotes: `StoreOrderId=${String(order.id || '')}`,
    taxMethod: 'tax-exempt',
    taxExemptionReason: 'Store online order - exempt flow',
    taxExemptionReference: `STORE-SHIPMENT-${orderRef || Date.now()}`,
    source: 'store',
    userId,
    userName,
  });

  const inventoryMovements = prepared.itemsForSalesInvoice
    .filter((entry) => {
      const category = String((entry.material as any)?.itemCategory || 'inventory').trim().toLowerCase();
      return category === 'inventory';
    })
    .map((entry, index) => ({
      id: `inv-sale-${String(createdShipment.id || '').trim()}-${index}`,
      date: String(createdShipment.date || new Date().toISOString()),
      materialId: entry.materialId,
      warehouseId: entry.warehouseId,
      shelfId: entry.shelfId,
      quantityIn: 0,
      quantityOut: entry.quantity,
      referenceType: 'sale',
      referenceId: String(createdShipment.id || ''),
      invoiceId: String(createdShipment.id || ''),
      shipmentId: String(createdShipment.id || ''),
      note: `Store shipment ${String(createdShipment.invoiceNumber || createdShipment.id || '')} from store order ${String(order.invoiceNumber || order.id || '')}`,
    }));

  if (inventoryMovements.length > 0) {
    await pgSaveInventoryMovements(inventoryMovements as Array<Record<string, unknown>>);
  }

  return {
    shipmentId: String(createdShipment.id || ''),
    shipmentNumber: String(createdShipment.invoiceNumber || ''),
    inventoryMovementCount: inventoryMovements.length,
    updatedOrderItems: prepared.updatedOrderItems,
  };
}

async function createStoreTaxInvoiceFromShipment(params: {
  order: Record<string, any>;
  shipmentId: string;
  userId: string;
  userName: string;
}) {
  const { order, shipmentId, userId, userName } = params;
  const customerParsed = parseCustomerFromNotes(String(order.notes || ''));
  const customerName = String(order.customerName || customerParsed.name || 'عميل متجر').trim() || 'عميل متجر';
  const customerPhone = String(order.storeCustomerPhone || customerParsed.phone || '').trim();
  const customerAddress = String(order.storeCustomerAddress || customerParsed.address || '').trim();
  const customerId = await ensureStoreCustomer({ name: customerName, phone: customerPhone, address: customerAddress });

  const service = getSalesInvoiceService();
  const orderRef = String(order.invoiceNumber || order.id || '').trim();
  const createdSalesInvoice = await service.create({
    customerId,
    date: String(order.date || new Date().toISOString()),
    items: [],
    linkedShipmentIds: [shipmentId],
    amountReceived: Number(order.amountPaid || 0),
    postingStatus: 'posted',
    shippingStatus: 'shipped',
    documentType: 'tax_invoice',
    customerNotes: `فاتورة ضريبية لطلب متجر رقم ${String(order.invoiceNumber || '')}`,
    internalNotes: `StoreOrderId=${String(order.id || '')}; ShipmentId=${shipmentId}`,
    taxMethod: 'tax-exempt',
    taxExemptionReason: 'Store online order - exempt flow',
    taxExemptionReference: `STORE-TAX-${orderRef || Date.now()}`,
    source: 'store',
    userId,
    userName,
  });

  return {
    salesInvoiceId: String(createdSalesInvoice.id || ''),
    salesInvoiceNumber: String(createdSalesInvoice.invoiceNumber || ''),
  };
}

async function processDeliveredOrderReturn(params: {
  order: Record<string, any>;
  salesInvoiceId: string;
  userId: string;
  userName: string;
  returnHandling?: {
    condition?: 'good' | 'damaged';
    reason?: string;
    refundMethod?: 'cash' | 'check' | 'bank_transfer' | 'credit_to_account';
    refundAmount?: number;
    note?: string;
  };
}) {
  const { order, salesInvoiceId, userId, userName, returnHandling } = params;
  const items = Array.isArray(order.items) ? order.items : [];
  if (items.length === 0) {
    throw new Error('لا توجد بنود لتنفيذ مردود عليها');
  }

  const condition = returnHandling?.condition === 'damaged' ? 'damaged' : 'good';
  const primaryReason = condition === 'damaged' ? 'damaged' : 'customer_request';
  const reasonDescription = String(returnHandling?.reason || '').trim() || (condition === 'damaged' ? 'مردود طلب متجر - أصناف تالفة' : 'مردود طلب متجر - إرجاع سليم');

  const service = createSalesReturnService();
  const createdReturn = await service.create({
    invoiceId: salesInvoiceId,
    date: new Date().toISOString().split('T')[0],
    primaryReason,
    reasonDescription,
    items: items.map((entry: any, index: number) => ({
      lineId: `${String(entry.materialId || 'line')}-${index + 1}`,
      materialId: String(entry.materialId || ''),
      returnedQuantity: Number(entry.quantity || 0),
      condition: condition === 'damaged' ? 'damaged' : 'good',
      conditionNotes: String(returnHandling?.note || '').trim() || undefined,
      inspectionNotes: String(returnHandling?.note || '').trim() || undefined,
    })),
    customerNotes: `مردود مرتبط بطلب متجر ${String(order.invoiceNumber || order.id || '')}`,
    internalNotes: `StoreOrderId=${String(order.id || '')}`,
    userId,
    userName,
  });

  const approvedReturn = await service.approve({
    returnId: createdReturn.id,
    approvalDate: new Date().toISOString().split('T')[0],
    userId,
    userName,
  });

  const totalReturnedQuantity = (approvedReturn.items || []).reduce((sum, entry) => sum + Number(entry.returnedQuantity || 0), 0);
  const receivedReturn = await service.receive({
    returnId: approvedReturn.id,
    receivedDate: new Date().toISOString().split('T')[0],
    receivedQuantity: totalReturnedQuantity,
    receivedNotes: String(returnHandling?.note || '').trim() || undefined,
    userId,
    userName,
  });

  const refundAmount = Number(returnHandling?.refundAmount || order.grandTotal || receivedReturn.totalAmount || 0);
  const processedReturn = await service.process({
    returnId: receivedReturn.id,
    processedDate: new Date().toISOString().split('T')[0],
    refundAmount,
    refundMethod: returnHandling?.refundMethod || 'credit_to_account',
    processingNotes: String(returnHandling?.note || '').trim() || undefined,
    userId,
    userName,
  });

  return {
    salesReturnId: processedReturn.id,
    salesReturnNumber: processedReturn.returnNumber,
    salesReturnStatus: processedReturn.status,
    refundAmount,
  };
}

export async function PATCH(
  request: NextRequest,
  { params }: { params: Promise<{ id: string }> }
) {
  try {
    const session = await getSession();
    if (!session?.user || (session.user.role !== 'admin' && session.user.role !== 'pos')) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    const resolvedParams = await params;
    const orderId = String(resolvedParams?.id || '').trim();
    if (!orderId) {
      return NextResponse.json({ error: 'Missing order ID' }, { status: 400 });
    }

    const body = await request.json();
    const { storeStatus, returnHandling, lineLocations, lineAllocations } = body;

    if (!storeStatus || !VALID_STATUSES.includes(storeStatus)) {
      return NextResponse.json(
        { error: `حالة غير صالحة. القيم المقبولة: ${VALID_STATUSES.join(', ')}` },
        { status: 400 }
      );
    }

    const invoicesResult = await pgGetInvoices({ page: 1, pageSize: 5000 });
    const allInvoices = (invoicesResult.items || []) as any[];
    const invoice = allInvoices.find((inv) => inv.id === orderId);

    if (!invoice) {
      return NextResponse.json({ error: 'الطلب غير موجود' }, { status: 404 });
    }

    if (invoice.source !== 'store' && !String(invoice.invoiceNumber || '').startsWith('STORE/')) {
      return NextResponse.json({ error: 'هذا الطلب ليس من المتجر' }, { status: 400 });
    }

    const currentStatus = String(invoice.storeStatus || 'pending').trim();
    const allowedNext = ALLOWED_TRANSITIONS[currentStatus] || [];
    if (!allowedNext.includes(storeStatus)) {
      return NextResponse.json(
        { error: `انتقال حالة غير مسموح: ${currentStatus} -> ${storeStatus}` },
        { status: 400 }
      );
    }

    let fulfillment = {
      ...(typeof invoice.storeFulfillment === 'object' && invoice.storeFulfillment ? invoice.storeFulfillment : {}),
    } as Record<string, unknown>;

    let nextOrderItems = Array.isArray(invoice.items) ? invoice.items : [];

    if (storeStatus === 'confirmed') {
      const existingShipmentId = String((fulfillment as any)?.shipmentId || '').trim();
      if (!existingShipmentId) {
        const shipment = await createStoreShipment({
          order: invoice,
          userId: String(session.user.id || ''),
          userName: String(session.user.name || session.user.username || 'system'),
          locationOverrides: Array.isArray(lineLocations) ? lineLocations : undefined,
          lineAllocations: Array.isArray(lineAllocations) ? lineAllocations : undefined,
        });
        nextOrderItems = Array.isArray(shipment.updatedOrderItems) ? shipment.updatedOrderItems : nextOrderItems;
        fulfillment = {
          ...fulfillment,
          shipmentCreatedAt: new Date().toISOString(),
          shipmentCreatedBy: String(session.user.id || ''),
          shipmentId: shipment.shipmentId,
          shipmentNumber: shipment.shipmentNumber,
          inventoryMovementCount: shipment.inventoryMovementCount,
        };
      }
    }

    if (storeStatus === 'shipped') {
      let shipmentId = String((fulfillment as any)?.shipmentId || '').trim();
      if (!shipmentId) {
        const shipment = await createStoreShipment({
          order: { ...invoice, items: nextOrderItems },
          userId: String(session.user.id || ''),
          userName: String(session.user.name || session.user.username || 'system'),
        });
        shipmentId = shipment.shipmentId;
        nextOrderItems = Array.isArray(shipment.updatedOrderItems) ? shipment.updatedOrderItems : nextOrderItems;
        fulfillment = {
          ...fulfillment,
          shipmentCreatedAt: new Date().toISOString(),
          shipmentCreatedBy: String(session.user.id || ''),
          shipmentId: shipment.shipmentId,
          shipmentNumber: shipment.shipmentNumber,
          inventoryMovementCount: shipment.inventoryMovementCount,
        };
      }

      const existingSalesInvoiceId = String((fulfillment as any)?.salesInvoiceId || '').trim();
      if (!existingSalesInvoiceId) {
        const posting = await createStoreTaxInvoiceFromShipment({
          order: { ...invoice, items: nextOrderItems },
          shipmentId,
          userId: String(session.user.id || ''),
          userName: String(session.user.name || session.user.username || 'system'),
        });
        fulfillment = {
          ...fulfillment,
          postedAt: new Date().toISOString(),
          postedBy: String(session.user.id || ''),
          salesInvoiceId: posting.salesInvoiceId,
          salesInvoiceNumber: posting.salesInvoiceNumber,
        };
      }
    }

    if (currentStatus === 'delivered' && storeStatus === 'cancelled') {
      const salesInvoiceId = String((fulfillment as any)?.salesInvoiceId || '').trim();
      if (!salesInvoiceId) {
        throw new Error('لا يمكن تنفيذ مردود لطلب غير مرحّل كمبيعات. قم بالتسليم أولاً.');
      }

      const existingSalesReturnId = String((fulfillment as any)?.salesReturnId || '').trim();
      if (!existingSalesReturnId) {
        const returnResult = await processDeliveredOrderReturn({
          order: invoice,
          salesInvoiceId,
          userId: String(session.user.id || ''),
          userName: String(session.user.name || session.user.username || 'system'),
          returnHandling,
        });

        fulfillment = {
          ...fulfillment,
          returnedAt: new Date().toISOString(),
          returnedBy: String(session.user.id || ''),
          returnCondition: String(returnHandling?.condition || 'good'),
          returnReason: String(returnHandling?.reason || '').trim() || undefined,
          salesReturnId: returnResult.salesReturnId,
          salesReturnNumber: returnResult.salesReturnNumber,
          salesReturnStatus: returnResult.salesReturnStatus,
          returnRefundAmount: returnResult.refundAmount,
        };
      }
    }

    const updatedInvoice = {
      ...invoice,
      items: nextOrderItems,
      storeStatus,
      storeFulfillment: fulfillment,
      updatedAt: new Date().toISOString(),
    };

    await pgSaveInvoices([updatedInvoice]);

    return NextResponse.json({ success: true, storeStatus, storeFulfillment: fulfillment, order: updatedInvoice });
  } catch (error: any) {
    console.error('[store/orders/[id]] PATCH error:', error);
    return NextResponse.json({ error: error?.message || 'Internal server error' }, { status: 500 });
  }
}
