(() => {
    const $ = (sel) => document.querySelector(sel);
    const state = {
        cards: [],
        selectedId: '',
        selectedCard: null,
        selectedEvents: []
    };
    const appDialog = window.appDialog || {
        alert: (message) => Promise.resolve(window.alert(message)),
        confirm: (message) => Promise.resolve(window.confirm(message)),
        prompt: (message, defaultValue) => Promise.resolve(window.prompt(message, defaultValue))
    };
    const HOLDER_NAME_PATTERN = /^[A-Za-z][A-Za-z .,'()&@/_\-+]*$/;
    const displayCardId = (card) => String(card?.display_card_id || card?.card_id || '---');

    const statusTextEl = $('#serverStatusText');
    const listEl = $('#cardList');
    const detailEl = $('#detailPanel');
    const eventEl = $('#eventList');
    const searchEl = $('#searchInput');

    const api = {
        async request(url, opts = {}) {
            const res = await fetch(url, opts);
            const data = await res.json().catch(() => ({}));
            if (!res.ok || data.ok === false) {
                throw new Error(data.error || res.statusText || '请求失败');
            }
            return data;
        },
        fetchCards(q = '') {
            return api.request(`/api/ic-cards?q=${encodeURIComponent(q)}`);
        },
        fetchCardDetail(id) {
            return api.request(`/api/ic-cards/${encodeURIComponent(id)}`);
        },
        createCard(payload) {
            return api.request('/api/ic-cards', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify(payload)
            });
        },
        updateCard(id, payload) {
            return api.request(`/api/ic-cards/${encodeURIComponent(id)}`, {
                method: 'PUT',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify(payload)
            });
        },
        topup(id, amount) {
            return api.request(`/api/ic-cards/${encodeURIComponent(id)}/topup`, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ amount })
            });
        }
    };

    const escapeHtml = (value) => String(value == null ? '' : value)
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#39;');

    const formatMoney = (value) => {
        const n = Number(value || 0);
        return Number.isFinite(n) ? n.toFixed(0) : '0';
    };

    const formatTime = (value) => {
        if (value == null || value === '') return '---';
        const ts = Number(value);
        const date = Number.isFinite(ts) ? new Date(ts) : new Date(value);
        return Number.isNaN(date.getTime()) ? String(value) : date.toLocaleString('zh-CN', { hour12: false });
    };

    const statusInfo = (status) => {
        const map = {
            pending_pickup: { text: '待领卡', className: 'badge-warning' },
            active: { text: '正常', className: 'badge-success' },
            disabled: { text: '停用', className: 'badge-danger' },
            lost: { text: '挂失', className: 'badge-danger' },
            refunded: { text: '已退卡', className: 'badge-secondary' }
        };
        return map[String(status || '').toLowerCase()] || { text: status || '未知', className: 'badge-secondary' };
    };

    const eventTitle = (event) => {
        const map = {
            create: '后台建卡',
            update: '信息更新',
            topup: '余额充值',
            order_created: '线上购卡',
            activated: '正式启用'
        };
        return map[String(event?.type || '').toLowerCase()] || (event?.type || '事件');
    };

    const renderStats = () => {
        const cards = state.cards;
        $('#statTotal').textContent = String(cards.length);
        $('#statPending').textContent = String(cards.filter((card) => card.status === 'pending_pickup').length);
        $('#statActive').textContent = String(cards.filter((card) => card.status === 'active').length);
        $('#statBalance').textContent = formatMoney(cards.reduce((sum, card) => sum + (Number(card.balance || 0) || 0), 0));
        $('#listCountBadge').textContent = String(cards.length);
    };

    const renderList = () => {
        if (!state.cards.length) {
            listEl.innerHTML = '<div class="empty-state" style="padding:24px 0;"><p>暂无 IC 卡记录。</p></div>';
            return;
        }
        listEl.innerHTML = state.cards.map((card) => {
            const info = statusInfo(card.status);
            return `
                <div class="line-item ic-card-item ${state.selectedId === card.card_id ? 'active' : ''}" data-id="${escapeHtml(card.card_id)}">
                    <div class="line-color-dot" style="background:${card.status === 'active' ? 'var(--success)' : (card.status === 'pending_pickup' ? 'var(--warning)' : 'var(--danger)')}"></div>
                    <div class="line-info">
                        <div class="line-name">${escapeHtml(displayCardId(card))}</div>
                        <div class="line-meta">${escapeHtml(card.holder_name || '未登记持卡人')} · IC 储值卡</div>
                        <div class="line-meta">订单 ${escapeHtml(card.order_code || '---')} · 余额 ${escapeHtml(formatMoney(card.balance))}</div>
                    </div>
                    <div class="line-actions" style="opacity:1;">
                        <span class="badge ${info.className}">${escapeHtml(info.text)}</span>
                    </div>
                </div>
            `;
        }).join('');

        listEl.querySelectorAll('[data-id]').forEach((item) => {
            item.addEventListener('click', () => {
                const id = item.getAttribute('data-id');
                if (id) loadCard(id);
            });
        });
    };

    const renderDetail = () => {
        if (!state.selectedCard) {
            detailEl.className = 'empty-state';
            detailEl.innerHTML = '<i class="fas fa-credit-card" style="font-size:48px; opacity:0.3;"></i><p>从左侧选择一张 IC 卡以查看详情。</p>';
            eventEl.innerHTML = '<div class="loading">选择卡片后显示事件流。</div>';
            return;
        }
        const card = state.selectedCard;
        const info = statusInfo(card.status);
        detailEl.className = '';
        detailEl.innerHTML = `
            <div class="flex between mb-4" style="align-items:flex-start;">
                <div>
                    <div class="mono" style="font-size:1.4rem; font-weight:700;">${escapeHtml(displayCardId(card))}</div>
                    <div class="text-muted" style="margin-top:6px;">订单号 ${escapeHtml(card.order_code || '---')} · 来源 ${escapeHtml(card.source || '---')}</div>
                </div>
                <span class="badge ${info.className}">${escapeHtml(info.text)}</span>
            </div>
            <div class="ic-detail-grid">
                <label class="ic-field">
                    <span>持卡人</span>
                    <input id="detailHolder" value="${escapeHtml(card.holder_name || '')}">
                </label>
                <label class="ic-field">
                    <span>卡片类型</span>
                    <input value="IC 储值卡" disabled>
                </label>
                <label class="ic-field">
                    <span>状态</span>
                    <select id="detailStatus">
                        <option value="pending_pickup" ${card.status === 'pending_pickup' ? 'selected' : ''}>待领卡</option>
                        <option value="active" ${card.status === 'active' ? 'selected' : ''}>正常</option>
                        <option value="disabled" ${card.status === 'disabled' ? 'selected' : ''}>停用</option>
                        <option value="lost" ${card.status === 'lost' ? 'selected' : ''}>挂失</option>
                        <option value="refunded" ${card.status === 'refunded' ? 'selected' : ''}>已退卡</option>
                    </select>
                </label>
                <label class="ic-field">
                    <span>余额</span>
                    <input id="detailBalance" type="number" min="0" step="1" value="${escapeHtml(Number(card.balance || 0))}">
                </label>
            </div>
            <div class="ic-inline-meta">
                <div class="list-item"><span class="k">创建时间</span><span class="v">${escapeHtml(formatTime(card.created_ts))}</span></div>
                <div class="list-item"><span class="k">最后更新</span><span class="v">${escapeHtml(formatTime(card.last_update_ts))}</span></div>
                <div class="list-item"><span class="k">首次充值</span><span class="v">${escapeHtml(formatMoney(card.purchase_amount ?? card.balance))}</span></div>
                <div class="list-item"><span class="k">购卡金额</span><span class="v">${escapeHtml(formatMoney(card.purchase_amount))}</span></div>
            </div>
        `;

        const events = state.selectedEvents;
        eventEl.innerHTML = events.length ? events.map((event) => `
            <div class="timeline-item">
                <div class="timeline-dot"></div>
                <div class="timeline-content">
                    <div class="flex between">
                        <span style="font-weight:600;">${escapeHtml(eventTitle(event))}</span>
                        <span class="text-muted" style="font-size:0.8rem;">${escapeHtml(formatTime(event.ts))}</span>
                    </div>
                    <div class="log-detail" style="margin-top:8px;">${escapeHtml(typeof event.detail === 'string' ? event.detail : JSON.stringify(event.detail || {}, null, 2))}</div>
                </div>
            </div>
        `).join('') : '<div class="loading">暂无事件记录。</div>';
    };

    const validateHolderName = (value) => {
        const holderName = String(value || '').trim();
        if (!holderName) return '请输入持卡人姓名';
        if (holderName.length > 24) return '持卡人姓名不能超过 24 个字符';
        if (!HOLDER_NAME_PATTERN.test(holderName)) return '持卡人姓名仅支持英文与常用符号';
        return '';
    };

    const currentDetailPayload = () => ({
        holder_name: $('#detailHolder')?.value.trim() || '',
        status: $('#detailStatus')?.value || 'active',
        balance: Number($('#detailBalance')?.value || 0) || 0
    });

    async function refreshList(keepSelection = true) {
        const query = searchEl.value.trim();
        const data = await api.fetchCards(query);
        state.cards = data.cards || [];
        renderStats();
        renderList();
        if (keepSelection && state.selectedId && state.cards.some((card) => card.card_id === state.selectedId)) {
            await loadCard(state.selectedId, false);
        } else if (state.selectedId && !state.cards.some((card) => card.card_id === state.selectedId)) {
            state.selectedId = '';
            state.selectedCard = null;
            state.selectedEvents = [];
            renderDetail();
        }
    }

    async function loadCard(id, rerenderList = true) {
        const data = await api.fetchCardDetail(id);
        state.selectedId = id;
        state.selectedCard = data.card || null;
        state.selectedEvents = data.events || [];
        if (rerenderList) renderList();
        renderDetail();
    }

    async function createCard() {
        const holder_name = $('#createHolder').value.trim();
        const balance = Number($('#createBalance').value || 0) || 0;
        const holderNameError = validateHolderName(holder_name);
        if (holderNameError) {
            alert(holderNameError);
            return;
        }
        const data = await api.createCard({ holder_name, balance });
        $('#createHolder').value = '';
        $('#createBalance').value = '50';
        await refreshList(false);
        if (data.card_id) await loadCard(data.card_id);
        alert(`IC 卡已创建：${displayCardId(data.card || data)}`);
    }

    async function saveCard() {
        if (!state.selectedId) {
            alert('请先选择一张 IC 卡');
            return;
        }
        const payload = currentDetailPayload();
        const holderNameError = validateHolderName(payload.holder_name);
        if (holderNameError) {
            alert(holderNameError);
            return;
        }
        await api.updateCard(state.selectedId, payload);
        await refreshList(false);
        await loadCard(state.selectedId);
        alert('已保存 IC 卡信息');
    }

    async function topupCard() {
        if (!state.selectedId) {
            alert('请先选择一张 IC 卡');
            return;
        }
        const raw = await appDialog.prompt({
            title: 'IC 卡充值',
            message: `请输入给 ${displayCardId(state.selectedCard || { card_id: state.selectedId })} 充值的金额`,
            defaultValue: '50',
            placeholder: '请输入充值金额',
            confirmText: '确认充值'
        });
        if (raw == null) return;
        const amount = Number(raw);
        if (!(amount > 0)) {
            alert('充值金额必须大于 0');
            return;
        }
        await api.topup(state.selectedId, amount);
        await refreshList(false);
        await loadCard(state.selectedId);
        alert('充值成功');
    }

    async function pingServer() {
        try {
            await fetch('/api/public/health', { cache: 'no-store' });
            statusTextEl.textContent = '服务状态：在线';
        } catch (_) {
            statusTextEl.textContent = '服务状态：离线';
        }
    }

    $('#refreshBtn').addEventListener('click', () => refreshList(false).catch((error) => alert(error.message || String(error))));
    $('#createBtn').addEventListener('click', () => createCard().catch((error) => alert(error.message || String(error))));
    $('#saveBtn').addEventListener('click', () => saveCard().catch((error) => alert(error.message || String(error))));
    $('#topupBtn').addEventListener('click', () => topupCard().catch((error) => alert(error.message || String(error))));
    searchEl.addEventListener('keydown', (event) => {
        if (event.key === 'Enter') {
            refreshList(false).catch((error) => alert(error.message || String(error)));
        }
    });
    searchEl.addEventListener('input', () => {
        window.clearTimeout(searchEl._timer);
        searchEl._timer = window.setTimeout(() => {
            refreshList(false).catch((error) => alert(error.message || String(error)));
        }, 240);
    });

    (async () => {
        await pingServer();
        await refreshList(false);
        if (state.cards[0]) await loadCard(state.cards[0].card_id);
    })().catch((error) => {
        statusTextEl.textContent = '服务状态：请求失败';
        listEl.innerHTML = `<div class="loading">${escapeHtml(error.message || String(error))}</div>`;
    });
})();
