const POSApp = {
  currentUser: null,
  items: [],
  warehouses: [],
  clients: [],
  safes: [],
  cart: [],
  transactions: [],
  currentTag: 'all',
  vatRate: 15,
  allowNegativeStock: false,
  settings: {},

  async init() {
    const savedVat = localStorage.getItem('pos_vat_rate');
    if(savedVat !== null) {
      this.vatRate = parseFloat(savedVat);
      const vatInput = document.getElementById('pos-vat-rate-input');
      if(vatInput) vatInput.value = this.vatRate;
    }

    const userStr = sessionStorage.getItem('currentUser');
    if (userStr) {
      this.currentUser = JSON.parse(userStr);
      document.getElementById('view-login').style.display = 'none';
      document.getElementById('app-layout').style.display = 'flex';
      document.getElementById('current-username').innerText = this.currentUser.username;
      await this.loadData();
    } else {
      document.getElementById('view-login').style.display = 'flex';
      document.getElementById('app-layout').style.display = 'none';
    }
  },

  async login() {
    const u = document.getElementById('login-username').value.trim();
    const p = document.getElementById('login-password').value.trim();
    const err = document.getElementById('login-error');
    err.style.display = 'none';
    if(!u || !p) { err.innerText = "أدخل البيانات"; err.style.display = 'block'; return; }

    document.getElementById('loading-overlay').style.display = 'flex';
    try {
      const user = await window.DB.login(u, p);
      if(user) {
        sessionStorage.setItem('currentUser', JSON.stringify(user));
        this.init();
      } else {
        err.innerText = "اسم المستخدم أو كلمة المرور غير صحيحة";
        err.style.display = 'block';
      }
    } catch(e) {
      err.innerText = "خطأ في الاتصال بالخادم";
      err.style.display = 'block';
    }
    document.getElementById('loading-overlay').style.display = 'none';
  },

  logout() {
    sessionStorage.removeItem('currentUser');
    location.reload();
  },

  async loadData() {
    document.getElementById('loading-overlay').style.display = 'flex';
    try {
      const [items, warehouses, contacts, accounts, settings, tx] = await Promise.all([
        DB.getAll('items'), DB.getAll('warehouses'), DB.getAll('contacts'), DB.getAll('accounts'), DB.getAll('settings'), DB.getAll('transactions')
      ]);

      this.items = items || [];
      this.warehouses = warehouses || [];
      this.clients = (contacts || []).filter(c => { const t = c.type ? c.type.toLowerCase() : ''; return t.includes('عميل') || t.includes('client') || !t; });
      this.safes = (accounts || []).filter(a => { const t = a.type ? a.type.toLowerCase() : ''; const n = a.name ? a.name.toLowerCase() : ''; return t.includes('خزينة') || t.includes('cash') || n.includes('خزين') || n.includes('صندوق') || n.includes('كاش') || n.includes('بنك') || n.includes('عهد'); });
      this.transactions = tx || [];
      
      const setObj = {};
      if(Array.isArray(settings) && settings.length > 0) {
         // If it's an array of key/value pairs (older schema)
         if(settings[0].key !== undefined) {
            settings.forEach(s => { setObj[s.key] = s.value; });
         } else {
            // If it's a single row object
            Object.assign(setObj, settings[0]);
         }
      } else if(settings && !Array.isArray(settings)) {
         Object.assign(setObj, settings);
      }
      if (setObj && Object.keys(setObj).length > 0) {
        this.settings = setObj;
        this.allowNegativeStock = this.settings.allow_negative_stock === true || this.settings.allow_negative_stock === 'true';
      }

      this.populateSelects();
      this.renderTags();
      this.renderProducts('all');
      this.updateSessionCounter();
    } catch (e) {
      console.error(e);
      alert("خطأ في تحميل البيانات");
    }
    document.getElementById('loading-overlay').style.display = 'none';
  },

  populateSelects() {
    // Warehouses
    const whSel = document.getElementById('pos-warehouse');
    let availableWarehouses = this.warehouses;
    if (this.currentUser) {
      if (this.currentUser.role === 'أمين مخزن' && this.currentUser.warehouse_id) {
        availableWarehouses = this.warehouses.filter(w => String(w.id) === String(this.currentUser.warehouse_id));
      } else if (this.currentUser.role === 'موظف مخصص' && this.currentUser.allowed_warehouses && this.currentUser.allowed_warehouses.length > 0) {
        availableWarehouses = this.warehouses.filter(w => this.currentUser.allowed_warehouses.some(aw => String(aw) === String(w.id)));
      } else if (this.currentUser.warehouse_id) {
        availableWarehouses = this.warehouses.filter(w => String(w.id) === String(this.currentUser.warehouse_id));
      }
    }
    if(availableWarehouses.length === 0) availableWarehouses = this.warehouses;

    whSel.innerHTML = availableWarehouses.map(w => `<option value="${w.id}">${w.name}</option>`).join('');
    if(availableWarehouses.length === 1) {
      whSel.value = availableWarehouses[0].id;
      whSel.disabled = true;
    } else {
      whSel.disabled = false;
    }
    whSel.addEventListener('change', () => this.renderProducts(this.currentTag));

    // Clients
    const clSel = document.getElementById('pos-client');
    let defaultClient = this.clients.find(c => c.name.includes('نقدي') || c.name.includes('نقدى') || c.name.toLowerCase() === 'cash');
    let defaultClientId = defaultClient ? defaultClient.id : '';

    const savedClient = localStorage.getItem('pos_last_client_id');
    if (savedClient && this.clients.some(c => String(c.id) === String(savedClient))) {
      defaultClientId = savedClient;
    }

    clSel.innerHTML = `<option value="">اختر عميل...</option>` + this.clients.map(c => `<option value="${c.id}" ${String(c.id) === String(defaultClientId) ? 'selected' : ''}>${c.name}</option>`).join('');
    
    clSel.addEventListener('change', (e) => {
      localStorage.setItem('pos_last_client_id', e.target.value);
    });

    // Safes
    const safeSel = document.getElementById('pos-safe');
    safeSel.innerHTML = this.safes.map(s => `<option value="${s.id}">${s.name}</option>`).join('');
  },

  renderTags() {
    const tagsContainer = document.getElementById('pos-tags-container');
    const allTags = new Set();
    this.items.forEach(i => {
      if(i.category) allTags.add(i.category);
      if(i.tags) {
        let tgs = typeof i.tags === 'string' ? i.tags.split(',') : i.tags;
        tgs.forEach(t => { if(t.trim()) allTags.add(t.trim()) });
      }
    });
    let html = `<div class="pos-tag active" data-tag="all" onclick="POSApp.filterProducts('all', this)">الكل</div>`;
    allTags.forEach(tag => {
      html += `<div class="pos-tag" data-tag="${tag}" onclick="POSApp.filterProducts('${tag}', this)">${tag}</div>`;
    });
    tagsContainer.innerHTML = html;
  },

  filterProducts(tag, el) {
    this.currentTag = tag;
    if(el) {
      document.querySelectorAll('.pos-tag').forEach(e => e.classList.remove('active'));
      el.classList.add('active');
    }
    this.renderProducts(tag);
  },

  renderProducts(tag) {
    const grid = document.getElementById('pos-products-grid');
    let filtered = this.items.filter(i => i.is_service !== true && i.is_service !== 'true'); // Filter out services if needed
    if (tag !== 'all') {
      filtered = filtered.filter(i => 
        i.category === tag || 
        (i.tags && i.tags.includes(tag))
      );
    }
    
    if(filtered.length === 0) {
      grid.innerHTML = '<div style="color:#888; text-align:center; grid-column: 1/-1;">لا توجد أصناف</div>';
      return;
    }

    grid.innerHTML = filtered.map(item => {
      // Calculate available stock across all warehouses, or let's show overall stock
      let stock = this.getItemStock(item.id);
      return `
        <div class="pos-product-card" onclick="POSApp.addToCart(${item.id})">
          <h4 title="${item.name || 'غير محدد'}">${item.name || 'غير محدد'}</h4>
          <div class="price">${(item.sales_price || 0)} <span style="font-size:11px; color:#aaa; font-weight:normal;">${item.unit || 'قطعة'}</span></div>
          <div class="stock" style="color: ${stock <= 0 && !this.allowNegativeStock ? '#e74c3c' : '#888'}">الرصيد: ${stock}</div>
        </div>
      `;
    }).join('');
  },

  getItemStock(itemId) {
    const whId = document.getElementById('pos-warehouse').value;
    let stock = 0;
    
    try {
      const cacheStr = localStorage.getItem('shared_balances_cache');
      if (cacheStr) {
        const cache = JSON.parse(cacheStr);
        if (cache[itemId]) {
          return whId ? (cache[itemId].warehouses[whId] || 0) : (cache[itemId].total || 0);
        }
      }
    } catch(e) {}

    this.transactions.forEach(inv => {
      if(inv.status === 'draft' || inv.status === 'pending_store') return;
      if(inv.items && Array.isArray(inv.items)) {
        inv.items.forEach(it => {
          if(String(it.item_id) === String(itemId)) {
            const qty = parseFloat(it.qty) || 0;
            if(['purchases', 'in', 'opening_balance', 'sales_return', 'petty_cash_settlement'].includes(inv.type)) {
              if(!whId || String(inv.to_warehouse_id || inv.warehouse_id || inv.from_warehouse_id) === String(whId)) stock += qty;
            }
            if(['sales', 'out_project', 'purchases_return', 'depreciate_asset', 'manufacture', 'out'].includes(inv.type)) {
              if(!whId || String(inv.from_warehouse_id || inv.warehouse_id || inv.to_warehouse_id) === String(whId)) stock -= qty;
            }
            if(inv.type === 'transfer') {
              if(String(inv.from_warehouse_id || inv.warehouse_id) === String(whId)) stock -= qty;
              if(String(inv.to_warehouse_id) === String(whId) && inv.status === 'completed') stock += qty;
            }
          }
        });
      }
    });
    return stock;
  },

  getLastPriceForClient(itemId, clientId) {
    if(!clientId) return null;
    // Find the latest transaction for this client and this item
    let lastPrice = null;
    let lastDate = null;
    for(let tx of this.transactions) {
      if((tx.type === 'out_project' || tx.type === 'sales') && (tx.client_id == clientId || tx.contact_id == clientId) && tx.items) {
        for(let line of tx.items) {
          if(line.item_id == itemId) {
            let txDate = new Date(tx.date || tx.created_at || 0);
            if(!lastDate || txDate > lastDate) {
               lastDate = txDate;
               lastPrice = line.price;
            }
          }
        }
      }
    }
    return lastPrice;
  },

  addToCart(itemId) {
    const item = this.items.find(i => i.id == itemId);
    if(!item) return;

    const warehouseId = document.getElementById('pos-warehouse').value;
    if(!warehouseId) {
       alert("الرجاء اختيار المخزن أولاً");
       return;
    }

    let existing = this.cart.find(c => c.item_id == itemId);
    let currentQty = existing ? existing.qty : 0;

    // Stock Check
    let stock = this.getItemStock(itemId, warehouseId);
    if (!this.allowNegativeStock && (currentQty + 1) > stock) {
      alert("الرصيد غير كافٍ. الرصيد المتاح: " + stock);
      return;
    }

    if (existing) {
      existing.qty++;
    } else {
      // Determine Price
      let price = parseFloat(item.sales_price || 0);
      const clientId = document.getElementById('pos-client').value;
      if(clientId) {
         let lp = this.getLastPriceForClient(itemId, clientId);
         if(lp !== null) price = parseFloat(lp);
      }

      this.cart.push({
        item_id: item.id,
        name: item.name,
        price: price,
        cost: parseFloat(item.purchase_price) || 0,
        qty: 1,
        tax_inclusive: item.tax_inclusive === true || item.tax_inclusive === 'true'
      });
    }
    this.renderCart();
  },

  updateQty(itemId, inputElement) {
    let val = parseFloat(inputElement.value);
    if(isNaN(val) || val <= 0) val = 1;
    
    const warehouseId = document.getElementById('pos-warehouse').value;
    let stock = this.getItemStock(itemId, warehouseId);
    if (!this.allowNegativeStock && val > stock) {
      alert("الرصيد غير كافٍ. سيتم تعيين الكمية إلى أقصى حد متاح: " + stock);
      val = stock;
      if(val <= 0) val = 1; // Or remove? Let's just set to 1 and block checkout later if needed.
    }

    let line = this.cart.find(c => c.item_id == itemId);
    if(line) {
      line.qty = val;
      inputElement.value = val;
    }
    this.renderCart();
  },

  updatePrice(itemId, inputElement) {
    let val = parseFloat(inputElement.value);
    if(isNaN(val) || val < 0) val = 0;
    let line = this.cart.find(c => c.item_id == itemId);
    if(line) {
      line.price = val;
    }
    this.renderCart();
  },

  removeFromCart(itemId) {
    this.cart = this.cart.filter(c => c.item_id != itemId);
    this.renderCart();
  },

  renderCart() {
    const tbody = document.getElementById('pos-cart-tbody');
    if(this.cart.length === 0) {
      tbody.innerHTML = '<tr><td colspan="5" style="text-align:center; color:#888;">السلة فارغة</td></tr>';
      this.updateTotals();
      return;
    }
    tbody.innerHTML = this.cart.map(c => {
      let total = c.price * c.qty;
      return `
        <tr>
          <td>${c.name}</td>
          <td><input type="number" class="cart-qty-input" value="${c.qty}" onchange="POSApp.updateQty(${c.item_id}, this)"></td>
          <td><input type="number" style="width:60px;" class="cart-qty-input" value="${c.price}" onchange="POSApp.updatePrice(${c.item_id}, this)"></td>
          <td>${total.toFixed(2)}</td>
          <td><button class="cart-remove-btn" onclick="POSApp.removeFromCart(${c.item_id})">×</button></td>
        </tr>
      `;
    }).join('');
    this.updateTotals();
  },

  updateVatRate(val) {
    let num = parseFloat(val);
    if(isNaN(num) || num < 0) num = 0;
    this.vatRate = num;
    localStorage.setItem('pos_vat_rate', num);
    this.updateTotals();
  },

  updateTotals() {
    let subtotal = 0;
    let vat = 0;
    this.cart.forEach(c => {
      let lineTotal = c.qty * c.price;
      if(c.tax_inclusive) {
        let base = lineTotal / (1 + this.vatRate / 100);
        let tax = lineTotal - base;
        subtotal += base;
        vat += tax;
      } else {
        subtotal += lineTotal;
        vat += lineTotal * (this.vatRate / 100);
      }
    });
    let grandTotal = subtotal + vat;

    document.getElementById('pos-subtotal').innerText = subtotal.toFixed(2);
    document.getElementById('pos-vat').innerText = vat.toFixed(2);
    document.getElementById('pos-grand-total').innerText = grandTotal.toFixed(2);
  },

  async processPosData() {
    if(this.cart.length === 0) {
      alert("السلة فارغة"); return;
    }
    const warehouseId = document.getElementById('pos-warehouse').value;
    const clientId = document.getElementById('pos-client').value;
    const safeId = document.getElementById('pos-safe').value;

    if(!warehouseId || !clientId || !safeId) {
      alert("تأكد من اختيار المخزن والعميل وخزينة الدفع");
      return;
    }

    // Final stock check
    if(!this.allowNegativeStock) {
      for(let c of this.cart) {
        let st = this.getItemStock(c.item_id, warehouseId);
        if(c.qty > st) {
          alert("الرصيد غير كافٍ للصنف: " + c.name + " (المتاح: " + st + ")");
          return;
        }
      }
    }

    const btn = document.getElementById('btn-submit-pos');
    btn.innerText = "جاري الحفظ...";
    btn.disabled = true;

    // Calculate Totals first
    let grandTotal = parseFloat(document.getElementById('pos-grand-total').innerText);
    let vat = parseFloat(document.getElementById('pos-vat').innerText);
    let subtotal = parseFloat(document.getElementById('pos-subtotal').innerText);

    // Construct Transaction Payload
    const invoiceId = "POS-" + Date.now();
    const transaction = {
      reference: invoiceId,
      type: 'sales',
      date: new Date().toISOString().split('T')[0],
      from_warehouse_id: parseInt(warehouseId) || null,
      contact_id: parseInt(clientId) || null,
      payment_status: 'paid', // Cash sale
      payment_account_id: parseInt(safeId) || null,
      status: 'posted',
      notes: 'تم البيع عبر شاشة POS',
      items: this.cart.map(c => ({
        item_id: c.item_id,
        name: c.name,
        qty: c.qty,
        price: c.price,
        cost: c.cost || 0,
        discount: 0,
        discountType: 'value',
        total: c.qty * c.price
      })),
      net_before_tax: subtotal,
      tax_rate: this.vatRate || 0,
      tax_amount: vat,
      total: grandTotal,
      user: (JSON.parse(sessionStorage.getItem('currentUser') || '{}')).username || 'POS',
      created_at: new Date().toISOString()
    };

    // Instead of sending to DB, save to localStorage session
    const sessionKey = 'pos_session_invoices_' + (this.currentUser ? this.currentUser.username : 'default');
    let sessionInvoices = JSON.parse(localStorage.getItem(sessionKey) || '[]');
    sessionInvoices.push(transaction);
    localStorage.setItem(sessionKey, JSON.stringify(sessionInvoices));

    // Save a copy to pos_archive for manual review (Simple Archive)
    fetch('api.php?store=pos_archive', {
        method: 'POST',
        headers: {'Content-Type': 'application/json'},
        body: JSON.stringify(transaction)
    }).catch(e => console.error("Archive Error:", e));

    // Immediately deduct local stock so cashier sees accurate numbers for the rest of the session
    this.transactions.push({ id: invoiceId, ...transaction });

    // Update UI
    this.cart = [];
    this.renderCart();
    this.renderProducts(this.currentTag);
    this.updateSessionCounter();

    btn.innerText = "حفظ واعتماد الفاتورة";
    btn.disabled = false;

    const toast = document.getElementById('pos-toast');
    toast.classList.add('show');
    setTimeout(() => toast.classList.remove('show'), 3000);
  },

  updateSessionCounter() {
    const sessionKey = 'pos_session_invoices_' + (this.currentUser ? this.currentUser.username : 'default');
    let sessionInvoices = JSON.parse(localStorage.getItem(sessionKey) || '[]');
    
    let totalMoney = 0;
    let totalItems = 0;
    for(let inv of sessionInvoices) {
      totalMoney += (inv.net_total || 0);
      if(inv.items) {
        for(let item of inv.items) {
          totalItems += (item.qty || 0);
        }
      }
    }

    let counterEl = document.getElementById('session-counter');
    if(counterEl) counterEl.innerText = sessionInvoices.length;
    
    let moneyEl = document.getElementById('session-money');
    if(moneyEl) moneyEl.innerText = totalMoney.toLocaleString('ar-EG', {minimumFractionDigits: 2});
    
    let itemsEl = document.getElementById('session-items');
    if(itemsEl) itemsEl.innerText = totalItems;
  },

  showPendingInvoices() {
    const sessionKey = 'pos_session_invoices_' + (this.currentUser ? this.currentUser.username : 'default');
    let sessionInvoices = JSON.parse(localStorage.getItem(sessionKey) || '[]');
    
    const tbody = document.getElementById('pending-invoices-tbody');
    if(!tbody) return;
    tbody.innerHTML = '';
    
    if (sessionInvoices.length === 0) {
        tbody.innerHTML = '<tr><td colspan="5" style="text-align:center;">لا توجد فواتير معلقة حالياً</td></tr>';
    } else {
        sessionInvoices.forEach((inv, index) => {
            const clientName = this.clients.find(c => String(c.id) === String(inv.contact_id))?.name || 'غير محدد';
            tbody.innerHTML += `
                <tr>
                    <td>${index + 1}</td>
                    <td>${new Date(inv.date).toLocaleTimeString('ar-EG')}</td>
                    <td>${clientName}</td>
                    <td>${parseFloat(inv.net_total).toFixed(2)}</td>
                    <td><button onclick="POSApp.deletePendingInvoice(${index})" style="background:#e74c3c; color:white; border:none; padding:5px 10px; border-radius:3px; cursor:pointer;">حذف ❌</button></td>
                </tr>
            `;
        });
    }
    
    document.getElementById('pending-modal').style.display = 'block';
  },

  deletePendingInvoice(index) {
    if(!confirm('هل أنت متأكد من حذف هذه الفاتورة المعلقة؟ لا يمكن التراجع!')) return;
    const sessionKey = 'pos_session_invoices_' + (this.currentUser ? this.currentUser.username : 'default');
    let sessionInvoices = JSON.parse(localStorage.getItem(sessionKey) || '[]');
    sessionInvoices.splice(index, 1);
    localStorage.setItem(sessionKey, JSON.stringify(sessionInvoices));
    this.updateSessionCounter();
    this.showPendingInvoices();
  },

  clearAllPendingInvoices() {
    if(!confirm('هل أنت متأكد من حذف جميع الفواتير المعلقة في الجلسة بالكامل؟')) return;
    const sessionKey = 'pos_session_invoices_' + (this.currentUser ? this.currentUser.username : 'default');
    localStorage.removeItem(sessionKey);
    this.updateSessionCounter();
    document.getElementById('pending-modal').style.display = 'none';
  },

  async closeSession() {
    const sessionKey = 'pos_session_invoices_' + (this.currentUser ? this.currentUser.username : 'default');
    let sessionInvoices = JSON.parse(localStorage.getItem(sessionKey) || '[]');
    if(sessionInvoices.length === 0) {
      alert("لا توجد فواتير معلقة للترحيل.");
      return;
    }

    if(!confirm(`هل أنت متأكد من ترحيل وإنهاء الجلسة؟ سيتم إرسال ${sessionInvoices.length} فواتير.`)) return;

    const btn = document.getElementById('btn-close-session');
    btn.innerText = "جاري الترحيل...";
    btn.disabled = true;

    try {
      // Smart Grouping logic
      const grouped = {};
      for(let inv of sessionInvoices) {
        // Handle old format vs new format
        const subtotalVal = inv.net_before_tax !== undefined ? inv.net_before_tax : inv.total;
        const vatVal = inv.tax_amount !== undefined ? inv.tax_amount : (inv.vat || 0);
        const grandTotalVal = inv.total !== undefined && inv.net_before_tax !== undefined ? inv.total : (inv.net_total || inv.total);
        
        let taxRateKey = inv.tax_rate;
        if (taxRateKey === undefined) {
             taxRateKey = subtotalVal > 0 ? parseFloat(((vatVal / subtotalVal) * 100).toFixed(2)) : 0;
        }

        // Group by Client + Warehouse + Safe + Tax Rate
        const key = `${inv.contact_id}_${inv.from_warehouse_id}_${inv.payment_account_id}_${taxRateKey}`;
        if(!grouped[key]) {
          grouped[key] = { 
              ...inv, 
              items: [], 
              net_before_tax: 0, 
              tax_amount: 0, 
              total: 0 
          };
          delete grouped[key].vat;
          delete grouped[key].net_total;
        }
        
        // Merge Items
        for(let item of inv.items) {
          let existing = grouped[key].items.find(i => i.item_id == item.item_id);
          if(existing) {
            existing.qty += item.qty;
            existing.total += item.total;
          } else {
            grouped[key].items.push({ ...item });
          }
        }
        // Add up totals
        grouped[key].net_before_tax += subtotalVal;
        grouped[key].tax_amount += vatVal;
        grouped[key].total += grandTotalVal;
      }

      // Find Accounts for Journal
      const allAccounts = await window.DB.getAll('accounts');
      const salesAcc = allAccounts.find(a => a.name.includes('مبيعات') && (a.name.includes('إيراد') || a.name.includes('ايراد')));
      const vatAcc = allAccounts.find(a => a.name.includes('ضريبة') && a.name.includes('قيمة'));
      const salesAccId = salesAcc ? salesAcc.id : null;
      const vatAccId = vatAcc ? vatAcc.id : null;

      // Post each grouped invoice
      for(let key in grouped) {
        const tx = grouped[key];
        // Update description to reflect consolidated nature
        tx.notes = 'فاتورة POS مجمعة - إغلاق جلسة';
        if (tx.net_before_tax > 0) {
            tx.tax_rate = parseFloat(((tx.tax_amount / tx.net_before_tax) * 100).toFixed(2));
        } else {
            tx.tax_rate = 0;
        }

        // Save Transaction
        const res = await fetch('api.php?store=transactions', {
          method: 'POST',
          headers: {'Content-Type': 'application/json'},
          body: JSON.stringify(tx)
        });
        const txResult = await res.json();

        if(txResult.id) {
          // 1. Find Client Account
          let clientAcc = allAccounts.find(a => a.contact_id && String(a.contact_id) === String(tx.contact_id));
          if (!clientAcc) clientAcc = allAccounts.find(a => a.name.includes('عملاء') || a.name.includes('العملاء'));
          const clientId = clientAcc ? clientAcc.id : tx.payment_account_id;

          // 2. Construct Grouped Sales Journal (Invoice)
          const journalEntry = {
             date: tx.date,
             reference: 'sales_session_' + txResult.id,
             desc: "فاتورة مبيعات نقدية مجمعة POS - " + txResult.id,
             source_type: 'sales',
             status: 'posted',
             created_by: 'POS System',
             total: tx.total,
             rows: [
               { account_id: clientId, debit: tx.total, credit: 0, description: "مديونية عميل مبيعات POS", project_id: null }
             ]
          };
          if(salesAccId) journalEntry.rows.push({ account_id: salesAccId, debit: 0, credit: tx.net_before_tax, description: "إيرادات مبيعات POS", project_id: null });
          if(vatAccId && tx.tax_amount > 0) journalEntry.rows.push({ account_id: vatAccId, debit: 0, credit: tx.tax_amount, description: "ضريبة مبيعات POS", project_id: null });

          await fetch('api.php?store=journal_entries', {
            method: 'POST',
            headers: {'Content-Type': 'application/json'},
            body: JSON.stringify(journalEntry)
          });

          // 3. Construct Receipt Journal (Payment) AND Receipt Transaction for Client Statement
          if (clientAcc && tx.payment_account_id && tx.total > 0) {
             // 3a. Receipt Transaction
             const receiptTx = {
                type: 'receipt',
                date: tx.created_at,
                contact_id: tx.contact_id,
                amount: tx.total,
                treasury_account_id: tx.payment_account_id,
                status: 'posted',
                notes: "تحصيل فوري لفاتورة مبيعات POS #" + txResult.id,
                reference_id: txResult.id,
                created_by: typeof currentUser !== 'undefined' ? currentUser.username : 'نظام POS'
             };
             await fetch('api.php?store=transactions', {
                method: 'POST',
                headers: {'Content-Type': 'application/json'},
                body: JSON.stringify(receiptTx)
             });

             // 3b. Receipt Journal
             const receiptJournal = {
                date: tx.created_at,
                reference: 'receipt_sales_session_' + txResult.id,
                desc: "سداد مبيعات نقدية مجمعة POS - " + txResult.id,
                source_type: 'receipt',
                status: 'posted',
                created_by: 'POS System',
                total: tx.total,
                rows: [
                  { account_id: tx.payment_account_id, debit: tx.total, credit: 0, description: "تحصيل نقدي مبيعات POS", project_id: null },
                  { account_id: clientAcc.id, debit: 0, credit: tx.total, description: "سداد عميل مبيعات POS", project_id: null }
                ]
             };
             await fetch('api.php?store=journal_entries', {
               method: 'POST',
               headers: {'Content-Type': 'application/json'},
               body: JSON.stringify(receiptJournal)
             });
          }

          // 4. COGS Journal Entry
          let inventoryAcc = allAccounts.find(a => a.name.includes('المخزون') || (a.name.includes('مخزون') && a.name.includes('بضاع')));
          if (!inventoryAcc) inventoryAcc = allAccounts.find(a => a.name.includes('مخزون'));
          
          let cogsAcc = allAccounts.find(a => (a.name.includes('تكلفة') || a.name.includes('تكاليف')) && (a.name.includes('مبيعات') || a.name.includes('مباعة')));
          if (!cogsAcc) cogsAcc = allAccounts.find(a => a.name.includes('تكلفة المشاريع') || a.name.includes('تكلفة'));

          let sharedBalances = {};
          try {
             const cacheStr = localStorage.getItem('shared_balances_cache');
             if (cacheStr) sharedBalances = JSON.parse(cacheStr);
          } catch(e) {}

          let totalCost = 0;
          tx.items.forEach(it => { 
              let cost = parseFloat(it.cost) || 0;
              if (!cost) {
                 if (sharedBalances[it.item_id]) {
                     cost = parseFloat(sharedBalances[it.item_id].avgCost) || 0;
                 }
                 if (!cost) {
                     const originalItem = this.items.find(x => String(x.id) === String(it.item_id));
                     if (originalItem) cost = parseFloat(originalItem.purchase_price) || 0;
                 }
              }
              totalCost += (it.qty * cost); 
          });

          if (inventoryAcc && cogsAcc) {
             const cogsJournal = {
                date: tx.date,
                reference: 'cogs_sales_session_' + txResult.id,
                desc: "تكلفة المبيعات لفاتورة POS مجمعة - " + txResult.id,
                source_type: 'store_out',
                status: 'posted',
                created_by: 'POS System',
                total: totalCost,
                rows: [
                  { account_id: cogsAcc.id, debit: totalCost, credit: 0, description: "تكلفة البضاعة المباعة", project_id: null },
                  { account_id: inventoryAcc.id, debit: 0, credit: totalCost, description: "صرف مخزون مبيعات", project_id: null }
                ]
             };
             await fetch('api.php?store=journal_entries', {
               method: 'POST',
               headers: {'Content-Type': 'application/json'},
               body: JSON.stringify(cogsJournal)
             });
          }
        }
      }

      // Session closed successfully
      const sessionKey = 'pos_session_invoices_' + (this.currentUser ? this.currentUser.username : 'default');
      localStorage.removeItem(sessionKey);
      this.updateSessionCounter();
      alert("تم ترحيل مبيعات الجلسة بنجاح والتجميع الذكي للعملاء!");

    } catch(e) {
      console.error(e);
      alert("حدث خطأ أثناء ترحيل الجلسة.");
    } finally {
      btn.innerText = "ترحيل وإنهاء الجلسة";
      btn.disabled = false;
    }
  }
};

document.addEventListener('DOMContentLoaded', () => {
  POSApp.init();
});
