/* .SOL DOMAINS — Solana Name Service Lookup & Registration */

const SNS_API = 'https://sns-sdk-proxy.bonfida.workers.dev';
const SNS_REG = 'https://www.sns.id/domain/';
const SNS_REGISTER_API = 'https://sdk-proxy.sns.id';
const SOLSCAN = 'https://solscan.io/account/';
const SOLSCAN_TX = 'https://solscan.io/tx/';
const REFERRAL_WALLET = '9NuiHh5wgRPx69BFGP1ZR8kHiBENGoJrXs5GpZzKAyn8';
const USDC_MINT = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v';
const SOLANA_RPC = 'https://api.mainnet-beta.solana.com';

let walletAddress = null;
let currentTab = 'search';
let pendingRegistrationDomain = null;

// ─── DOM ────────────────────────────────────────────────────
const $ = s => document.querySelector(s);
const $$ = s => document.querySelectorAll(s);

document.addEventListener('DOMContentLoaded', () => {
    initTabs();
    initSearch();
    initWallet();
    createRegistrationModal();
});

// ─── TABS ───────────────────────────────────────────────────
function initTabs() {
    $$('.sol-tab').forEach(tab => {
        tab.addEventListener('click', () => {
            const t = tab.dataset.tab;
            switchTab(t);
        });
    });
}

function switchTab(t) {
    currentTab = t;
    $$('.sol-tab').forEach(tab => tab.classList.toggle('active', tab.dataset.tab === t));
    $$('.sol-panel').forEach(p => p.classList.toggle('hidden', p.id !== `panel-${t}`));
    if (t === 'mydomains' && walletAddress) loadMyDomains();
}

// ─── SEARCH / LOOKUP ────────────────────────────────────────
function initSearch() {
    const input = $('#sol-search');
    const btn = $('#sol-search-go');
    if (!input || !btn) return;
    btn.addEventListener('click', () => doSearch());
    input.addEventListener('keydown', e => { if (e.key === 'Enter') doSearch(); });

    const revInput = $('#sol-reverse');
    const revBtn = $('#sol-reverse-go');
    if (revInput && revBtn) {
        revBtn.addEventListener('click', () => doReverse());
        revInput.addEventListener('keydown', e => { if (e.key === 'Enter') doReverse(); });
    }
}

async function doSearch() {
    const raw = $('#sol-search').value.trim().toLowerCase();
    if (!raw) return;
    const domain = raw.replace(/\.sol$/i, '');
    const results = $('#search-results');
    results.innerHTML = loadingHTML('RESOLVING DOMAIN...');

    try {
        const res = await fetch(`${SNS_API}/resolve/${domain}`);
        const data = await res.json();
        if (data.s === 'ok' && data.result) {
            await showTakenDomain(domain, data.result);
        } else {
            showAvailableDomain(domain);
        }
    } catch (err) {
        results.innerHTML = errorHTML(`Network error: ${err.message}`);
    }
}

async function showTakenDomain(domain, owner) {
    const results = $('#search-results');
    let favourite = null;
    try {
        const favRes = await fetch(`${SNS_API}/favourite-domain/${owner}`);
        const favData = await favRes.json();
        if (favData.s === 'ok') favourite = favData.result || null;
    } catch(e) {}

    results.innerHTML = `
        <div class="sol-result-card">
            <div class="sol-result-header">
                <div class="sol-result-domain">${esc(domain)}<span class="sol-ext">.sol</span></div>
                <div class="sol-result-status taken">REGISTERED</div>
            </div>
            <div class="sol-result-body">
                <div>
                    <div class="sol-result-field">
                        <span class="sol-result-label">OWNER</span>
                        <div class="sol-result-value">
                            <a href="${SOLSCAN}${esc(owner)}" target="_blank" rel="noopener">${truncAddr(owner)}</a>
                        </div>
                    </div>
                    ${favourite ? `
                    <div class="sol-result-field">
                        <span class="sol-result-label">OWNER'S FAVOURITE</span>
                        <div class="sol-result-value">${esc(favourite)}.sol</div>
                    </div>` : ''}
                </div>
                <div>
                    <div class="sol-result-field">
                        <span class="sol-result-label">SOLSCAN</span>
                        <div class="sol-result-value">
                            <a href="${SOLSCAN}${esc(owner)}" target="_blank" rel="noopener">View on Solscan ↗</a>
                        </div>
                    </div>
                    <div class="sol-result-field">
                        <span class="sol-result-label">SNS</span>
                        <div class="sol-result-value">
                            <a href="${SNS_REG}${esc(domain)}" target="_blank" rel="noopener">View on SNS.id ↗</a>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    `;
}

function showAvailableDomain(domain) {
    const results = $('#search-results');
    const price = getEstimatedPrice(domain);

    results.innerHTML = `
        <div class="sol-result-card">
            <div class="sol-result-header">
                <div class="sol-result-domain">${esc(domain)}<span class="sol-ext">.sol</span></div>
                <div class="sol-result-status available">AVAILABLE</div>
            </div>
            <div class="sol-result-body">
                <div>
                    <div class="sol-result-field">
                        <span class="sol-result-label">LENGTH</span>
                        <div class="sol-result-value">${domain.length} character${domain.length !== 1 ? 's' : ''}</div>
                    </div>
                    <div class="sol-result-field">
                        <span class="sol-result-label">ESTIMATED COST</span>
                        <div class="sol-price">
                            <span class="sol-price-amount">${price.amount.replace('~','')}</span>
                            <span class="sol-price-currency">${price.currency}</span>
                            <span class="sol-price-usd">(estimated)</span>
                        </div>
                    </div>
                </div>
                <div>
                    <div class="sol-result-field">
                        <span class="sol-result-label">REGISTRATION</span>
                        <div class="sol-result-value">Register directly from your wallet</div>
                    </div>
                    <div class="sol-result-field">
                        <span class="sol-result-label">PAYMENT</span>
                        <div class="sol-result-value">USDC on Solana</div>
                    </div>
                    <button class="sol-register-btn" id="register-domain-btn">REGISTER ${esc(domain.toUpperCase())}.SOL</button>
                </div>
            </div>
        </div>
    `;

    const regBtn = results.querySelector('#register-domain-btn');
    if (regBtn) {
        regBtn.addEventListener('click', () => initiateRegistration(domain));
    }
}

// ─── REVERSE LOOKUP ─────────────────────────────────────────
async function doReverse() {
    const addr = $('#sol-reverse').value.trim();
    if (!addr) return;

    const results = $('#reverse-results');
    results.innerHTML = loadingHTML('SCANNING WALLET...');

    try {
        const res = await fetch(`${SNS_API}/domains/${addr}`);
        const data = await res.json();

        // Normalise response to array — API may return various formats
        let domains = [];
        if (Array.isArray(data)) {
            domains = data;
        } else if (data && typeof data === 'object') {
            if (Array.isArray(data.result)) {
                domains = data.result;
            } else if (typeof data.result === 'string') {
                domains = [data.result];
            } else if (data.result && typeof data.result === 'object' && !Array.isArray(data.result)) {
                // Single domain object
                domains = [data.result];
            }
        }

        if (!domains || domains.length === 0) {
            results.innerHTML = `<div class="sol-empty">NO .SOL DOMAINS FOUND FOR THIS WALLET</div>`;
            return;
        }

        let favourite = null;
        try {
            const favRes = await fetch(`${SNS_API}/favourite-domain/${addr}`);
            const favData = await favRes.json();
            if (favData.s === 'ok') favourite = favData.result || null;
        } catch(e) {}

        results.innerHTML = `
            <div class="sol-stats-bar">
                <div class="sol-stat">DOMAINS: <span class="sol-stat-value">${domains.length}</span></div>
                ${favourite ? `<div class="sol-stat">FAVOURITE: <span class="sol-stat-value">${favourite}.sol</span></div>` : ''}
                <div class="sol-stat">WALLET: <span class="sol-stat-value">${truncAddr(addr)}</span></div>
            </div>
            <div class="sol-domains-grid">
                ${domains.map(d => {
                    const name = typeof d === 'string' ? d : (d.domain || d.name || String(d));
                    const isFav = favourite && name === favourite;
                    return `
                        <div class="sol-domain-card">
                            <div class="sol-domain-name">${esc(name)}<span class="sol-ext">.sol</span></div>
                            ${isFav ? '<div class="sol-domain-fav">★ FAVOURITE</div>' : ''}
                        </div>
                    `;
                }).join('')}
            </div>
        `;
    } catch(err) {
        results.innerHTML = errorHTML(`Network error: ${err.message}`);
    }
}

// ─── WALLET (uses global window.solWallet from wallet-connect.js) ────────────

// Sync local walletAddress from global wallet state
function syncWalletState() {
    const sw = window.solWallet;
    if (sw && sw.connected && sw.address) {
        walletAddress = sw.address;
    } else {
        walletAddress = null;
    }
}

function initWallet() {
    const btn = $('#wallet-btn');
    if (!btn) return;
    btn.addEventListener('click', toggleWallet);
    createWalletModal();

    // Listen for global wallet events
    window.addEventListener('wallet-connected', (e) => {
        walletAddress = e.detail.address;
        updateWalletUI();
        checkPendingRegistration();
    });

    window.addEventListener('wallet-disconnected', () => {
        walletAddress = null;
        updateWalletUI();
    });

    // Sync initial state (wallet may have auto-reconnected already)
    syncWalletState();
    updateWalletUI();
}

function createWalletModal() {
    const modal = document.createElement('div');
    modal.id = 'wallet-modal';
    modal.className = 'sol-modal hidden';
    modal.innerHTML = `
        <div class="sol-modal-backdrop"></div>
        <div class="sol-modal-content">
            <div class="sol-modal-header">
                <span class="sol-modal-title">SELECT WALLET</span>
                <button class="sol-modal-close" id="modal-close">✕</button>
            </div>
            <div class="sol-modal-body" id="wallet-list"></div>
            <div class="sol-modal-footer">
                <span class="sol-modal-hint">No wallet? Install one to connect to Solana</span>
            </div>
        </div>
    `;
    document.body.appendChild(modal);
    modal.querySelector('.sol-modal-backdrop').addEventListener('click', closeModal);
    modal.querySelector('#modal-close').addEventListener('click', closeModal);
}

function openModal() {
    const sw = window.solWallet;
    if (!sw) { console.warn('solWallet not loaded'); return; }

    const modal = $('#wallet-modal');
    const list = $('#wallet-list');

    const KNOWN_WALLETS = sw.KNOWN_WALLETS || [];

    // Small delay to let async provider injection complete
    setTimeout(() => {
        const available = sw.getAvailableWallets();
        const detectedNames = new Set(available.map(w => w.name));

        let html = '';

        if (available.length > 0) {
            html += '<div class="sol-wallet-divider">DETECTED</div>';
            html += available.map(w => `
                <button class="sol-wallet-option detected" data-wallet="${w.name}">
                    <span class="sol-wallet-option-icon">${w.icon}</span>
                    <span class="sol-wallet-option-name">${w.name}</span>
                    <span class="sol-wallet-option-status detected">DETECTED</span>
                </button>
            `).join('');
        }

        const notInstalled = KNOWN_WALLETS.filter(w => !detectedNames.has(w.name));
        if (notInstalled.length > 0) {
            html += '<div class="sol-wallet-divider">NOT INSTALLED</div>';
            html += notInstalled.map(w => `
                <a href="${w.url}" target="_blank" rel="noopener" class="sol-wallet-option not-installed">
                    <span class="sol-wallet-option-icon">${w.icon}</span>
                    <span class="sol-wallet-option-name">${w.name}</span>
                    <span class="sol-wallet-option-status">INSTALL ↗</span>
                </a>
            `).join('');
        }

        if (available.length === 0) {
            html = `<div class="sol-empty" style="padding:1rem;">
                NO SOLANA WALLETS DETECTED<br><br>
                Install a Solana wallet extension to connect.<br>
                <span style="color:#14F195;font-size:0.6rem;">If you just installed one, refresh the page.</span>
            </div>`;
        }

        list.innerHTML = html;

        list.querySelectorAll('.sol-wallet-option.detected').forEach(btn => {
            btn.addEventListener('click', async (e) => {
                e.preventDefault();
                e.stopPropagation();
                const name = btn.dataset.wallet;
                const wallet = available.find(w => w.name === name);
                if (wallet) {
                    try {
                        closeModal();
                        await sw.connect(wallet);
                    } catch (err) {
                        console.error('Wallet connection failed:', err);
                        const status = $('#wallet-status');
                        if (status) status.innerHTML = `<span style="color:rgba(255,50,50,0.8)">CONNECTION REJECTED</span>`;
                    }
                }
            });
        });

        modal.classList.remove('hidden');
    }, 150);
}

function closeModal() {
    const modal = $('#wallet-modal');
    if (modal) modal.classList.add('hidden');
}

async function toggleWallet() {
    if (walletAddress) {
        disconnectWallet();
        return;
    }
    openModal();
}

function disconnectWallet() {
    const sw = window.solWallet;
    if (sw) sw.disconnect();
    walletAddress = null;
    updateWalletUI();
}

function updateWalletUI() {
    const status = $('#wallet-status');
    const btn = $('#wallet-btn');

    const sw = window.solWallet;

    if (walletAddress) {
        const wName = (sw && sw.walletName) ? sw.walletName : 'WALLET';
        const wIcon = '◆';
        status.className = 'sol-wallet-status connected';
        status.innerHTML = `● CONNECTED VIA ${wIcon} ${wName} <span class="sol-wallet-address">${truncAddr(walletAddress)}</span>`;
        btn.className = 'sol-wallet-btn disconnect';
        btn.textContent = 'DISCONNECT';
    } else {
        status.className = 'sol-wallet-status';
        status.innerHTML = '○ NOT CONNECTED';
        btn.className = 'sol-wallet-btn';
        btn.textContent = 'CONNECT WALLET';
        const panel = $('#mydomains-content');
        if (panel) panel.innerHTML = `<div class="sol-empty">CONNECT WALLET TO VIEW YOUR DOMAINS</div>`;
    }
}

// ─── MY DOMAINS ─────────────────────────────────────────────
async function loadMyDomains() {
    if (!walletAddress) return;
    const content = $('#mydomains-content');
    content.innerHTML = loadingHTML('LOADING YOUR DOMAINS...');

    try {
        const res = await fetch(`${SNS_API}/domains/${walletAddress}`);
        const data = await res.json();

        // Normalise to array
        let domains = [];
        if (Array.isArray(data)) {
            domains = data;
        } else if (data && typeof data === 'object') {
            if (Array.isArray(data.result)) {
                domains = data.result;
            } else if (typeof data.result === 'string') {
                domains = [data.result];
            } else if (data.result && typeof data.result === 'object') {
                domains = [data.result];
            }
        }

        let favourite = null;
        try {
            const favRes = await fetch(`${SNS_API}/favourite-domain/${walletAddress}`);
            const favData = await favRes.json();
            if (favData.s === 'ok') favourite = favData.result || null;
        } catch(e) {}

        if (!domains || domains.length === 0) {
            const regUrl = `${SNS_REG}?ref=${REFERRAL_WALLET}`;
            content.innerHTML = `
                <div class="sol-empty">
                    NO .SOL DOMAINS FOUND<br>
                    <a href="${regUrl}" target="_blank" rel="noopener" style="color:#14F195; font-size:0.7rem">Register one on SNS.id ↗</a>
                </div>
            `;
            return;
        }

        content.innerHTML = `
            <div class="sol-stats-bar">
                <div class="sol-stat">YOUR DOMAINS: <span class="sol-stat-value">${domains.length}</span></div>
                ${favourite ? `<div class="sol-stat">FAVOURITE: <span class="sol-stat-value">${favourite}.sol</span></div>` : ''}
            </div>
            <div class="sol-domains-grid">
                ${domains.map(d => {
                    const name = typeof d === 'string' ? d : (d.domain || d.name || String(d));
                    const isFav = favourite && name === favourite;
                    return `
                        <div class="sol-domain-card">
                            <div class="sol-domain-name">${esc(name)}<span class="sol-ext">.sol</span></div>
                            ${isFav ? '<div class="sol-domain-fav">★ FAVOURITE</div>' : ''}
                        </div>
                    `;
                }).join('')}
            </div>
        `;
    } catch(err) {
        content.innerHTML = errorHTML(`Network error: ${err.message}`);
    }
}

// ─── HELPERS ────────────────────────────────────────────────
function truncAddr(a) {
    if (!a || a.length < 12) return a;
    return a.slice(0, 6) + '...' + a.slice(-4);
}

function esc(s) {
    const d = document.createElement('div');
    d.textContent = s;
    return d.innerHTML;
}

function loadingHTML(msg) {
    return `<div class="sol-loading"><div class="sol-loading-spinner"></div><div class="sol-loading-text">${msg}</div></div>`;
}

function errorHTML(msg) {
    return `<div class="sol-error">ERROR // ${msg}</div>`;
}

// ─── REGISTRATION ───────────────────────────────────────────

function getEstimatedPrice(domain) {
    const len = domain.length;
    if (len <= 1) return { amount: '~750', currency: 'USDC', numeric: 750 };
    if (len === 2) return { amount: '~700', currency: 'USDC', numeric: 700 };
    if (len === 3) return { amount: '~640', currency: 'USDC', numeric: 640 };
    if (len === 4) return { amount: '~160', currency: 'USDC', numeric: 160 };
    return { amount: '~20', currency: 'USDC', numeric: 20 };
}

function createRegistrationModal() {
    const modal = document.createElement('div');
    modal.id = 'registration-modal';
    modal.className = 'sol-modal hidden';
    modal.innerHTML = `
        <div class="sol-modal-backdrop"></div>
        <div class="sol-modal-content sol-reg-modal-content">
            <div class="sol-modal-header">
                <span class="sol-modal-title">CONFIRM REGISTRATION</span>
                <button class="sol-modal-close" id="reg-modal-close">✕</button>
            </div>
            <div class="sol-modal-body" id="reg-modal-body"></div>
        </div>
    `;
    document.body.appendChild(modal);
    modal.querySelector('.sol-modal-backdrop').addEventListener('click', closeRegistrationModal);
    modal.querySelector('#reg-modal-close').addEventListener('click', closeRegistrationModal);
}

function initiateRegistration(domain) {
    if (!walletAddress) {
        pendingRegistrationDomain = domain;
        openModal();
        return;
    }
    showRegistrationModal(domain);
}

function checkPendingRegistration() {
    if (pendingRegistrationDomain && walletAddress) {
        const domain = pendingRegistrationDomain;
        pendingRegistrationDomain = null;
        setTimeout(() => showRegistrationModal(domain), 300);
    }
}

function showRegistrationModal(domain) {
    const modal = $('#registration-modal');
    const body = $('#reg-modal-body');
    const price = getEstimatedPrice(domain);

    body.innerHTML = `
        <div class="sol-reg-summary">
            <div class="sol-reg-domain-display">
                <span class="sol-reg-domain-name">${esc(domain)}</span><span class="sol-reg-domain-ext">.sol</span>
            </div>
            <div class="sol-reg-details">
                <div class="sol-reg-row">
                    <span class="sol-reg-label">DOMAIN</span>
                    <span class="sol-reg-value">${esc(domain)}.sol</span>
                </div>
                <div class="sol-reg-row">
                    <span class="sol-reg-label">ESTIMATED COST</span>
                    <span class="sol-reg-value sol-reg-price">${price.amount} ${price.currency}</span>
                </div>
                <div class="sol-reg-row">
                    <span class="sol-reg-label">PAYMENT TOKEN</span>
                    <span class="sol-reg-value">USDC (Solana)</span>
                </div>
                <div class="sol-reg-row">
                    <span class="sol-reg-label">BUYER WALLET</span>
                    <span class="sol-reg-value">${truncAddr(walletAddress)}</span>
                </div>
                <div class="sol-reg-row">
                    <span class="sol-reg-label">STORAGE SPACE</span>
                    <span class="sol-reg-value">0 kB (minimum)</span>
                </div>
            </div>
            <div class="sol-reg-warning" id="reg-warning">
                ⚠ THIS IS A REAL ON-CHAIN TRANSACTION. USDC WILL BE DEDUCTED FROM YOUR WALLET.
                THE EXACT AMOUNT IS DETERMINED BY THE BONFIDA SNS SMART CONTRACT.
            </div>
            <div class="sol-reg-actions" id="reg-actions">
                <button class="sol-reg-cancel-btn" id="reg-cancel">CANCEL</button>
                <button class="sol-reg-confirm-btn" id="reg-confirm">CONFIRM & REGISTER</button>
            </div>
        </div>
        <div class="sol-reg-status hidden" id="reg-status"></div>
    `;

    body.querySelector('#reg-cancel').addEventListener('click', closeRegistrationModal);
    body.querySelector('#reg-confirm').addEventListener('click', () => executeRegistration(domain));
    modal.classList.remove('hidden');
}

function closeRegistrationModal() {
    const modal = $('#registration-modal');
    if (modal) modal.classList.add('hidden');
}

function updateRegistrationStatus(state, message, extra) {
    const statusEl = $('#reg-status');
    if (!statusEl) return;
    statusEl.classList.remove('hidden');

    const actions = $('#reg-actions');
    const warning = $('#reg-warning');

    let icon, stateClass;
    switch (state) {
        case 'processing':
            icon = '<div class="sol-loading-spinner"></div>';
            stateClass = 'processing';
            if (actions) actions.style.display = 'none';
            if (warning) warning.style.display = 'none';
            break;
        case 'pending':
            icon = '<div class="sol-loading-spinner"></div>';
            stateClass = 'pending';
            break;
        case 'success':
            icon = '<span class="sol-reg-status-icon success">✓</span>';
            stateClass = 'success';
            if (actions) actions.style.display = 'none';
            if (warning) warning.style.display = 'none';
            break;
        case 'error':
            icon = '<span class="sol-reg-status-icon error">✕</span>';
            stateClass = 'error';
            if (actions) { actions.style.display = 'flex'; }
            if (warning) { warning.style.display = 'block'; }
            break;
    }

    statusEl.innerHTML = `
        <div class="sol-reg-status-card ${stateClass}">
            <div class="sol-reg-status-header">
                ${icon}
                <span class="sol-reg-status-text">${message}</span>
            </div>
            ${extra || ''}
        </div>
    `;
}

async function executeRegistration(domain) {
    if (!walletAddress || !window.solWallet?.provider) {
        updateRegistrationStatus('error', 'WALLET NOT CONNECTED',
            '<p class="sol-reg-error-detail">Please connect your wallet and try again.</p>');
        return;
    }

    updateRegistrationStatus('processing', 'FETCHING TRANSACTION FROM SNS...');

    try {
        // 1. Fetch serialised transaction from SDK proxy
        const params = new URLSearchParams({
            buyer: walletAddress,
            domain: domain,
            space: '0',
            serialize: 'true',
            refKey: REFERRAL_WALLET,
            mint: USDC_MINT
        });

        const apiUrl = `${SNS_REGISTER_API}/register?${params.toString()}`;
        const res = await fetch(apiUrl);

        if (!res.ok) {
            throw new Error(`SNS API returned HTTP ${res.status}`);
        }

        const data = await res.json();

        if (data.s !== 'ok' || !data.result) {
            const errMsg = typeof data.result === 'string' ? data.result : (data.error || 'Unknown error from SNS API');
            throw new Error(errMsg);
        }

        updateRegistrationStatus('processing', 'PREPARING TRANSACTION...');

        // 2. Decode base64 transaction
        const txBytes = base64ToUint8Array(data.result);

        // 3. Deserialise — try VersionedTransaction first, fallback to legacy
        let transaction;
        let isVersioned = false;

        try {
            transaction = solanaWeb3.VersionedTransaction.deserialize(txBytes);
            isVersioned = true;
        } catch (e) {
            try {
                transaction = solanaWeb3.Transaction.from(txBytes);
                isVersioned = false;
            } catch (e2) {
                throw new Error('Failed to deserialise transaction from SNS API');
            }
        }

        // 4. Get fresh blockhash from Solana RPC
        const connection = new solanaWeb3.Connection(SOLANA_RPC, 'confirmed');
        const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash('confirmed');

        // 5. Set fresh blockhash on transaction
        if (isVersioned) {
            transaction.message.recentBlockhash = blockhash;
        } else {
            transaction.recentBlockhash = blockhash;
        }

        updateRegistrationStatus('processing', 'AWAITING WALLET SIGNATURE...');

        // 6. Sign and send via connected wallet
        let signature;

        if (window.solWallet && window.solWallet.isWalletStandard) {
            signature = await signAndSendWalletStandard(transaction, isVersioned, connection);
        } else {
            signature = await signAndSendLegacy(transaction, isVersioned, connection);
        }

        updateRegistrationStatus('pending', 'TRANSACTION SUBMITTED — CONFIRMING...',
            `<div class="sol-reg-tx-info">
                <span class="sol-reg-label">TX SIGNATURE</span>
                <a href="${SOLSCAN_TX}${signature}" target="_blank" rel="noopener" class="sol-reg-tx-link">${truncAddr(signature)} ↗</a>
            </div>`);

        // 7. Confirm transaction on-chain
        const confirmation = await connection.confirmTransaction({
            signature,
            blockhash,
            lastValidBlockHeight
        }, 'confirmed');

        if (confirmation.value.err) {
            throw new Error('Transaction failed on-chain: ' + JSON.stringify(confirmation.value.err));
        }

        // 8. Success!
        updateRegistrationStatus('success',
            `${domain.toUpperCase()}.SOL REGISTERED SUCCESSFULLY!`,
            `<div class="sol-reg-tx-info">
                <span class="sol-reg-label">TRANSACTION</span>
                <a href="${SOLSCAN_TX}${signature}" target="_blank" rel="noopener" class="sol-reg-tx-link">View on Solscan ↗</a>
            </div>
            <div class="sol-reg-tx-info">
                <span class="sol-reg-label">DOMAIN</span>
                <a href="${SNS_REG}${encodeURIComponent(domain)}" target="_blank" rel="noopener" class="sol-reg-tx-link">View on SNS.id ↗</a>
            </div>
            <div class="sol-reg-success-actions">
                <button class="sol-reg-confirm-btn" onclick="closeRegistrationModal()">CLOSE</button>
            </div>`);

    } catch (err) {
        console.error('Registration error:', err);
        let userMessage = err.message || 'Unknown error';

        // User-friendly error messages
        if (/reject|denied|cancel|declined|disapproved/i.test(userMessage)) {
            userMessage = 'Transaction was rejected by your wallet.';
        } else if (/insufficient|not enough|0x1/i.test(userMessage)) {
            userMessage = 'Insufficient USDC balance. Ensure you have enough USDC to cover the registration cost plus network fees.';
        } else if (/already taken|already registered|already exists|registered/i.test(userMessage)) {
            userMessage = 'This domain was just registered by someone else. Try a different name.';
        } else if (/blockhash|expired|block height exceeded/i.test(userMessage)) {
            userMessage = 'Transaction expired. Please try again.';
        } else if (/network|fetch|failed to fetch|CORS/i.test(userMessage)) {
            userMessage = 'Network error. Check your connection and try again.';
        }

        updateRegistrationStatus('error', 'REGISTRATION FAILED',
            `<p class="sol-reg-error-detail">${esc(userMessage)}</p>
             <div class="sol-reg-success-actions">
                <button class="sol-reg-confirm-btn" id="reg-retry-btn">RETRY</button>
                <button class="sol-reg-cancel-btn" onclick="closeRegistrationModal()">CLOSE</button>
            </div>`);

        // Bind retry after DOM update
        const retryBtn = document.querySelector('#reg-retry-btn');
        if (retryBtn) retryBtn.addEventListener('click', () => executeRegistration(domain));
    }
}

async function signAndSendLegacy(transaction, isVersioned, connection) {
    const provider = window.solWallet.provider;

    // Try signAndSendTransaction first (Phantom, Solflare support this)
    if (typeof provider.signAndSendTransaction === 'function') {
        try {
            const result = await provider.signAndSendTransaction(transaction, {
                skipPreflight: false,
                preflightCommitment: 'confirmed'
            });
            return result.signature || result;
        } catch (e) {
            if (/reject|denied|cancel|declined|disapproved/i.test(e.message || '')) throw e;
            console.warn('signAndSendTransaction failed, falling back to signTransaction:', e.message);
        }
    }

    // Fallback: signTransaction + manual send
    if (typeof provider.signTransaction !== 'function') {
        throw new Error('Wallet does not support transaction signing.');
    }
    const signed = await provider.signTransaction(transaction);
    const rawTx = signed.serialize();
    const signature = await connection.sendRawTransaction(rawTx, {
        skipPreflight: false,
        preflightCommitment: 'confirmed'
    });
    return signature;
}

async function signAndSendWalletStandard(transaction, isVersioned, connection) {
    const wallet = window.solWallet.provider;
    const account = wallet.accounts?.[0];
    if (!account) throw new Error('No wallet account available.');

    // Serialise the transaction for Wallet Standard
    let txBytes;
    if (isVersioned) {
        txBytes = transaction.serialize();
    } else {
        txBytes = transaction.serialize({ requireAllSignatures: false, verifySignatures: false });
    }

    // Try signAndSendTransaction first
    const signAndSendFeature = wallet.features?.['solana:signAndSendTransaction'];
    if (signAndSendFeature) {
        try {
            const results = await signAndSendFeature.signAndSendTransaction({
                account,
                transaction: txBytes,
                chain: 'solana:mainnet'
            });
            const result = Array.isArray(results) ? results[0] : results;
            if (result.signature) {
                if (typeof result.signature === 'string') return result.signature;
                return uint8ArrayToBase58(new Uint8Array(result.signature));
            }
            return result;
        } catch (e) {
            if (/reject|denied|cancel|declined|disapproved/i.test(e.message || '')) throw e;
            console.warn('WS signAndSendTransaction failed, falling back:', e.message);
        }
    }

    // Fallback: signTransaction + manual send
    const signFeature = wallet.features?.['solana:signTransaction'];
    if (!signFeature) throw new Error('Wallet does not support Solana transaction signing.');

    const results = await signFeature.signTransaction({
        account,
        transaction: txBytes,
        chain: 'solana:mainnet'
    });
    const result = Array.isArray(results) ? results[0] : results;
    const signedBytes = result.signedTransaction;

    const signature = await connection.sendRawTransaction(signedBytes, {
        skipPreflight: false,
        preflightCommitment: 'confirmed'
    });
    return signature;
}

function base64ToUint8Array(base64) {
    const binary = atob(base64);
    const bytes = new Uint8Array(binary.length);
    for (let i = 0; i < binary.length; i++) {
        bytes[i] = binary.charCodeAt(i);
    }
    return bytes;
}

function uint8ArrayToBase58(bytes) {
    const ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
    let result = '';
    let num = BigInt(0);
    for (const b of bytes) num = num * 256n + BigInt(b);
    while (num > 0n) {
        result = ALPHABET[Number(num % 58n)] + result;
        num = num / 58n;
    }
    for (const b of bytes) {
        if (b === 0) result = '1' + result;
        else break;
    }
    return result || '1';
}
