/**
 * Minimal Test Runner for Browser
 * Run tests by opening tests/index.html in browser
 */

const results = {
    passed: 0,
    failed: 0,
    tests: []
}

/**
 * Define a test
 * @param {string} name - Test name
 * @param {Function} fn - Test function
 */
export function test(name, fn) {
    try {
        fn()
        results.passed++
        results.tests.push({ name, status: 'passed' })
        console.log(`✓ ${name}`)
    } catch (error) {
        results.failed++
        results.tests.push({ name, status: 'failed', error: error.message })
        console.error(`✗ ${name}`)
        console.error(`  ${error.message}`)
    }
}

/**
 * Group tests
 * @param {string} name - Group name
 * @param {Function} fn - Function containing tests
 */
export function describe(name, fn) {
    console.group(name)
    fn()
    console.groupEnd()
}

/**
 * Assert equality
 * @param {*} actual 
 * @param {*} expected 
 * @param {string} [message]
 */
export function assertEquals(actual, expected, message = '') {
    if (actual !== expected) {
        throw new Error(
            message || `Expected ${JSON.stringify(expected)}, got ${JSON.stringify(actual)}`
        )
    }
}

/**
 * Assert truthy
 * @param {*} value 
 * @param {string} [message]
 */
export function assertTrue(value, message = '') {
    if (!value) {
        throw new Error(message || `Expected truthy value, got ${value}`)
    }
}

/**
 * Assert falsy
 * @param {*} value 
 * @param {string} [message]
 */
export function assertFalse(value, message = '') {
    if (value) {
        throw new Error(message || `Expected falsy value, got ${value}`)
    }
}

/**
 * Assert throws
 * @param {Function} fn 
 * @param {string} [message]
 */
export function assertThrows(fn, message = '') {
    try {
        fn()
        throw new Error(message || 'Expected function to throw')
    } catch (e) {
        if (e.message === (message || 'Expected function to throw')) {
            throw e
        }
    }
}

/**
 * Assert deep equality for objects/arrays
 * @param {*} actual 
 * @param {*} expected 
 * @param {string} [message]
 */
export function assertDeepEquals(actual, expected, message = '') {
    const actualStr = JSON.stringify(actual)
    const expectedStr = JSON.stringify(expected)
    if (actualStr !== expectedStr) {
        throw new Error(
            message || `Expected ${expectedStr}, got ${actualStr}`
        )
    }
}

/**
 * Get test results
 * @returns {Object}
 */
export function getResults() {
    return { ...results }
}

/**
 * Render results to DOM
 * @param {HTMLElement} container 
 */
export function renderResults(container) {
    const summary = document.createElement('div')
    summary.className = 'test-summary'
    summary.innerHTML = `
        <h2>Test Results</h2>
        <p class="passed">Passed: ${results.passed}</p>
        <p class="failed">Failed: ${results.failed}</p>
    `
    
    const list = document.createElement('ul')
    list.className = 'test-list'
    
    results.tests.forEach(t => {
        const li = document.createElement('li')
        li.className = t.status
        li.innerHTML = t.status === 'passed' 
            ? `✓ ${t.name}`
            : `✗ ${t.name}<br><small>${t.error}</small>`
        list.appendChild(li)
    })
    
    container.appendChild(summary)
    container.appendChild(list)
}
