const assert = require('node:assert/strict');
const fs = require('node:fs');
const path = require('node:path');
const vm = require('node:vm');

const root = path.join(__dirname, '..');

function apiResponse(data) {
    return {
        headers: { get: () => '' },
        ok: true,
        status: 200,
        statusText: 'OK',
        text: () => Promise.resolve(JSON.stringify({ code: 'OK', data })),
    };
}

function harness(search = '') {
    const requests = [];
    const location = {
        hash: '',
        hostname: 'h5.global-interaction.com',
        href: `https://h5.global-interaction.com/guild/fami/agency-center/${search}`,
        origin: 'https://h5.global-interaction.com',
        pathname: '/guild/fami/agency-center/',
        search,
    };
    const storage = new Map();
    const window = {
        atob: (value) => Buffer.from(value, 'base64').toString('binary'),
        crypto: { randomUUID: () => 'fixed-uuid' },
        document: {
            currentScript: null,
            documentElement: { setAttribute: () => {} },
        },
        dispatchEvent: () => {},
        fetch: (rawURL, options = {}) => {
            const url = new URL(rawURL);
            requests.push({ url, options });
            if (url.pathname === '/api/v1/users/me') {
                return Promise.resolve(
                    apiResponse({ contact_info: '+20 100 200 300' })
                );
            }
            if (url.pathname === '/api/v1/agency-center/overview') {
                return Promise.resolve(
                    apiResponse({
                        agency: {
                            agency_id: '9',
                            short_id: '90009',
                            name: 'Fami Stars',
                            created_at_ms: 1_750_000_000_000,
                        },
                    })
                );
            }
            if (url.pathname === '/api/v1/wallet/me/balances') {
                return Promise.resolve(
                    apiResponse({
                        balances: [
                            { asset_type: 'POINT', available_amount: 8800 },
                        ],
                    })
                );
            }
            if (url.pathname === '/api/v1/agency-center/stats') {
                return Promise.resolve(
                    apiResponse({
                        summary: {
                            total_earnings: 1200,
                            gift_income: 700,
                            share_income: 500,
                            total_hosts: 1,
                            gifted_host_count: 1,
                        },
                        hosts: [
                            {
                                membership_id: '77',
                                host_user_id: '42',
                                display_user_id: '100042',
                                username: 'Fami Host',
                                diamond_earnings: 700,
                                valid_mic_days: 3,
                            },
                        ],
                    })
                );
            }
            if (url.pathname === '/api/v1/users/by-display-user-id/100099') {
                return Promise.resolve(apiResponse({ user_id: '99' }));
            }
            return Promise.resolve(apiResponse({}));
        },
        localStorage: {
            getItem: (key) => storage.get(key) || null,
            removeItem: (key) => storage.delete(key),
            setItem: (key, value) => storage.set(key, String(value)),
        },
        location,
    };
    window.window = window;
    const context = vm.createContext({
        Buffer,
        CustomEvent: function CustomEvent() {},
        Date,
        Error,
        FormData,
        JSON,
        Math,
        Number,
        Object,
        Promise,
        String,
        URL,
        URLSearchParams,
        console,
        document: window.document,
        window,
    });
    return { context, requests, window };
}

function run(context, file) {
    vm.runInContext(fs.readFileSync(path.join(root, file), 'utf8'), context, {
        filename: file,
    });
}

async function main() {
    const browser = harness('?token=test-token&env=test');
    run(browser.context, 'guild/packages/core/product-context.js');
    run(browser.context, 'guild/products/fami/product.js');
    run(browser.context, 'common/api.js');
    run(browser.context, 'guild/packages/core/date-range.js');
    run(browser.context, 'guild/packages/agency-center/agency-center.js');

    const range = browser.window.HyGuild.dateRange.create('last_7_days', {
        now: new Date(2026, 6, 12),
    });
    const data = await browser.window.HyGuild.agencyCenter.load(range);
    assert.equal(data.agency.shortId, '90009');
    assert.equal(data.contact, '+20 100 200 300');
    assert.equal(data.pointBalance, 8800);
    assert.equal(data.stats.summary.share_income, 500);
    assert.equal(data.stats.hosts[0].displayUserId, '100042');

    const statsRequest = browser.requests.find(
        ({ url }) => url.pathname === '/api/v1/agency-center/stats'
    );
    assert.equal(statsRequest.url.searchParams.get('start_date'), '2026-07-06');
    assert.equal(statsRequest.url.searchParams.get('end_date'), '2026-07-12');

    await browser.window.HyGuild.agencyCenter.inviteHost('100099');
    const invite = browser.requests.find(
        ({ url }) => url.pathname === '/api/v1/agency-center/invitations/host'
    );
    assert.ok(invite, 'resolved display ID must be sent to invite endpoint');
    assert.deepEqual(JSON.parse(invite.options.body), {
        command_id: 'fami-agency-invite-host:fixed-uuid',
        target_user_id: '99',
    });
    browser.requests.forEach(({ options }) => {
        assert.equal(options.headers['X-App-Code'], 'fami');
    });

    const mockBrowser = harness('?mock=1');
    run(mockBrowser.context, 'guild/packages/core/product-context.js');
    run(mockBrowser.context, 'guild/products/fami/product.js');
    run(mockBrowser.context, 'guild/packages/core/date-range.js');
    run(mockBrowser.context, 'guild/packages/agency-center/agency-center.js');
    const mock = await mockBrowser.window.HyGuild.agencyCenter.load(
        mockBrowser.window.HyGuild.dateRange.create('today', {
            now: new Date(2026, 6, 12),
        })
    );
    assert.equal(mock.stats.hosts.length, 1);
    assert.equal(mockBrowser.requests.length, 0);

    console.log('Fami agency center tests passed');
}

main().catch((error) => {
    console.error(error);
    process.exitCode = 1;
});
