/**
 * PaymentWidget - переиспользуемый виджет для оплаты заказа.
 * Поддерживает одиночную и смешанную оплату.
 *
 * @example
 * const widget = new PaymentWidget({
 *   containerId: 'paymentContainer',
 *   mode: 'single', // или 'mixed'
 *   order: { id: 1, total: 5000, amount_due: 5000 },
 *   customer: { id: 1, wallet_balance: 1000 },
 *   paymentMethods: [
 *     { id: 1, code: 'account_balance', name: 'С баланса счёта' },
 *     { id: 2, code: 'cash', name: 'Наличными' },
 *     ...
 *   ],
 *   onSubmit: (payments) => { console.log(payments); }
 * });
 */
export class PaymentWidget {
    constructor(options = {}) {
        this.containerId = options.containerId;
        this.mode = options.mode || 'single'; // 'single' | 'mixed'
        this.order = options.order;
        this.customer = options.customer;
        this.paymentMethods = options.paymentMethods || [];
        this.onSubmit = options.onSubmit || (() => {});

        // Внутреннее состояние
        this.payments = []; // [{ method_id, method_code, method_name, amount, notes }]
        this.selectedMethod = null; // Для single mode

        this.init();
    }

    init() {
        this.render();
        this.attachEvents();
    }

    render() {
        const container = document.getElementById(this.containerId);
        if (!container) {
            console.error(`Container #${this.containerId} not found`);
            return;
        }

        if (this.mode === 'single') {
            // SINGLE MODE - старый UI (не трогаем)
            container.innerHTML = `
                <!-- Способы оплаты -->
                <div class="mb-2">
                    <label class="form-label fw-semibold small mb-1">Способ оплаты</label>
                    <div class="d-flex flex-wrap gap-1" id="${this.containerId}-methods">
                        ${this.renderPaymentMethods()}
                    </div>
                </div>

                <!-- Сумма -->
                <div class="mb-2">
                    <label class="form-label fw-semibold small mb-1">Сумма</label>
                    <div class="input-group input-group-sm">
                        <input type="number"
                               class="form-control form-control-sm"
                               id="${this.containerId}-amount"
                               step="0.01"
                               min="0.01"
                               value="${this.order.amount_due}"
                               placeholder="0.00">
                        <span class="input-group-text">руб.</span>
                    </div>
                    <small class="text-muted" id="${this.containerId}-hint"></small>
                </div>
            `;
        } else {
            // MIXED MODE - новый UI с построчным добавлением
            container.innerHTML = `
                <div id="${this.containerId}-payment-rows"></div>
                <div class="mb-2 text-center">
                    <small class="text-muted" id="${this.containerId}-remaining-hint">
                        Осталось оплатить: ${this.order.amount_due.toFixed(2)} руб.
                    </small>
                </div>
                <button type="button"
                        class="btn btn-sm btn-outline-primary w-100"
                        id="${this.containerId}-add-row-btn">
                    <i class="bi bi-plus-circle"></i> Добавить еще часть платежа
                </button>
            `;

            // Добавляем первую строку автоматически
            this.addPaymentRow();
        }
    }

    renderPaymentMethods() {
        return this.paymentMethods.map(method => {
            const showWallet = method.code === 'account_balance' && this.customer;
            return `
                <button type="button"
                        class="btn btn-sm btn-outline-primary payment-method-btn"
                        data-method-id="${method.id}"
                        data-method-code="${method.code}"
                        data-method-name="${method.name}"
                        style="font-size: 0.85rem;">
                    ${method.name}
                    ${showWallet ? `
                        <span class="badge bg-info ms-1" style="font-size: 0.75rem;">
                            ${this.customer.wallet_balance.toFixed(2)}
                        </span>
                    ` : ''}
                </button>
            `;
        }).join('');
    }

    // renderPaymentsList() УДАЛЕН - больше не используется в новом UI

    // ========== НОВЫЕ МЕТОДЫ ДЛЯ MIXED MODE ==========

    addPaymentRow() {
        const rowId = Date.now(); // уникальный ID для строки
        const remaining = this.order.amount_due - this.getTotalPayments();

        const row = {
            id: rowId,
            method_id: null,
            method_code: null,
            method_name: null,
            amount: remaining
        };

        this.payments.push(row);
        this.renderPaymentRows();
    }

    renderPaymentRows() {
        const container = document.getElementById(`${this.containerId}-payment-rows`);
        if (!container) return;

        container.innerHTML = this.payments.map((payment, index) => {
            // Редактируемая строка (без системы fixed/unfixed)
            const methodsOptions = this.paymentMethods.map(m =>
                `<option value="${m.id}"
                         data-code="${m.code}"
                         data-name="${m.name}"
                         ${payment.method_id == m.id ? 'selected' : ''}>
                    ${m.name}
                    ${m.code === 'account_balance' && this.customer ?
                      ` (${this.customer.wallet_balance.toFixed(2)} руб.)` : ''}
                </option>`
            ).join('');

            return `
                <div class="payment-row mb-2 p-2 border rounded" data-index="${index}">
                    <div class="row g-2 align-items-center">
                        <div class="col-5">
                            <select class="form-select form-select-sm payment-method-select"
                                    data-index="${index}">
                                <option value="">Выберите способ</option>
                                ${methodsOptions}
                            </select>
                        </div>
                        <div class="col-5">
                            <div class="input-group input-group-sm">
                                <input type="number"
                                       class="form-control payment-amount-input"
                                       data-index="${index}"
                                       value="${payment.amount.toFixed(2)}"
                                       step="0.01"
                                       min="0.01">
                                <span class="input-group-text">руб.</span>
                            </div>
                            <small class="text-danger payment-error"
                                   data-index="${index}"
                                   style="display: none;"></small>
                        </div>
                        <div class="col-2 text-end">
                            <button type="button"
                                    class="btn btn-sm btn-outline-danger remove-payment-row"
                                    data-index="${index}">
                                <i class="bi bi-trash"></i>
                            </button>
                        </div>
                    </div>
                </div>
            `;
        }).join('');

        // Обновляем подсказку об остатке
        this.updateRemainingHint();

        // Прикрепляем обработчики событий
        this.attachPaymentRowEvents();
    }

    attachPaymentRowEvents() {
        // Обработчик выбора способа оплаты
        document.querySelectorAll('.payment-method-select').forEach(select => {
            select.addEventListener('change', (e) => {
                const index = parseInt(e.target.dataset.index);
                const option = e.target.selectedOptions[0];

                if (option.value) {
                    this.payments[index].method_id = option.value;
                    this.payments[index].method_code = option.dataset.code;
                    this.payments[index].method_name = option.dataset.name;

                    // Автофокус на поле суммы
                    const amountInput = document.querySelector(`.payment-amount-input[data-index="${index}"]`);
                    if (amountInput) {
                        amountInput.focus();
                        amountInput.select(); // Выделяем всю сумму для быстрой замены
                    }

                    // Если кошелек - ограничить сумму
                    if (option.dataset.code === 'account_balance' && this.customer) {
                        const remaining = this.order.amount_due - this.getTotalPayments();
                        const maxAmount = Math.min(remaining, this.customer.wallet_balance);
                        amountInput.value = maxAmount.toFixed(2);
                        amountInput.max = maxAmount;
                    }
                }
            });
        });

        // Обработчик изменения суммы
        document.querySelectorAll('.payment-amount-input').forEach(input => {
            input.addEventListener('input', (e) => {
                const index = parseInt(e.target.dataset.index);
                this.payments[index].amount = parseFloat(e.target.value) || 0;
                // Real-time обновление остатка!
                this.updateRemainingHint();
            });
        });

        // Обработчик удаления (корзина)
        document.querySelectorAll('.remove-payment-row').forEach(btn => {
            btn.addEventListener('click', (e) => {
                const index = parseInt(e.target.closest('button').dataset.index);
                this.removePaymentRow(index);
            });
        });

        // Обработчик кнопки "Добавить еще"
        const addRowBtn = document.getElementById(`${this.containerId}-add-row-btn`);
        if (addRowBtn) {
            // Используем replaceWith для пересоздания элемента и удаления всех обработчиков
            const newBtn = addRowBtn.cloneNode(true);
            addRowBtn.replaceWith(newBtn);
            newBtn.addEventListener('click', () => this.addPaymentRow());
        }
    }

    // ========== КОНЕЦ НОВЫХ МЕТОДОВ ==========

    attachEvents() {
        // Выбор способа оплаты (только для single mode)
        if (this.mode === 'single') {
            document.querySelectorAll(`#${this.containerId}-methods .payment-method-btn`).forEach(btn => {
                btn.addEventListener('click', () => this.selectPaymentMethod(btn));
            });
        }

        // Для mixed mode обработчики событий прикрепляются в attachPaymentRowEvents()
        // который вызывается из renderPaymentRows()
    }

    selectPaymentMethod(btnElement) {
        // Снимаем выделение
        document.querySelectorAll(`#${this.containerId}-methods .payment-method-btn`).forEach(b => {
            b.classList.remove('active');
        });

        // Выделяем выбранный
        btnElement.classList.add('active');

        this.selectedMethod = {
            id: btnElement.dataset.methodId,
            code: btnElement.dataset.methodCode,
            name: btnElement.dataset.methodName
        };

        // Валидация для кошелька
        const amountInput = document.getElementById(`${this.containerId}-amount`);
        const hint = document.getElementById(`${this.containerId}-hint`);

        // Вычисляем остаток с учетом уже добавленных платежей
        const remaining = this.order.amount_due - this.getTotalPayments();

        if (this.selectedMethod.code === 'account_balance' && this.customer) {
            const maxAmount = Math.min(remaining, this.customer.wallet_balance);
            amountInput.max = maxAmount;
            amountInput.value = maxAmount.toFixed(2);
            hint.textContent = `Макс: ${maxAmount.toFixed(2)} руб. | Осталось: ${remaining.toFixed(2)} руб.`;
        } else {
            amountInput.removeAttribute('max');
            amountInput.value = remaining.toFixed(2);
            hint.textContent = `Осталось оплатить: ${remaining.toFixed(2)} руб.`;
        }
    }

    // СТАРЫЕ МЕТОДЫ addPayment(), removePayment() и updatePaymentsList() УДАЛЕНЫ
    // Теперь используются новые методы для построчного UI

    removePaymentRow(index) {
        this.payments.splice(index, 1);

        // Если удалили все строки - добавить одну пустую
        if (this.payments.length === 0) {
            this.addPaymentRow();
        } else {
            this.renderPaymentRows();
        }
    }

    updateRemainingHint() {
        const hintEl = document.getElementById(`${this.containerId}-remaining-hint`);
        const addRowBtn = document.getElementById(`${this.containerId}-add-row-btn`);
        if (!hintEl) return;

        const totalPaid = this.getTotalPayments();
        const remaining = this.order.amount_due - totalPaid;

        if (totalPaid > this.order.amount_due) {
            // Превышение суммы
            const excess = totalPaid - this.order.amount_due;
            hintEl.innerHTML = '<strong class="text-danger">⚠ Превышение: +' +
                              excess.toFixed(2) + ' руб.</strong>';
            if (addRowBtn) addRowBtn.style.display = 'none';
        } else if (remaining <= 0) {
            // Точная оплата
            hintEl.innerHTML = '<strong class="text-success">✅ Оплачено полностью: ' +
                              this.order.amount_due.toFixed(2) + ' руб.</strong>';
            if (addRowBtn) addRowBtn.style.display = 'none';
        } else {
            // Осталось оплатить
            hintEl.textContent = 'Осталось оплатить: ' + remaining.toFixed(2) + ' руб.';
            if (addRowBtn) addRowBtn.style.display = 'block';
        }
    }

    getTotalPayments() {
        return this.payments
            .filter(p => p.method_id)  // Считать только если выбран способ оплаты
            .reduce((sum, p) => sum + p.amount, 0);
    }

    validate() {
        if (this.mode === 'single') {
            // Одиночная оплата
            if (!this.selectedMethod) {
                throw new Error('Выберите способ оплаты');
            }

            const amountInput = document.getElementById(`${this.containerId}-amount`);
            const amount = parseFloat(amountInput.value);

            if (amount <= 0 || isNaN(amount)) {
                throw new Error('Введите сумму больше 0');
            }

            if (amount > this.order.amount_due) {
                throw new Error(`Сумма превышает остаток к оплате (${this.order.amount_due.toFixed(2)} руб.)`);
            }

            // Проверка кошелька
            if (this.selectedMethod.code === 'account_balance' && this.customer) {
                if (amount > this.customer.wallet_balance) {
                    throw new Error(`Недостаточно средств в кошельке (${this.customer.wallet_balance.toFixed(2)} руб.)`);
                }
            }

        } else {
            // Смешанная оплата
            const validPayments = this.payments.filter(p => p.method_id && p.amount > 0);

            if (validPayments.length === 0) {
                throw new Error('Добавьте хотя бы один платеж');
            }

            // Проверить незавершенные платежи
            const incompletePayments = this.payments.filter(p =>
                (p.method_id && !p.amount) || (!p.method_id && p.amount)
            );

            if (incompletePayments.length > 0) {
                throw new Error('Заполните все поля или удалите незавершенные строки');
            }

            const total = this.getTotalPayments();

            if (total > this.order.amount_due) {
                const excess = total - this.order.amount_due;
                throw new Error(`Сумма платежей превышает остаток к оплате на ${excess.toFixed(2)} руб.`);
            }

            // Проверка кошелька
            if (this.customer) {
                const walletPayments = validPayments.filter(p => p.method_code === 'account_balance');
                const walletTotal = walletPayments.reduce((sum, p) => sum + p.amount, 0);

                if (walletTotal > this.customer.wallet_balance) {
                    throw new Error(`Недостаточно средств в кошельке (${this.customer.wallet_balance.toFixed(2)} руб.)`);
                }
            }
        }

        return true;
    }

    submit() {
        try {
            this.validate();

            let paymentsData;

            if (this.mode === 'single') {
                // Одиночная оплата
                const amountInput = document.getElementById(`${this.containerId}-amount`);
                const amount = parseFloat(amountInput.value);

                // Проверка на частичную оплату
                if (amount < this.order.amount_due) {
                    const confirmed = confirm(
                        'Вы хотите закрыть заказ, который оплачен частично?\n\n' +
                        'Нажмите ОК, чтобы создать заказ с частичной оплатой.\n' +
                        'Нажмите Отмена, чтобы вернуться и выбрать смешанную оплату.'
                    );
                    if (!confirmed) {
                        return; // Пользователь отменил действие
                    }
                }

                paymentsData = [{
                    payment_method: this.selectedMethod.code,
                    amount: amount,
                    notes: ''
                }];
            } else {
                // Смешанная оплата - берем только заполненные
                paymentsData = this.payments
                    .filter(p => p.method_id && p.amount > 0)
                    .map(p => ({
                        payment_method: p.method_code,
                        amount: p.amount,
                        notes: ''
                    }));
            }

            this.onSubmit(paymentsData);

        } catch (error) {
            alert(error.message);
        }
    }
}
