(function () {
    'use strict';

    var state = {
        data: null,
        mode: 'seller',
        selectedSellerID: '',
        busy: false,
    };

    function $(id) {
        return document.getElementById(id);
    }

    function t(key, fallback) {
        return window.HyAppI18n && window.HyAppI18n.t
            ? window.HyAppI18n.t(key, fallback)
            : fallback || key;
    }

    function toast(message) {
        if (window.HyAppToast) window.HyAppToast.show(message);
    }

    function number(value) {
        var normalized = value || 0;
        if (
            typeof BigInt === 'function' &&
            typeof normalized === 'string' &&
            /^-?\d+$/.test(normalized)
        ) {
            return new Intl.NumberFormat().format(BigInt(normalized));
        }
        return Number(normalized).toLocaleString(undefined, {
            maximumFractionDigits: 0,
        });
    }

    function amount() {
        var value = Number($('pointAmount').value || 0);
        return Number.isSafeInteger(value) && value > 0 ? value : 0;
    }

    function selectedSeller() {
        if (!state.data) return null;
        return state.data.sellers.find(function (seller) {
            return seller.userId === state.selectedSellerID;
        });
    }

    function setBusy(value) {
        state.busy = value;
        document.body.classList.toggle('is-busy', value);
        $('sellerSubmit').disabled = value || !selectedSeller();
        $('usdtSubmit').disabled = value;
        $('saveAddressButton').disabled = value;
    }

    function renderOverview() {
        if (!state.data) return;
        $('pointBalance').textContent = number(state.data.balance.available);
        $('balanceUSD').textContent =
            '≈ ' + state.data.balance.displayUSD + ' USDT';
        $('addressInput').value = state.data.address || '';
        $('addressStatus').classList.toggle(
            'has-address',
            Boolean(state.data.address)
        );
        $('addressStatus').textContent = state.data.address
            ? t('fami_wallet.saved_address', 'Saved address:') +
              ' ' +
              state.data.address
            : t('fami_wallet.no_address', 'No USDT address saved.');
        $('policyCaption').textContent =
            t('fami_wallet.policy_caption', 'Rate and fee are set by Admin.') +
            ' · 1 USDT = ' +
            number(state.data.pointsPerUSD) +
            ' POINT · ' +
            (state.data.feeBPS / 100).toFixed(2) +
            '%';
        if (!$('pointAmount').value && state.data.minimumPoints > 0) {
            $('pointAmount').value = String(state.data.minimumPoints);
        }
        renderConversion();
    }

    function renderSellers() {
        var sellers = state.data ? state.data.sellers : [];
        if (
            sellers.length &&
            !sellers.some(function (seller) {
                return seller.userId === state.selectedSellerID;
            })
        ) {
            state.selectedSellerID = sellers[0].userId;
        }
        $('sellerList').innerHTML = sellers
            .map(function (seller) {
                var selected = seller.userId === state.selectedSellerID;
                var avatar = seller.avatar
                    ? '<img src="' + escapeHTML(seller.avatar) + '" alt="" />'
                    : escapeHTML(
                          (seller.nickname || 'C').charAt(0).toUpperCase()
                      );
                return (
                    '<button class="seller-card" type="button" data-seller-id="' +
                    escapeHTML(seller.userId) +
                    '" aria-pressed="' +
                    selected +
                    '"><span class="seller-avatar">' +
                    avatar +
                    '</span><span class="seller-copy"><strong>' +
                    escapeHTML(seller.nickname || '—') +
                    '</strong><span>' +
                    t('fami_common.uid_prefix', 'UID:') +
                    ' ' +
                    escapeHTML(seller.displayUserId || seller.userId) +
                    '</span><span class="seller-ratio">' +
                    number(seller.pointAmount) +
                    ' : ' +
                    number(seller.sellerCoinAmount) +
                    '</span></span><span class="seller-check" aria-hidden="true">' +
                    (selected ? '✓' : '○') +
                    '</span></button>'
                );
            })
            .join('');
        $('sellerEmpty').hidden = sellers.length > 0;
        setBusy(state.busy);
    }

    function renderHistory() {
        var items = state.data ? state.data.history || [] : [];
        $('historyList').innerHTML = items
            .map(function (item) {
                var seller = item.counterpartyUserId
                    ? ' · UID ' + escapeHTML(item.counterpartyUserId)
                    : '';
                return (
                    '<article class="history-item"><strong>' +
                    escapeHTML(historyLabel(item.bizType)) +
                    seller +
                    '</strong><span class="history-amount">' +
                    (item.availableDelta > 0 ? '+' : '') +
                    number(item.availableDelta) +
                    '</span><small>' +
                    dateTime(item.createdAtMS) +
                    '</small></article>'
                );
            })
            .join('');
        $('historyEmpty').textContent = t(
            'fami_wallet.no_history',
            'No withdrawal records'
        );
        $('historyEmpty').hidden = items.length > 0;
        if (state.data && state.data.historyUnavailable) {
            $('historyEmpty').hidden = false;
            $('historyEmpty').textContent = t(
                'fami_wallet.history_unavailable',
                'History is temporarily unavailable.'
            );
        }
    }

    function historyLabel(bizType) {
        if (bizType === 'point_transfer_to_coin_seller') {
            return t('fami_wallet.seller_withdrawal', 'Coin seller withdrawal');
        }
        if (String(bizType).indexOf('withdrawal') >= 0) {
            return t('fami_wallet.usdt_withdrawal', 'USDT withdrawal');
        }
        return t('fami_wallet.point_transaction', 'POINT transaction');
    }

    function renderConversion() {
        var points = amount();
        if (!state.data || !points) {
            $('estimatedReceive').textContent = '—';
            return;
        }
        if (state.mode === 'seller') {
            var seller = selectedSeller();
            var receive = seller ? ratioAmount(points, seller) : '0';
            $('estimatedReceive').textContent =
                number(receive) +
                ' ' +
                t('fami_wallet.seller_coin', 'seller coins');
            return;
        }
        var fee = Math.floor((points * state.data.feeBPS) / 10000);
        var net = points - fee;
        $('estimatedReceive').textContent =
            (net / state.data.pointsPerUSD).toFixed(2) + ' USDT';
    }

    function ratioAmount(points, seller) {
        // 余额可达到万亿级，Number 中间乘法会超过安全整数；BigInt 只用于前端预计值，最终到账仍由 wallet-service 计算。
        if (typeof BigInt === 'function') {
            return (
                (BigInt(points) * BigInt(seller.sellerCoinAmount)) /
                BigInt(seller.pointAmount)
            ).toString();
        }
        return String(
            Math.floor((points * seller.sellerCoinAmount) / seller.pointAmount)
        );
    }

    function selectMode(mode) {
        state.mode = mode === 'usdt' ? 'usdt' : 'seller';
        $('sellerPanel').hidden = state.mode !== 'seller';
        $('usdtPanel').hidden = state.mode !== 'usdt';
        document.querySelectorAll('[data-mode]').forEach(function (button) {
            button.setAttribute(
                'aria-selected',
                button.getAttribute('data-mode') === state.mode
                    ? 'true'
                    : 'false'
            );
        });
        renderConversion();
    }

    function load() {
        setBusy(true);
        return window.HyGuild.wallet
            .load()
            .then(function (data) {
                state.data = data;
                renderOverview();
                renderSellers();
                renderHistory();
            })
            .catch(function () {
                toast(t('fami_wallet.load_failed', 'Unable to load wallet.'));
            })
            .finally(function () {
                setBusy(false);
            });
    }

    function submitSeller() {
        var seller = selectedSeller();
        var points = amount();
        if (!seller || !validateAmount(points, state.data.minimumPoints))
            return;
        setBusy(true);
        window.HyGuild.wallet
            .transferToCoinSeller(seller.userId, points)
            .then(function () {
                toast(t('fami_wallet.submitted', 'Withdrawal submitted.'));
                return load();
            })
            .catch(function () {
                toast(
                    t(
                        'fami_wallet.submit_failed',
                        'Unable to submit withdrawal.'
                    )
                );
            })
            .finally(function () {
                setBusy(false);
            });
    }

    function submitUSDT() {
        var points = amount();
        if (!validateAmount(points, state.data.minimumPoints)) return;
        var address = String($('addressInput').value || '').trim();
        if (!validTRC20(address)) {
            toast(
                t('fami_wallet.invalid_address', 'Enter a valid TRC20 address.')
            );
            return;
        }
        setBusy(true);
        window.HyGuild.wallet
            .withdrawUSDT(points, address)
            .then(function () {
                toast(t('fami_wallet.submitted', 'Withdrawal submitted.'));
                return load();
            })
            .catch(function () {
                toast(
                    t(
                        'fami_wallet.submit_failed',
                        'Unable to submit withdrawal.'
                    )
                );
            })
            .finally(function () {
                setBusy(false);
            });
    }

    function saveAddress() {
        var address = String($('addressInput').value || '').trim();
        if (!validTRC20(address)) {
            toast(
                t('fami_wallet.invalid_address', 'Enter a valid TRC20 address.')
            );
            return;
        }
        setBusy(true);
        window.HyGuild.wallet
            .saveAddress(address)
            .then(function () {
                state.data.address = address;
                renderOverview();
                toast(t('fami_wallet.address_saved', 'Address saved.'));
            })
            .catch(function () {
                toast(
                    t(
                        'fami_wallet.address_save_failed',
                        'Unable to save address.'
                    )
                );
            })
            .finally(function () {
                setBusy(false);
            });
    }

    function validateAmount(points, minimum) {
        if (!points || !state.data || points > state.data.balance.available) {
            toast(
                t(
                    'fami_wallet.invalid_amount',
                    'Enter an available POINT amount.'
                )
            );
            return false;
        }
        if (points < minimum) {
            toast(
                t('fami_wallet.minimum_amount', 'Minimum POINT amount:') +
                    ' ' +
                    number(minimum)
            );
            return false;
        }
        return true;
    }

    function validTRC20(value) {
        return /^T[1-9A-HJ-NP-Za-km-z]{33}$/.test(value);
    }

    function escapeHTML(value) {
        return String(value || '')
            .replace(/&/g, '&amp;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;')
            .replace(/"/g, '&quot;')
            .replace(/'/g, '&#39;');
    }

    function dateTime(value) {
        if (!Number(value)) return '—';
        return new Date(Number(value)).toLocaleString();
    }

    function bind() {
        $('backButton').addEventListener('click', function () {
            if (window.history.length > 1) window.history.back();
            else if (window.HyAppBridge) window.HyAppBridge.back();
        });
        document
            .querySelector('.wallet-tabs')
            .addEventListener('click', function (event) {
                var button = event.target.closest('[data-mode]');
                if (button) selectMode(button.getAttribute('data-mode'));
            });
        $('sellerList').addEventListener('click', function (event) {
            var button = event.target.closest('[data-seller-id]');
            if (!button || state.busy) return;
            state.selectedSellerID = button.getAttribute('data-seller-id');
            renderSellers();
            renderConversion();
        });
        $('pointAmount').addEventListener('input', renderConversion);
        $('allButton').addEventListener('click', function () {
            if (!state.data) return;
            $('pointAmount').value = String(state.data.balance.available);
            renderConversion();
        });
        $('sellerSubmit').addEventListener('click', submitSeller);
        $('usdtSubmit').addEventListener('click', submitUSDT);
        $('saveAddressButton').addEventListener('click', saveAddress);
        window.addEventListener('hyapp:i18n-ready', function () {
            renderOverview();
            renderHistory();
        });
    }

    function init() {
        bind();
        selectMode('seller');
        load().finally(function () {
            if (window.HyAppBridge) {
                window.HyAppBridge.ready({
                    page: 'fami-wallet',
                    app_code: 'fami',
                });
            }
        });
    }

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }
})();
