(() => {
    const parseNumber = (value) => {
        const normalized = String(value ?? "").trim().replace(/\s+/g, "").replace(",", ".");
        const num = Number(normalized);
        return Number.isFinite(num) ? num : 0;
    };

    const parseIntCount = (value) => {
        const num = parseNumber(value);
        if (num <= 0) return 0;
        return Math.max(0, Math.trunc(num));
    };

    const formatAmount = (value, decimals = 2) => {
        return Number(value || 0).toFixed(decimals).replace(".", ",");
    };

    const setupSegmentTabs = () => {
        document.querySelectorAll("[data-seg-tabs]").forEach((container) => {
            const targetId = String(container.getAttribute("data-target-input") || "").trim();
            if (!targetId) return;

            const target = document.getElementById(targetId);
            if (!target) return;

            const buttons = [...container.querySelectorAll("button[data-value]")];
            const setActive = (value) => {
                buttons.forEach((btn) => {
                    btn.classList.toggle("active", String(btn.dataset.value || "") === String(value || ""));
                });
            };

            setActive(target.value);

            buttons.forEach((btn) => {
                btn.addEventListener("click", () => {
                    const value = String(btn.dataset.value || "");
                    target.value = value;
                    target.dispatchEvent(new Event("change", { bubbles: true }));
                    setActive(value);
                });
            });
        });
    };

    const setupAutocomplete = () => {
        document.querySelectorAll("[data-autocomplete]").forEach((wrap) => {
            const input = wrap.querySelector("[data-autocomplete-input]");
            const hidden = wrap.querySelector("[data-autocomplete-hidden]");
            const list = wrap.querySelector("[data-autocomplete-list]");
            if (!input || !hidden || !list) return;

            let options = [];
            try {
                const raw = wrap.getAttribute("data-options") || "[]";
                const parsed = JSON.parse(raw);
                if (Array.isArray(parsed)) {
                    options = parsed
                        .map((x) => String(x || "").trim())
                        .filter((x) => x.length > 0);
                }
            } catch (_err) {
                options = [];
            }

            const submitOnSelect = wrap.getAttribute("data-submit-form") === "true";

            const closeList = () => {
                list.innerHTML = "";
                list.classList.remove("open");
            };

            const applySelection = (value, shouldSubmit = false) => {
                input.value = value;
                hidden.value = value;
                closeList();
                if (shouldSubmit && submitOnSelect) {
                    const form = wrap.closest("form");
                    if (form) form.submit();
                }
            };

            const renderList = (query, showAllOnEmpty = false) => {
                const q = String(query || "").trim().toLocaleLowerCase("tr-TR");
                if (q.length === 0 && !showAllOnEmpty) {
                    closeList();
                    return;
                }

                const filtered = q.length === 0
                    ? options.slice(0, 60)
                    : options
                        .filter((item) => item.toLocaleLowerCase("tr-TR").includes(q))
                        .slice(0, 60);

                if (!filtered.length) {
                    closeList();
                    return;
                }

                list.innerHTML = "";
                filtered.forEach((item) => {
                    const btn = document.createElement("button");
                    btn.type = "button";
                    btn.className = "autocomplete-item";
                    btn.textContent = item;
                    btn.addEventListener("mousedown", (ev) => {
                        ev.preventDefault();
                        applySelection(item, true);
                    });
                    list.appendChild(btn);
                });
                list.classList.add("open");
            };

            input.addEventListener("input", () => {
                hidden.value = "";
                renderList(input.value);
            });

            input.addEventListener("focus", () => {
                renderList(input.value, true);
            });

            input.addEventListener("click", () => {
                renderList(input.value, true);
            });

            input.addEventListener("keydown", (ev) => {
                if (ev.key === "Enter") {
                    const exact = options.find((x) => x.toLocaleLowerCase("tr-TR") === input.value.trim().toLocaleLowerCase("tr-TR"));
                    if (exact) {
                        ev.preventDefault();
                        applySelection(exact, true);
                    }
                }
                if (ev.key === "Escape") {
                    closeList();
                }
            });

            input.addEventListener("blur", () => {
                window.setTimeout(() => {
                    const exact = options.find((x) => x.toLocaleLowerCase("tr-TR") === input.value.trim().toLocaleLowerCase("tr-TR"));
                    if (exact) {
                        hidden.value = exact;
                    } else if (hidden.value === "") {
                        input.value = "";
                    }
                    closeList();
                }, 120);
            });

            if (hidden.value) {
                input.value = hidden.value;
            }
        });
    };

    const setupCashForm = () => {
        const cashType = document.getElementById("cash_hoca_type");
        const cashAccount = document.getElementById("cash_account_select");

        const syncAccounts = () => {
            if (!cashType || !cashAccount) return;
            const wanted = cashType.value === "cash" ? "cash" : "card";
            let hasSelectedVisible = false;

            [...cashAccount.options].forEach((opt, idx) => {
                if (idx === 0) return;
                const accountType = String(opt.dataset.atype || "");
                const visible = accountType === wanted;
                opt.hidden = !visible;
                opt.disabled = !visible;
                if (visible && opt.selected) hasSelectedVisible = true;
            });

            if (!hasSelectedVisible) {
                cashAccount.value = "";
            }
        };

        if (cashType && cashAccount) {
            cashType.addEventListener("change", syncAccounts);
            syncAccounts();
        }
    };

    const setupStockForm = () => {
        const form = document.getElementById("customer-stock-form");
        if (!form) return;

        const stockModeInput = document.getElementById("stock_mode_select");
        const stockTypeInput = document.getElementById("stock_type_input");
        const stockItemSelect = document.getElementById("stock_item_select") || form.querySelector('select[name="item_name"]');
        const stockQtyInput = document.getElementById("stock_qty_input") || form.querySelector('input[name="quantity"]');
        const stockUnitPrice = document.getElementById("stock_unit_price") || form.querySelector('input[name="unit_price"]');
        const stockCurrencySelect = document.getElementById("stock_currency_select") || form.querySelector('select[name="currency"]');
        const stockGold = document.getElementById("stock_gold_fields");
        const stockPaid = document.getElementById("stock_paid_fields");
        const stockBarcodeRows = document.getElementById("stock_barcode_rows");
        const stockDepotSelect = form.querySelector('select[name="depot_name"]');
        const bedelRows = document.getElementById("bedel_rows");
        const bedelAddBtn = document.getElementById("bedel_add_btn");
        const bedelTpl = document.getElementById("bedel_row_tpl");
        const stockPaymentTitle = document.getElementById("stock_payment_title");
        const stockPaymentSummary = document.getElementById("stock_payment_summary");
        const stockMainTotalText = document.getElementById("stock_main_total_text");
        const stockPaidTotalText = document.getElementById("stock_paid_total_text");
        const stockPaidDiffText = document.getElementById("stock_paid_diff_text");
        const stockTaxBlock = document.getElementById("stock_tax_block");
        const stockApplyTaxes = document.getElementById("stock_apply_taxes");
        const stockTaxList = document.getElementById("stock_tax_list");
        const stockTaxItems = [...form.querySelectorAll(".stock-tax-item")];

        let stockMeta = {};
        try {
            stockMeta = JSON.parse(form.getAttribute("data-stock-meta") || "{}");
        } catch (_err) {
            stockMeta = {};
        }
        let ratesPayload = {};
        try {
            ratesPayload = JSON.parse(form.getAttribute("data-rates") || "{}");
        } catch (_err) {
            ratesPayload = {};
        }
        let barcodeMeta = {};
        try {
            barcodeMeta = JSON.parse(form.getAttribute("data-barcode-meta") || "{}");
        } catch (_err) {
            barcodeMeta = {};
        }

        const currentMode = () => String(stockModeInput?.value || "Purchase");
        const isPaymentMode = () => {
            const mode = currentMode();
            return mode === "Purchase" || mode === "Sale" || mode === "In" || mode === "Out";
        };
        const isSalePaymentMode = () => {
            const mode = currentMode();
            return mode === "Sale" || mode === "Out";
        };
        const isBedelMode = () => {
            const mode = currentMode();
            return mode === "PaidIn" || mode === "PaidOut";
        };
        const isBedelPanelMode = () => isPaymentMode() || isBedelMode();
        const currentMainCurrency = () => String(stockCurrencySelect?.value || "TRY").toUpperCase();
        const currentStockTotal = () => {
            const qty = parseNumber(stockQtyInput?.value || "0");
            const unit = parseNumber(stockUnitPrice?.value || "0");
            return qty * unit;
        };
        const shouldApplyTaxes = () => {
            return isPaymentMode() && !!stockApplyTaxes?.checked;
        };

        const computeTaxTotals = (mainTotal) => {
            const subtotal = Math.max(0, Number(mainTotal || 0));
            if (!shouldApplyTaxes()) {
                return {
                    apply: false,
                    hasSelection: false,
                    taxTotal: 0,
                    grandTotal: subtotal,
                };
            }

            let taxTotal = 0;
            let selectedCount = 0;
            stockTaxItems.forEach((item) => {
                if (!item || !item.checked) return;
                selectedCount += 1;
                const kind = String(item.dataset.taxType || "percent").toLowerCase();
                const rate = Math.max(0, parseNumber(item.dataset.taxRate || "0"));
                if (kind === "fixed") {
                    taxTotal += rate;
                } else {
                    taxTotal += (subtotal * rate) / 100;
                }
            });
            taxTotal = Number(taxTotal.toFixed(2));
            const grandTotal = Number((subtotal + taxTotal).toFixed(2));
            return {
                apply: true,
                hasSelection: selectedCount > 0,
                taxTotal,
                grandTotal,
            };
        };

        const syncTaxPanel = () => {
            const paymentMode = isPaymentMode();
            const canUseTaxes = paymentMode;

            if (stockTaxBlock) {
                stockTaxBlock.classList.toggle("hidden", !paymentMode);
            }
            if (stockApplyTaxes) {
                stockApplyTaxes.disabled = !canUseTaxes;
            }
            const showTaxList = canUseTaxes && !!stockApplyTaxes?.checked;
            if (stockTaxList) {
                stockTaxList.classList.toggle("hidden", !showTaxList);
            }
            stockTaxItems.forEach((item) => {
                item.disabled = !showTaxList;
            });
        };

        const currentPriceAndCurrency = () => {
            const selectedName = String(stockItemSelect?.value || "");
            const meta = stockMeta[selectedName] || {};
            const mode = currentMode();
            const isSale = mode === "Sale" || mode === "PaidOut";
            return {
                price: parseNumber(isSale ? meta.sell_price : meta.buy_price),
                currency: String(isSale ? (meta.sell_currency || "TRY") : (meta.buy_currency || "TRY")),
            };
        };

        const parseRateText = (rawRate) => {
            const text = String(rawRate ?? "").trim();
            if (!text) return 0;
            let normalized = text.replace(/\s+/g, "");
            if (normalized.includes(",") && normalized.includes(".")) {
                normalized = normalized.replace(/\./g, "");
            }
            normalized = normalized.replace(",", ".");
            const value = Number(normalized);
            return Number.isFinite(value) ? value : 0;
        };

        const rateToTry = (currency) => {
            const cur = String(currency || "").trim().toUpperCase();
            if (!cur) return null;
            if (cur === "TRY") return 1;
            const row = ratesPayload[cur] || ratesPayload[cur.toLowerCase()];
            if (!row || typeof row !== "object") return null;
            const buy = parseRateText(row.buy ?? row.Buy ?? row.alis ?? row.Alis);
            const sell = parseRateText(row.sell ?? row.Sell ?? row.satis ?? row.Satis);
            if (buy > 0) return buy;
            if (sell > 0) return sell;
            return null;
        };

        const convertAmount = (amount, fromCurrency, toCurrency) => {
            const fromCur = String(fromCurrency || "").trim().toUpperCase();
            const toCur = String(toCurrency || "").trim().toUpperCase();
            if (!fromCur || !toCur) return null;
            if (fromCur === toCur) return amount;
            const fromRate = rateToTry(fromCur);
            const toRate = rateToTry(toCur);
            if (!fromRate || !toRate) return null;
            return (amount * fromRate) / toRate;
        };

        const syncAccountOptions = (accountSel, kind) => {
            if (!accountSel) return;
            const wanted = kind === "card" || kind === "transfer" ? "card" : "";
            let hasSelectedVisible = false;
            [...accountSel.options].forEach((opt, idx) => {
                if (idx === 0) return;
                const accountType = String(opt.dataset.atype || "");
                const visible = wanted === "" || accountType === wanted;
                opt.hidden = !visible;
                opt.disabled = !visible;
                if (visible && opt.selected) {
                    hasSelectedVisible = true;
                }
            });
            if (!hasSelectedVisible) {
                accountSel.value = "";
            }
        };

        const inferKindFromType = (typeValue) => {
            const rawType = String(typeValue || "").trim();
            const upper = rawType.toUpperCase();
            if (!rawType) return "";
            if (["TRY", "USD", "EUR", "GBP"].includes(upper)) return "currency";
            const lower = rawType.toLocaleLowerCase("tr-TR");
            if (lower === "nakit" || lower === "cash") return "cash";
            if (lower === "kart" || lower === "card") return "card";
            if (lower === "havale" || lower === "transfer") return "transfer";
            return "";
        };

        const syncTypeOptionsForMode = (typeSel) => {
            if (!typeSel) return;
            const bedelMode = isBedelMode();
            let selectedHidden = false;
            [...typeSel.options].forEach((opt, idx) => {
                if (idx === 0) return;
                const kind = String(opt.dataset.kind || "");
                const hideForBedel = bedelMode && ["cash", "card", "transfer"].includes(kind);
                opt.hidden = hideForBedel;
                opt.disabled = hideForBedel;
                if (hideForBedel && opt.selected) {
                    selectedHidden = true;
                }
            });
            if (selectedHidden) {
                typeSel.value = "";
            }
        };

        const syncBedelRow = (rowEl) => {
            if (!rowEl) return null;
            const paymentMode = isPaymentMode();
            const bedelMode = isBedelMode();
            const typeSel = rowEl.querySelector(".payment-type");
            const kindInp = rowEl.querySelector(".payment-kind");
            const qtyInp = rowEl.querySelector(".payment-qty");
            const unitInp = rowEl.querySelector(".payment-unit-price");
            const curSel = rowEl.querySelector(".payment-currency");
            const accountSel = rowEl.querySelector(".payment-account");
            const depotSel = rowEl.querySelector(".payment-depot");
            const gramInp = rowEl.querySelector(".payment-gram");
            const karatInp = rowEl.querySelector(".payment-karat");
            const lineTotalInp = rowEl.querySelector(".payment-line-total");
            const qtyLabel = rowEl.querySelector(".payment-qty-wrap label");
            const unitWrap = rowEl.querySelector(".payment-unit-wrap");
            const currencyWrap = rowEl.querySelector(".payment-currency-wrap");
            const accountWrap = rowEl.querySelector(".payment-account-wrap");
            const depotWrap = rowEl.querySelector(".payment-depot-wrap");
            const lineTotalWrap = rowEl.querySelector(".payment-line-total-wrap");

            syncTypeOptionsForMode(typeSel);

            const selectedOpt = typeSel ? typeSel.options[typeSel.selectedIndex] : null;
            let kind = selectedOpt ? String(selectedOpt.dataset.kind || "") : "";
            if (!kind && typeSel) {
                kind = inferKindFromType(typeSel.value);
            }
            if (paymentMode && !kind) {
                kind = "currency";
            }
            kind = String(kind || "").toLowerCase();
            if (kindInp) kindInp.value = kind;

            const isStockKind = ["product", "ziynet", "scrap"].includes(kind);
            const isGoldType = kind === "product";
            const needsAccount = ["cash", "card", "transfer", "currency"].includes(kind);

            if (qtyLabel) {
                if (paymentMode && (kind === "currency" || kind === "cash" || kind === "card" || kind === "transfer")) {
                    qtyLabel.textContent = "Tutar";
                } else if (paymentMode && kind === "scrap") {
                    qtyLabel.textContent = "Gram";
                } else {
                    qtyLabel.textContent = "Miktar";
                }
            }

            if (unitWrap) unitWrap.classList.toggle("hidden", !(paymentMode && isStockKind));
            if (currencyWrap) currencyWrap.classList.toggle("hidden", !paymentMode);
            if (accountWrap) accountWrap.classList.toggle("hidden", !(paymentMode && needsAccount));
            if (depotWrap) depotWrap.classList.toggle("hidden", !(paymentMode && isStockKind));
            if (lineTotalWrap) lineTotalWrap.classList.toggle("hidden", !paymentMode);
            rowEl.querySelectorAll(".bedel-gold-field").forEach((el) => {
                el.classList.toggle("hidden", !isGoldType);
            });

            if (typeSel) typeSel.required = paymentMode;
            if (qtyInp) qtyInp.required = paymentMode;
            if (unitInp) unitInp.required = paymentMode && isStockKind;
            if (curSel) curSel.required = paymentMode;
            if (accountSel) accountSel.required = paymentMode && needsAccount;
            if (depotSel) depotSel.required = paymentMode && isStockKind;
            if (gramInp) gramInp.required = isGoldType;
            if (karatInp) karatInp.required = isGoldType;

            if (paymentMode) {
                syncAccountOptions(accountSel, kind);
            } else if (accountSel) {
                accountSel.required = false;
            }

            const qty = parseNumber(qtyInp?.value || "0");
            const unit = paymentMode && isStockKind ? parseNumber(unitInp?.value || "0") : 1;
            const lineTotal = qty * (unit > 0 ? unit : 0);
            if (lineTotalInp) {
                lineTotalInp.value = formatAmount(lineTotal, 2);
            }

            const selectedTypeUpper = String(typeSel?.value || "").trim().toUpperCase();
            if (paymentMode && kind === "currency" && ["TRY", "USD", "EUR", "GBP"].includes(selectedTypeUpper) && curSel) {
                curSel.value = selectedTypeUpper;
            }

            const lineCurrency = String(curSel?.value || currentMainCurrency());
            const lineMain = paymentMode ? convertAmount(lineTotal, lineCurrency, currentMainCurrency()) : lineTotal;
            return {
                kind,
                type: String(typeSel?.value || ""),
                qty,
                unit,
                currency: lineCurrency,
                lineTotal,
                lineMain,
                bedelMode,
            };
        };

        const collectPaymentTotals = () => {
            const mainTotal = currentStockTotal();
            const mainCurrency = currentMainCurrency();
            const taxState = computeTaxTotals(mainTotal);
            const expectedTotal = taxState.grandTotal;
            let paidTotal = 0;
            let rowCount = 0;
            let hasMissingRate = false;
            let hasInvalidRow = false;

            if (!isPaymentMode()) {
                [...(bedelRows?.querySelectorAll(".bedel-row") || [])].forEach((rowEl) => {
                    syncBedelRow(rowEl);
                });
                if (stockMainTotalText) stockMainTotalText.textContent = "-";
                if (stockPaidTotalText) stockPaidTotalText.textContent = "-";
                if (stockPaidDiffText) {
                    stockPaidDiffText.textContent = "-";
                    stockPaidDiffText.classList.remove("txt-pos", "txt-neg");
                }
                return {
                    mainTotal: 0,
                    expectedTotal: 0,
                    taxTotal: 0,
                    paidTotal: 0,
                    diff: 0,
                    rowCount: 0,
                    hasMissingRate: false,
                    hasInvalidRow: false,
                    needsTaxSelection: false,
                };
            }

            [...(bedelRows?.querySelectorAll(".bedel-row") || [])].forEach((rowEl) => {
                const rowData = syncBedelRow(rowEl);
                if (!rowData) return;
                if (!rowData.type && rowData.qty <= 0) return;
                rowCount += 1;
                if (!rowData.type || rowData.qty <= 0) {
                    hasInvalidRow = true;
                    return;
                }
                if (rowData.lineMain === null) {
                    hasMissingRate = true;
                    return;
                }
                paidTotal += rowData.lineMain;
            });

            const diff = paidTotal - expectedTotal;
            if (stockMainTotalText) {
                let mainText = `${formatAmount(expectedTotal, 2)} ${mainCurrency}`;
                if (taxState.apply && taxState.taxTotal > 0) {
                    mainText += ` (Vergi: ${formatAmount(taxState.taxTotal, 2)} ${mainCurrency})`;
                }
                stockMainTotalText.textContent = mainText;
            }
            if (stockPaidTotalText) stockPaidTotalText.textContent = `${formatAmount(paidTotal, 2)} ${mainCurrency}`;
            if (stockPaidDiffText) {
                stockPaidDiffText.textContent = `${formatAmount(diff, 2)} ${mainCurrency}`;
                stockPaidDiffText.classList.remove("txt-pos", "txt-neg");
                if (Math.abs(diff) > 0.05) {
                    stockPaidDiffText.classList.add(diff > 0 ? "txt-pos" : "txt-neg");
                }
            }

            return {
                mainTotal,
                expectedTotal,
                taxTotal: taxState.taxTotal,
                paidTotal,
                diff,
                rowCount,
                hasMissingRate,
                hasInvalidRow,
                needsTaxSelection: taxState.apply && !taxState.hasSelection,
            };
        };

        const defaultPaymentSeed = () => {
            const selectedName = String(stockItemSelect?.value || "");
            const qty = parseNumber(stockQtyInput?.value || "0");
            const unit = parseNumber(stockUnitPrice?.value || "0");
            const currency = currentMainCurrency();
            const depot = String(stockDepotSelect?.value || "");

            if (isPaymentMode()) {
                const expectedTotal = computeTaxTotals(currentStockTotal()).grandTotal;
                return {
                    type: currency,
                    qty: expectedTotal > 0 ? formatAmount(expectedTotal, 2) : "",
                    unitPrice: "",
                    currency,
                    depot,
                    kind: "currency",
                };
            }

            let type = selectedName;
            let kind = inferKindFromType(type);
            if (!kind && bedelTpl) {
                const optionExists = [...bedelTpl.content.querySelectorAll(".payment-type option")]
                    .some((opt) => String(opt.value || "") === selectedName);
                if (!optionExists) {
                    type = currency;
                    kind = "currency";
                }
            }
            return {
                type,
                qty: qty > 0 ? formatAmount(qty, 3) : "",
                unitPrice: unit > 0 ? formatAmount(unit, 2) : "",
                currency,
                depot,
                kind,
            };
        };

        const addBedelRow = (seed = {}, markAuto = false) => {
            if (!bedelTpl || !bedelRows) return null;
            const node = bedelTpl.content.firstElementChild.cloneNode(true);
            const typeSel = node.querySelector(".payment-type");
            const kindInp = node.querySelector(".payment-kind");
            const qtyInp = node.querySelector(".payment-qty");
            const unitInp = node.querySelector(".payment-unit-price");
            const curSel = node.querySelector(".payment-currency");
            const depotSel = node.querySelector(".payment-depot");
            const removeBtn = node.querySelector(".bedel-remove");

            if (typeSel && seed.type) typeSel.value = String(seed.type);
            if (kindInp && seed.kind) kindInp.value = String(seed.kind);
            if (qtyInp && seed.qty !== undefined && seed.qty !== null) qtyInp.value = String(seed.qty);
            if (unitInp && seed.unitPrice !== undefined && seed.unitPrice !== null) unitInp.value = String(seed.unitPrice);
            if (curSel && seed.currency) curSel.value = String(seed.currency);
            if (depotSel && seed.depot) depotSel.value = String(seed.depot);
            if (markAuto) node.dataset.auto = "1";

            node.querySelectorAll("input,select").forEach((el) => {
                el.addEventListener("input", () => {
                    node.dataset.auto = "0";
                    collectPaymentTotals();
                });
                el.addEventListener("change", () => {
                    node.dataset.auto = "0";
                    collectPaymentTotals();
                });
            });
            if (typeSel) {
                typeSel.addEventListener("change", () => {
                    syncBedelRow(node);
                    collectPaymentTotals();
                });
            }
            if (removeBtn) {
                removeBtn.addEventListener("click", () => {
                    node.remove();
                    if (isBedelPanelMode() && !bedelRows.querySelector(".bedel-row")) {
                        addBedelRow(defaultPaymentSeed(), true);
                    }
                    collectPaymentTotals();
                });
            }

            bedelRows.appendChild(node);
            syncBedelRow(node);
            collectPaymentTotals();
            return node;
        };

        const ensureInitialPayment = (force = false) => {
            if (!bedelRows) return;
            const { price, currency } = currentPriceAndCurrency();
            if (stockCurrencySelect && currency) {
                const exists = [...stockCurrencySelect.options].some((opt) => opt.value === currency);
                if (exists && (force || !stockCurrencySelect.value)) {
                    stockCurrencySelect.value = currency;
                }
            }
            if (stockUnitPrice && price > 0 && (force || stockUnitPrice.value.trim() === "")) {
                stockUnitPrice.value = formatAmount(price, 2);
            }
            if (!isBedelPanelMode()) {
                collectPaymentTotals();
                return;
            }
            const first = bedelRows.querySelector(".bedel-row");
            if (!first) {
                addBedelRow(defaultPaymentSeed(), true);
                return;
            }
            if (force || first.dataset.auto === "1") {
                const seed = defaultPaymentSeed();
                const typeSel = first.querySelector(".payment-type");
                const kindInp = first.querySelector(".payment-kind");
                const qtyInp = first.querySelector(".payment-qty");
                const unitInp = first.querySelector(".payment-unit-price");
                const curSel = first.querySelector(".payment-currency");
                const depotSel = first.querySelector(".payment-depot");
                if (typeSel && seed.type) typeSel.value = String(seed.type);
                if (kindInp && seed.kind) kindInp.value = String(seed.kind);
                if (qtyInp && seed.qty !== "") qtyInp.value = String(seed.qty);
                if (unitInp && seed.unitPrice !== "") unitInp.value = String(seed.unitPrice);
                if (curSel && seed.currency) curSel.value = String(seed.currency);
                if (depotSel && seed.depot) depotSel.value = String(seed.depot);
                first.dataset.auto = "1";
                syncBedelRow(first);
            }
            collectPaymentTotals();
        };

        const resetPaymentRowsByMode = () => {
            if (!bedelRows || !stockPaid) return;
            const panelOn = isBedelPanelMode();
            const paymentMode = isPaymentMode();
            const modeKind = paymentMode ? "payment" : (isBedelMode() ? "bedel" : "none");
            const prevModeKind = String(stockPaid.dataset.modeKind || "");
            stockPaid.classList.toggle("hidden", !panelOn);
            if (stockPaymentTitle) {
                stockPaymentTitle.textContent = paymentMode ? "Odemeler" : "Karsilik / Bedel Listesi";
            }
            if (bedelAddBtn) {
                bedelAddBtn.textContent = paymentMode ? "Odeme Ekle" : "Bedel Ekle";
            }
            if (stockPaymentSummary) {
                stockPaymentSummary.classList.toggle("hidden", !paymentMode);
            }
            syncTaxPanel();
            if (prevModeKind && prevModeKind !== modeKind) {
                bedelRows.innerHTML = "";
            }
            stockPaid.dataset.modeKind = modeKind;
            if (!panelOn) {
                bedelRows.innerHTML = "";
                collectPaymentTotals();
                return;
            }
            if (!bedelRows.querySelector(".bedel-row")) {
                addBedelRow(defaultPaymentSeed(), true);
            } else {
                collectPaymentTotals();
            }
        };

        const renderBarcodeRows = () => {
            if (!stockBarcodeRows) return;
            const isGold = stockTypeInput && stockTypeInput.value === "Product";
            if (!isGold) {
                stockBarcodeRows.innerHTML = "";
                return;
            }

            const count = parseIntCount(stockQtyInput?.value || "0");
            const mode = currentMode();
            const isOut = mode === "Sale" || mode === "Out" || mode === "PaidOut";

            // Altın işlemlerinde barkod zorunlu.
            const req = "required";
            const prev = [...stockBarcodeRows.querySelectorAll(".barcode-row")].map((row) => ({
                bc: row.querySelector('input[name="barcode_code_list[]"]')?.value || "",
                gr: row.querySelector('input[name="barcode_gram_list[]"]')?.value || "",
                kr: row.querySelector('input[name="barcode_karat_list[]"]')?.value || "",
            }));

            let html = "";
            for (let i = 0; i < count; i++) {
                const p = prev[i] || { bc: "", gr: "", kr: "" };
                html += `
                    <div class="row barcode-row" style="margin:6px 0; display:flex; flex-wrap:wrap; align-items:center;">
                        <span class="tag">#${i + 1}</span>
                        <div style="display:flex; flex:1; min-width:150px; gap:5px;">
                            <input type="text" name="barcode_code_list[]" class="barcode-input-target" placeholder="Barkod Okutun/Yazın" value="${String(p.bc).replace(/"/g, "&quot;")}" ${req} style="flex:1;">
                            ${isOut ? '<button type="button" class="btn scan-barcode-btn">📷</button>' : ''}
                        </div>
                        <input type="text" name="barcode_gram_list[]" placeholder="Gram" value="${String(p.gr).replace(/"/g, "&quot;")}" ${req} ${isOut ? "readonly" : ""} style="width:70px; flex:initial;">
                        <input type="text" name="barcode_karat_list[]" placeholder="Ayar" value="${String(p.kr).replace(/"/g, "&quot;")}" ${req} ${isOut ? "readonly" : ""} style="width:60px; flex:initial;">
                    </div>
                `;
            }
            stockBarcodeRows.innerHTML = html;

            if (isOut) {
                stockBarcodeRows.querySelectorAll(".barcode-row").forEach((row) => {
                    const bcInput = row.querySelector('input[name="barcode_code_list[]"]');
                    const grInput = row.querySelector('input[name="barcode_gram_list[]"]');
                    const krInput = row.querySelector('input[name="barcode_karat_list[]"]');
                    if (!bcInput || !grInput || !krInput) return;
                    const applyBarcodeMeta = () => {
                        const bc = String(bcInput.value || "").trim();
                        if (!bc) {
                            grInput.value = "";
                            krInput.value = "";
                            return;
                        }
                        const meta = barcodeMeta[bc];
                        if (!meta) {
                            grInput.value = "";
                            krInput.value = "";
                            return;
                        }
                        const gramVal = Number(meta.gram || 0);
                        const karatVal = String(meta.karat || "");
                        grInput.value = gramVal > 0 ? gramVal.toFixed(3).replace(".", ",") : "";
                        krInput.value = karatVal;
                    };
                    bcInput.addEventListener("input", applyBarcodeMeta);
                    bcInput.addEventListener("change", applyBarcodeMeta);
                    applyBarcodeMeta();
                });
            }
        };

        const syncStockForm = () => {
            const isGold = stockTypeInput && stockTypeInput.value === "Product";
            if (stockGold) stockGold.classList.toggle("hidden", !isGold);
            renderBarcodeRows();
            resetPaymentRowsByMode();
            syncTaxPanel();
            ensureInitialPayment(false);
            collectPaymentTotals();
        };

        if (bedelAddBtn) {
            bedelAddBtn.addEventListener("click", () => {
                const seed = {
                    currency: currentMainCurrency(),
                    depot: String(stockDepotSelect?.value || ""),
                };
                addBedelRow(seed, false);
            });
        }

        if (stockModeInput) {
            stockModeInput.addEventListener("change", () => {
                resetPaymentRowsByMode();
                syncTaxPanel();
                ensureInitialPayment(true);
                syncStockForm();
            });
        }

        if (stockItemSelect) {
            stockItemSelect.addEventListener("change", () => {
                ensureInitialPayment(true);
                syncStockForm();
            });
        }

        if (stockQtyInput) {
            stockQtyInput.addEventListener("input", () => {
                ensureInitialPayment(true);
                renderBarcodeRows();
                collectPaymentTotals();
            });
            stockQtyInput.addEventListener("change", () => {
                ensureInitialPayment(true);
                renderBarcodeRows();
                collectPaymentTotals();
            });
        }

        if (stockUnitPrice) {
            stockUnitPrice.addEventListener("input", () => {
                ensureInitialPayment(false);
                collectPaymentTotals();
            });
            stockUnitPrice.addEventListener("change", () => {
                ensureInitialPayment(false);
                collectPaymentTotals();
            });
        }

        if (stockCurrencySelect) {
            stockCurrencySelect.addEventListener("change", () => {
                ensureInitialPayment(false);
                collectPaymentTotals();
            });
        }
        if (stockApplyTaxes) {
            stockApplyTaxes.addEventListener("change", () => {
                syncTaxPanel();
                ensureInitialPayment(false);
                collectPaymentTotals();
            });
        }
        stockTaxItems.forEach((item) => {
            item.addEventListener("change", () => {
                ensureInitialPayment(false);
                collectPaymentTotals();
            });
        });

        if (stockDepotSelect) {
            stockDepotSelect.addEventListener("change", () => {
                const first = bedelRows?.querySelector(".bedel-row");
                if (first && first.dataset.auto === "1") {
                    const firstDepot = first.querySelector(".payment-depot");
                    if (firstDepot) {
                        firstDepot.value = String(stockDepotSelect.value || "");
                    }
                }
                collectPaymentTotals();
            });
        }

        form.addEventListener("submit", (ev) => {
            if (!isPaymentMode()) return;
            const totals = collectPaymentTotals();
            if (totals.rowCount === 0) {
                ev.preventDefault();
                window.alert("Alis/Satis isleminde en az bir odeme satiri zorunludur.");
                return;
            }
            if (totals.hasInvalidRow) {
                ev.preventDefault();
                window.alert("Lutfen odeme satirlarindaki tur/miktar alanlarini doldurun.");
                return;
            }
            if (totals.hasMissingRate) {
                ev.preventDefault();
                window.alert("Kur donusumu icin gerekli doviz verisi bulunamadi.");
                return;
            }
            if (totals.needsTaxSelection) {
                ev.preventDefault();
                window.alert("Vergi uygulama secildi. Lutfen en az bir vergi tipi secin.");
                return;
            }
            if (Math.abs(totals.diff) > 0.05) {
                ev.preventDefault();
                window.alert("Odeme toplami islem tutari (vergi dahil) ile eslesmelidir.");
            }
        });

        syncStockForm();
    };

    const setupExchangeAndVirman = () => {
        const syncExchangeSide = (prefix) => {
            const typeSel = document.getElementById(`exchange_${prefix}_type`);
            const kindInput = document.getElementById(`exchange_${prefix}_kind`);
            const amountLabel = document.getElementById(`exchange_${prefix}_amount_label`);
            const gramWrap = document.getElementById(`exchange_${prefix}_gram_wrap`);
            const karatWrap = document.getElementById(`exchange_${prefix}_karat_wrap`);
            const gramInp = document.getElementById(`exchange_${prefix}_gram`);
            const karatInp = document.getElementById(`exchange_${prefix}_karat`);
            if (!typeSel || !amountLabel) return;

            const selectedOpt = typeSel.options[typeSel.selectedIndex];
            const kind = selectedOpt ? String(selectedOpt.dataset.kind || "") : "currency";
            const isGoldType = kind === "product";

            if (kindInput) kindInput.value = kind || "currency";

            if (kind === "scrap") {
                amountLabel.textContent = `${prefix === "out" ? "Verilen" : "Alınan"} Gram`;
            } else if (kind === "ziynet" || isGoldType) {
                amountLabel.textContent = `${prefix === "out" ? "Verilen" : "Alınan"} Adet`;
            } else {
                amountLabel.textContent = `${prefix === "out" ? "Verilen" : "Alınan"} Miktar`;
            }

            if (gramWrap) gramWrap.classList.toggle("hidden", !isGoldType);
            if (karatWrap) karatWrap.classList.toggle("hidden", !isGoldType);
            if (gramInp) gramInp.required = isGoldType;
            if (karatInp) karatInp.required = isGoldType;
        };

        const exOutType = document.getElementById("exchange_out_type");
        const exInType = document.getElementById("exchange_in_type");
        if (exOutType) {
            exOutType.addEventListener("change", () => syncExchangeSide("out"));
            syncExchangeSide("out");
        }
        if (exInType) {
            exInType.addEventListener("change", () => syncExchangeSide("in"));
            syncExchangeSide("in");
        }

        const virmanType = document.getElementById("virman_asset_type");
        const virmanGramWrap = document.getElementById("virman_gram_wrap");
        const virmanKaratWrap = document.getElementById("virman_karat_wrap");
        const virmanGram = document.getElementById("virman_gram");
        const virmanKarat = document.getElementById("virman_karat");

        const syncVirmanType = () => {
            if (!virmanType || !virmanGramWrap || !virmanKaratWrap) return;
            const selectedOpt = virmanType.options[virmanType.selectedIndex];
            const kind = selectedOpt ? String(selectedOpt.dataset.kind || "") : "currency";
            const isGoldType = kind === "product";
            virmanGramWrap.classList.toggle("hidden", !isGoldType);
            virmanKaratWrap.classList.toggle("hidden", !isGoldType);
            if (virmanGram) virmanGram.required = isGoldType;
            if (virmanKarat) virmanKarat.required = isGoldType;
        };

        if (virmanType) {
            virmanType.addEventListener("change", syncVirmanType);
            syncVirmanType();
        }
    };

    const setupWebSessionHeartbeat = () => {
        const config = window.GOLDER_WEB_SESSION;
        if (!config || typeof config !== "object") return;

        const sessionId = String(config.sessionId || "").trim();
        const heartbeatUrl = String(config.heartbeatUrl || "").trim();
        const heartbeatSeconds = Number(config.heartbeatIntervalSeconds || 25);
        if (!sessionId || !heartbeatUrl) return;

        const intervalMs = Math.max(20000, Math.min(30000, heartbeatSeconds * 1000));
        const tabStorageKey = "golder_web_tab_id";
        const tabId = (() => {
            try {
                const existing = window.sessionStorage.getItem(tabStorageKey);
                if (existing) return existing;
                const created = typeof crypto.randomUUID === "function"
                    ? crypto.randomUUID()
                    : `tab-${Date.now()}-${Math.random().toString(16).slice(2)}`;
                window.sessionStorage.setItem(tabStorageKey, created);
                return created;
            } catch (_err) {
                return `tab-${Date.now()}-${Math.random().toString(16).slice(2)}`;
            }
        })();

        let heartbeatTimer = 0;
        let heartbeatInFlight = false;
        let lastHeartbeatTime = 0;

        const redirectToLogin = () => {
            if (document.visibilityState === "hidden") return;
            window.location.assign("index.php?act=customer_login");
        };

        const sendJson = async (url, payload, keepalive = false) => {
            const response = await window.fetch(url, {
                method: "POST",
                credentials: "same-origin",
                headers: {
                    "Content-Type": "application/json",
                    "X-Requested-With": "XMLHttpRequest",
                },
                body: JSON.stringify(payload),
                keepalive,
            });
            if (response.status === 401) {
                redirectToLogin();
                return null;
            }
            return response;
        };

        const sendHeartbeat = async () => {
            const now = Date.now();
            if (now - lastHeartbeatTime < 2000) return;
            if (heartbeatInFlight) return;
            heartbeatInFlight = true;
            lastHeartbeatTime = now;
            try {
                const response = await sendJson(heartbeatUrl, {
                    sessionId,
                    tabId,
                });
                if (!response || !response.ok) {
                    return;
                }
                const payload = await response.json().catch(() => null);
                if (payload && payload.status === "error" && payload.code === "SESSION_EXPIRED") {
                    redirectToLogin();
                }
            } catch (_err) {
            } finally {
                heartbeatInFlight = false;
            }
        };

        void sendHeartbeat();
        heartbeatTimer = window.setInterval(() => {
            void sendHeartbeat();
        }, intervalMs);

        document.addEventListener("visibilitychange", () => {
            if (document.visibilityState === "visible") {
                void sendHeartbeat();
            }
        });

        // Refresh ve sayfa içi gezinmelerde disconnect beacon göndermek
        // oturumu gereksiz yere kapatabiliyor. Bu yüzden kapanışı heartbeat timeout'una bırakıyoruz.
        window.addEventListener("online", () => {
            void sendHeartbeat();
        });

        window.addEventListener("pageshow", () => {
            if (!heartbeatTimer) {
                heartbeatTimer = window.setInterval(() => {
                    void sendHeartbeat();
                }, intervalMs);
            }
            void sendHeartbeat();
        });
    };

    setupSegmentTabs();
    setupAutocomplete();
    setupCashForm();
    setupStockForm();
    setupExchangeAndVirman();
    setupWebSessionHeartbeat();
    const ensureDeviceNameCookie = () => {
        try {
            const name = window.localStorage ? String(localStorage.getItem("golder_web_dev_name") || "").trim() : "";
            if (!name) return;
            const maxAge = 60 * 60 * 24 * 3650;
            document.cookie = `golder_web_dev_name=${encodeURIComponent(name)}; path=/; max-age=${maxAge}`;
        } catch (_err) {}
    };
    ensureDeviceNameCookie();

    const setupBarcodeScanner = () => {
        const modal = document.getElementById("global-scanner-modal");
        const closeBtn = document.getElementById("global-scanner-close");
        if (!modal) return;

        let html5QrCode = null;
        let currentTargetInput = null;

        // Scanner kapatma fonksiyonu
        const stopScanner = () => {
            if (html5QrCode) {
                html5QrCode
                    .stop()
                    .catch((err) => console.log("Scanner stop error:", err))
                    .finally(() => {
                        html5QrCode.clear();
                        html5QrCode = null;
                    });
            }
            modal.close();
            currentTargetInput = null;
        };

        closeBtn.addEventListener("click", stopScanner);

        // Dinamik eklenen butonları yakalamak için event delegation
        document.body.addEventListener("click", (e) => {
            if (e.target && (e.target.classList.contains("scan-barcode-btn") || e.target.closest(".scan-barcode-btn"))) {
                e.preventDefault();
                const btn = e.target.classList.contains("scan-barcode-btn") ? e.target : e.target.closest(".scan-barcode-btn");

                // Butonun yanındaki inputu bul
                currentTargetInput = btn.parentElement.querySelector(".barcode-input-target");
                if (!currentTargetInput) return;

                modal.showModal();

                if (!html5QrCode) {
                    // Html5Qrcode nesnesi index.php'den import edildi (device_pair kısmından)
                    html5QrCode = new Html5Qrcode("global-reader");
                }

                html5QrCode
                    .start(
                        { facingMode: "environment" },
                        {
                            fps: 10,
                            qrbox: { width: 250, height: 100 }, // Barkod (dikdörtgen) formatı için
                        },
                        (decodedText) => {
                            // Başarılı okuma
                            if (currentTargetInput) {
                                currentTargetInput.value = decodedText;
                                // Manuel değişiklik gibi tetikle ki fiyat vs. hesaplansın
                                currentTargetInput.dispatchEvent(new Event("input", { bubbles: true }));
                                currentTargetInput.dispatchEvent(new Event("change", { bubbles: true }));
                            }
                            stopScanner(); // Okuyunca kapat
                        },
                        (_errorMessage) => {
                            // Okuma devam ediyor...
                        }
                    )
                    .catch((_err) => {
                        alert("Kamera başlatılamadı. İzinleri kontrol edin.");
                        stopScanner();
                    });
            }
        });
    };

    // Kurulumu çağır
    setupBarcodeScanner();

    // --- TELEFONDAN OTOMATİK BARKOD OKUMA SİSTEMİ ---
    const setupRemoteScannerListener = () => {
        let isScannerOpen = false;
        let currentRequestId = null;

        const checkPendingScan = async () => {
            if (isScannerOpen || document.visibilityState === "hidden") return;
            try {
                const res = await fetch("api/scanner/check.php", {
                    method: "POST",
                    headers: { "Content-Type": "application/json" },
                    body: JSON.stringify({})
                });
                const data = await res.json();
                if (data.status === "ok" && data.has_request && data.request_id) {
                    currentRequestId = data.request_id;
                    openRemoteScannerModal();
                }
            } catch (e) {}
        };

        const openRemoteScannerModal = () => {
            isScannerOpen = true;
            const modal = document.getElementById("global-scanner-modal");
            const title = modal.querySelector("h3");
            title.textContent = "🖥️ Masaüstü Barkod Bekliyor...";
            title.style.color = "var(--warning)";
            modal.showModal();

            if (window.html5QrCodeGlobal) {
                window.html5QrCodeGlobal.stop().catch(()=>{});
            } else {
                window.html5QrCodeGlobal = new Html5Qrcode("global-reader");
            }

            window.html5QrCodeGlobal.start(
                { facingMode: "environment" },
                { fps: 10, qrbox: { width: 250, height: 100 } },
                (decodedText) => {
                    // Barkod Okundu!
                    submitBarcodeToDesktop(decodedText, "completed");
                    closeRemoteScannerModal();
                },
                () => {}
            ).catch(() => {
                alert("Kameraya ulaşılamadı. İzinleri kontrol edin.");
                submitBarcodeToDesktop("", "cancelled");
                closeRemoteScannerModal();
            });
        };

        const closeRemoteScannerModal = () => {
            const modal = document.getElementById("global-scanner-modal");
            if (window.html5QrCodeGlobal) {
                window.html5QrCodeGlobal.stop().catch(()=>{});
            }
            modal.close();
            const title = modal.querySelector("h3");
            title.textContent = "Barkod Okut";
            title.style.color = "var(--primary)";
            
            setTimeout(() => { isScannerOpen = false; currentRequestId = null; }, 3000); // 3 sn bekle ki tekrar açılmasın
        };

        const submitBarcodeToDesktop = async (barcode, action) => {
            if (!currentRequestId) return;
            try {
                await fetch("api/scanner/submit.php", {
                    method: "POST",
                    headers: { "Content-Type": "application/json" },
                    body: JSON.stringify({ request_id: currentRequestId, barcode: barcode, scan_action: action })
                });
            } catch (e) {}
        };

        // Kapatma butonuna basıldığında iptal et
        const closeBtn = document.getElementById("global-scanner-close");
        if(closeBtn) {
            closeBtn.addEventListener("click", () => {
                if (isScannerOpen) {
                    submitBarcodeToDesktop("", "cancelled");
                    closeRemoteScannerModal();
                }
            });
        }

        // Her 2.5 saniyede bir kontrol et
        setInterval(checkPendingScan, 2500);
    };

    setupRemoteScannerListener();
})();





